简体   繁体   English

如何通过URL防止XSS?

[英]How to prevent XSS via URL?

I'm familiar with the usual persistent XSS, where content coming from user input should be escaped on the way out to the templates (html entities). 我熟悉通常的持久性XSS,在这种情况下,来自用户输入的内容应在通往模板(html实体)的途中进行转义。

Recently, I encountered a non-persistent one, where a user can just send in the script on the URL where the URL is displayed somewhere on the page. 最近,我遇到了一个非持久性的问题,用户可以在URL上的脚本中发送该URL,而该URL则显示在页面的某处。 In my case, it was a link tag. 就我而言,这是一个链接标记。

So I have the following link tag that uses the current URL. 因此,我有以下使用当前URL的链接标记。

<link rel="next" href="{current_url}" />

The problem is when someone sends a link such as: 问题是当某人发送链接时,例如:

www.example.com/?%27;alert...

It could be a %27 (single quote) and %22 (double quote) that will close the tag, therefore allowing the user to input scripts, etc. 可能是%27(单引号)和%22(双引号)将关闭标签,因此允许用户输入脚本等。

I know the usual way of preventing XSS would be to use html entities. 我知道防止XSS的通常方法是使用html实体。 In this case, won't this break the URL? 在这种情况下,这不会破坏URL吗? Is it possible to use url encode instead? 是否可以改用url编码?

Btw, I'm using PHP and would prefer to use native functions. 顺便说一句,我正在使用PHP,并且希望使用本机函数。

I know you said you preferred native functions, but I have generally been able to find ways to beat most solutions. 我知道您说过您喜欢本机功能,但是我通常能够找到击败大多数解决方案的方法。 This library, however, definitely does the job. 但是,该库肯定可以完成工作。 It is a little slow if you run a ton of executions (> 1000 per request would slow your page down). 如果您运行大量执行,速度会有些慢(每个请求> 1000会使页面速度变慢)。

http://htmlpurifier.org/ http://htmlpurifier.org/

All content coming from users should be escaped, whether from the URL or from the database. 来自用户的所有内容都应转义,无论是从URL还是从数据库。 In this case, you'll just do URL encoding instead of HTML entities. 在这种情况下,您将只执行URL编码而不是HTML实体。 It's possible your templating engine is already smart enough to do this for values going into HTML attributes. 您的模板引擎可能已经足够聪明,可以对进入HTML属性的值执行此操作。

Like this: Check this answer, it's the one with the function below: XSS filtering function in PHP 像这样:检查此答案,它是具有以下功能的答案: PHP中的XSS过滤功能

 function xss_clean($data)
    {
        /*
         * Function to clean a string to prevent XSS attack.
         */

        // Fix &entity\n;
        $data = str_replace(array('&amp;','&lt;','&gt;'), array('&amp;amp;','&amp;lt;','&amp;gt;'), $data);
        $data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data);
        $data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data);

        // decode
        $data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');

        // Remove any attribute starting with "on" or xmlns
        $data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);

        // Remove javascript: and vbscript: protocols
        $data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
        $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
        $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);

        // Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
        $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
        $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
        $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);

        // Remove namespaced elements (we do not need them)
        $data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);

        do
        {
            // Remove really unwanted tags
            $old_data = $data;
            $data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
        }
        while ($old_data !== $data);

        // we are done...
        return $data;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM