且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何防止跨站点脚本

更新时间:2023-01-08 15:55:05

请勿在输入期间尝试防止XSS攻击.始终在输出时转义.

另请参见:由于MySQL列被截断而在Wordpress 4.2中存储了XSS .对输出进行过滤会避免这些情况.

Do not attempt to prevent XSS attacks during input. Always escape on output.

See also: Stored XSS in Wordpress 4.2 caused by MySQL column truncation. Filtering on output would have prevented these conditions.

相反,您要做的只是使用准备好的语句并将数据裸存储. (当然,您仍然应该验证数据!请确保他们在您要求输入电子邮件地址时给了您一个电子邮件地址,等等.)

Instead, what you want to do is just use prepared statements and store the data naked. (You should still validate the data of course! Make sure they've given you an email address when you asked for one, etc.)

从数据库中提取数据以显示在网页上时,即要过滤时.并且您想要这样做(假设您不需要允许用户提供一些HTML):

When you are pulling the data from the database to display on a webpage, that is when you want to filter. And you want to do it like this (assuming you don't need to allow users to provide some HTML):

echo htmlentities($row['column'], ENT_QUOTES | ENT_HTML5, 'UTF-8');

为什么ENT_QUOTES | ENT_HTML5'UTF-8'?

我假设您的网页使用的是HTML5(即<!DOCTYPE html>),而您的字符集为UTF-8(即在<meta>标记以及HTTP Content-Type标头中).如果两者都使用其他内容,请进行调整.

Why ENT_QUOTES | ENT_HTML5 and 'UTF-8'?

I'm assuming your web page is using HTML5 (i.e. <!DOCTYPE html>) and your charset is UTF-8 (i.e. in the <meta> tag as well as in the HTTP Content-Type header). Please adjust if you're using something different for either.

我们指定ENT_QUOTES告诉htmlentities()转义引号字符("').这对于以下情况很有用:

We specify ENT_QUOTES to tell htmlentities() to escape quote characters (" and '). This is helpful for situations such as:

<input type="text" name="field" value="<?php echo $escaped_value; ?>" />

如果您未能指定ENT_QUOTES并且攻击者只需要将" onload="alert('XSS');作为值传递给该表单字段,就可以了!即时客户端代码执行.

If you failed to specify ENT_QUOTES and attacker simply needs to pass " onload="alert('XSS'); as a value to that form field and, presto! Instant client-side code execution.

我们指定'UTF-8',所以htmlentities()知道要使用的字符集.我们这样做的原因是,如针对mysql_real_escape_string() 演示了,错误的(尤其是由攻击者控制的)字符编码可能会失败基于字符串的转义策略.

We specify 'UTF-8' so htmlentities() knows what character set to work with. The reason we do this is, as demonstrated against mysql_real_escape_string(), an incorrect (especially attacker-controlled) character encoding can defeat string-based escaping strategies.

请注意,这将转义所有HTML特殊字符,并阻止用户提供任何标记.如果您需要允许某些 HTML,我们概述了防止XSS的***策略.简而言之:

Note that this will escape all HTML special characters and prevent users from supplying any markup. If you need to allow some HTML, we outlined the best strategies for preventing XSS. In a nutshell:

  • 使用树枝吗?以下示例是安全的.请注意,使用{% autoescape %}块指定默认策略,但对于other_variable,将其用|e('html')覆盖:

  • Using Twig? The below example is safe. Note the use of {% autoescape %} blocks for specifying the default strategy, but overriding it with |e('html') for other_variable:

{% autoescape 'html_attr' %}
<p class="{{ variable }}" id="{{ var_two }}">
    {{ other_variable|e('html') }}
</p>
{% endautoescape %}

  • 如果其他所有方法均失败,请使用 HTML净化器.
  • If all else fails, use HTML Purifier.