净化 $_GET 参数以避免 XSS 和其他攻击。

16

我有一个使用PHP编写的网站,其中使用include()将内容嵌入模板。要加载的页面在get参数中给出,我在参数的末尾添加".php"并包含该页面。我需要进行一些安全检查,以避免XSS或其他问题(不是MySQL注入,因为我们没有数据库)。我想到的方法如下。

$page = $_GET['page'];

if(!strpos(strtolower($page), 'http') || !strpos($page, '/') ||
    !strpos($page, '\\') || !strpos($page, '..')) {
        //append ".php" to $page and include the page

还有其他什么我可以做来进一步清理我的输入吗?


4
不要这样检查strpos()的结果 - 如果匹配在字符串开头,它将返回零,这将被评估为false。 - Tom Haigh
@Tom,接受的解决方案让我也避免了这个问题,不管怎样,谢谢,我会记住你的建议,为以后的代码做准备。 - Federico klez Culloca
请参见:https://dev59.com/H3VC5IYBdhLWcg3wtzkQ#15825812 - Dave Jarvis
3个回答

33
$page = preg_replace('/[^-a-zA-Z0-9_]/', '', $_GET['page']);

这可能是最快的消毒方法,它可以接受任何内容,并确保仅包含字母、数字、下划线或破折号。


1
仍然可以使用十六进制代码进行攻击:请参见https://dev59.com/xHVC5IYBdhLWcg3w9GLM#12202218和https://dev59.com/oHVD5IYBdhLWcg3wL4cA#12710285。 - Janaka R Rajapaksha
3
翻译文本:两个链接都是关于MySQL的,这个问题不涉及SQL注入。 - NikkyD

7

我已经阅读了它,但我认为它不适合我正在开发的网站。 - Federico klez Culloca

5

定义一个明确的页面列表,然后使用它来检查输入。是的,这更费力,但它使得允许什么和不允许什么变得非常清晰。例如:

$AVAILABLE_PAGES = array('home', 'news',  ...);
$AVAILABLE_PAGES = array_fill_keys($AVAILABLE_PAGES, 1);

$page = $_GET['page'];
if (!$AVAILABLE_PAGES[$page]) {
   header("HTTP/1.0 404 Not Found");
   die('Page not found.');
}

include "pages/$page.php";

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接