2. XSS
XSS 又叫 CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往 Web 页面里插入恶意 html 代码,当用户浏览该页之时,嵌入其中 Web 里面的 html 代码会被执行,从而达到恶意攻击用户的特殊目的。
下面以一个搜索页面为例子:
<body> <?php $searchQuery = $_GET['q']; /* some search magic here */ ?> <h1>You searched for: <?php echo $searchQuery; ?></h1> <p>We found: Absolutely nothing because this is a demo</p> </body>
因为我们把用户的内容直接打印出来,不经过任何过滤,非法用户可以拼接 URL:
search.php?q=%3Cscript%3Ealert(1)%3B%3C%2Fscript%3E
PHP 渲染出来的内容如下,可以看到 Javascript 代码会被直接执行:
<body> <h1>You searched for: <script>alert(1);</script></h1> <p>We found: Absolutely nothing because this is a demo</p> </body>
问:JS 代码被执行有什么大不了的?
Javascript 可以:
偷走你用户浏览器里的 Cookie;
通过浏览器的记住密码功能获取到你的站点登录账号和密码;
盗取用户的机密信息;
你的用户在站点上能做到的事情,有了 JS 权限执行权限就都能做,也就是说 A 用户可以模拟成为任何用户;
在你的网页中嵌入恶意代码;
...
问:如何防范此问题呢?
好消息是比较先进的浏览器现在已经具备了一些基础的 XSS 防范功能,不过请不要依赖与此。
正确的做法是坚决不要相信用户的任何输入,并过滤掉输入中的所有特殊字符。这样就能消灭绝大部分的 XSS 攻击:
<?php $searchQuery = htmlentities($searchQuery, ENT_QUOTES);
或者你可以使用模板引擎 Twig ,一般的模板引擎都会默认为输出加上 htmlentities 防范。
如果你保持了用户的输入内容,在输出时也要特别注意,在以下的例子中,我们允许用户填写自己的博客链接:
<body> <a href="<?php echo $homepageUrl; ?>" rel="external nofollow" >Visit Users homepage</a> </body>
以上代码可能第一眼看不出来有问题,但是假设用户填入以下内容:
#" onclick="alert(1)
会被渲染为:
<body> <a href="#" rel="external nofollow" onclick="alert(1)">Visit Users homepage</a> </body>
永远永远不要相信用户输入的数据,或者,永远都假设用户的内容是有攻击性的,态度端正了,然后小心地处理好每一次的用户输入和输出。