2010-08-13 42 views
4

我已經爲我的webapp寫了一個基本的「安全檢查器」。我需要一眼就看到用戶提交的代碼是否包含惡意內容。PHP strpos()返回奇數結果

下面是代碼的截圖我快這對現在:http://cl.ly/677a6dc40034f096697f

這裏是PHP代碼我使用的是針對這些代碼三位:

<!-- The View --> 
<h2>Security analysis</h2> 
<?php echo securitycheck($html, $css, $js); ?> 

-

// The controller 
function securitycheck($html, $css, $js) 
{ 
    // The code is the html, css, and js, appended together. We're scanning it all. 
    $code = $html." ".$css." ".$js; 

    // $insecure is our array of naughty things to search for. 
    $insecure = array(
         /* HTML Elements */ 
         'applet', 
         'basefont', 
         'base', 
         'behavior', 
         'bgsound', 
         'blink', 
         'embed', 
         'expression', 
         'frameset', 
         'frame', 
         'ilayer', 
         'iframe', 
         'isindex', 
         'javascript', 
         'layer', 
         'link', 
         'meta', 
         'object', 
         'plaintext', 
         'style', 
         'script', 
         'xml', 
         'xss', 
         /* Javascript Elements */ 
         'alert', 
         'cmd', 
         'passthru', 
         'eval', 
         'exec', 
         'expression', 
         'system', 
         'fopen', 
         'fromcharcode', 
         'fsockopen', 
         'file', 
         'file_get_contents', 
         'readfile', 
         'unlink', 
         /* Misc Elements */ 
         'vbscript:', 
         '<?', 
         '<?php', 
         '?>' 
        ); 

    $found = ""; 
    $output = "<p><strong>Potentially insecure items found:</strong> "; 

    foreach($insecure as $item) 
    { 
     if (($pos = strpos($code, $item)) !== FALSE) 
     { 
      $found .= "$item, "; 
     } 
    } 

    if ($found == "") 
    { 
     $output .= "None.<br/>"; 
    } 
    else 
    { 
     $output .= "<span class=\"alert\">".substr($found, 0, -2)."</span>"."</p><br/>"; // cuts trailing comma and space from $found 
    } 

    return $output; 
} 

最後,這裏是返回輸出的截圖(HTML格式)http://cl.ly/f246dc419fb499dd6bd7

查看截圖?有幾件事情是錯誤的。尾部空格和逗號沒有被切斷(我使用substr()來做,而且它報告了兩個alert s,正如你從第一個截圖看到的那樣,這裏只有一個被執行過。我做錯了

感謝

傑克

編輯:?!作爲Fosco好心指出,alert在我的數組(!DOH)被列爲兩次我已經修復了,但是問題尾隨的逗號是lef t仍然存在。我知道這是一個小問題,但我發誓,它仍然不應該在那裏......

+2

警報在您的陣列中列出兩次。 – Fosco 2010-08-13 13:33:45

+0

@Fosco:* facepalm!* – Jack 2010-08-13 13:36:39

回答

1

一眼看上去你的代碼看起來應該給你想要的輸出。我不確定發生了什麼問題。

相反建設$found作爲字符串的,我會建議其構建爲一個數組,然後使用implode()得到一個字符串:

  • 取代$found = "";$found = array();
  • $found[] = $item;
更換 $found .= "$item, ";和替換此代碼塊:

if ($found == "") 
{ 
    $output .= "None.<br/>"; 
} 
else 
{ 
    $output .= "<span class=\"alert\">".substr($found, 0, -2)."</span>"."</p><br/>"; // cuts trailing comma and space from $found 
} 

與此:

if (!count($found)) 
{ 
    $output .= "None.<br/>"; 
} 
else 
{ 
    $output .= "<span class=\"alert\">".implode(', ',$found)."</span>"."</p><br/>"; // cuts trailing comma and space from $found 
} 
+0

感謝Hammerite,我現在正在做這個數組,我想這是一個更好的主意!唯一的問題是 - 它依然會在'eval後輸出一個尾隨的逗號,因爲@Joseph說這可能與'<?php'有關 - 我要手動編輯代碼並查看它。 – Jack 2010-08-13 13:47:45

+0

我明白了。但是禁止應謹慎使用......用戶可以從不知道其內容的地方粘貼HTML。 – 2010-08-13 13:51:50

+1

@FractalizeR該網站的主題是*原創* CSS3,HTML5和JS片段。任何觸發安全警告的事情我都會特別關注。顯然,如果它看起來像一個明目張膽的故意黑客企圖,他們被禁止,如果它只是一個複製粘貼錯誤,一個禮貌的電子郵件被髮送,要求他們修改他們的提交。 – Jack 2010-08-13 14:02:39

1

對付找到的項目更簡單的方法是使用...

$found = array(); 

foreach($insecure as $item) 
{ 
    if (($pos = strpos($code, $item)) !== FALSE) 
    { 
     $found[] $item; 
    } 
} 
$found = implode(', ', $found); 

而且只有有一個警報在字符串中,但它在$ insecure列表中兩次,因此它出現在輸出兩次。爲了避免這種情況,您必須分別掃描每個部分。

+0

非常感謝!我看到第二條警報,並且已被刪除,現在正在使用此array()方法。 – Jack 2010-08-13 13:46:15

1

不要重新發明輪子。

http://htmlpurifier.org/

+0

謝謝@FractalizeR,我不是在重新發明輪子 - 當我需要將這個'live'輸出給用戶時,我實際上會使用HTML Purifier。這純粹是一種一目瞭然的方式,看看用戶是否插入了不好的東西,這樣我就可以看到是否需要採取進一步的預防措施(例如禁止)。 – Jack 2010-08-13 13:40:04

1

你有沒有嘗試過呼應$發現,然後做一個查看源代碼?我猜猜問題是您的某個項目沒有基於HTML編碼顯示('<?'),並且有一個逗號和空格實際上被刪除。

但我會用他的解決方案回覆@Hammerite。

+0

你說得對,那是破壞它的'<?'的輸出。有沒有什麼辦法解決這一問題? – Jack 2010-08-13 14:01:04

+1

使用htmlentities在屏幕上顯示之前對其進行編碼:'htmlentities(substr($ found,0,-2))' - http://us3.php.net/manual/en/function.htmlentities.php – Joseph 2010-08-13 14:28:10