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, когда, как видно из первого снимка экрана, только один из них был пройден.

Что я делаю не так?

Спасибо!

Джек

РЕДАКТИРОВАТЬ: Как любезно отметил Фоско, alert был дважды указан в моем массиве (дох!) , Я исправил это, однако проблема с запятой оставлена ​​до сих пор. Я знаю, что это меньшая проблема, но я клянусь, что этого не должно быть ...

4 голоса | спросил Jack 13 PM00000050000003131 2010, 17:27:31

4 ответа


0

С первого взгляда ваш код выглядит так, как будто он должен давать желаемый результат. Я не уверен, что происходит не так.

Вместо того, чтобы собирать $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
}
ответил Hammerite 13 PM00000050000004931 2010, 17:37:49
0

Более простой способ справиться с найденными предметами - использовать ...

$found = array();

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

И в строке есть только одно предупреждение, но оно дважды в вашем списке небезопасных $, следовательно, оно появляется в выводе дважды Чтобы избежать этого, вам придется сканировать каждый раздел отдельно.

ответил Peter O'Callaghan 13 PM00000050000002131 2010, 17:37:21
0

Не изобретай велосипед.

http://htmlpurifier.org/

ответил Vladislav Rastrusny 13 PM00000050000002631 2010, 17:38:26
0

Вы пытались просто повторить $ found и затем сделать View Source? Я предполагаю, что проблема в том, что один из ваших элементов не отображается на основе кодировки HTML ('<?') и что запятая и пробел, которые на самом деле удаляются.

Но я буду повторять @Hammerite с его решениями.

ответил Joseph 13 PM00000050000002831 2010, 17:39:28

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132