且构网

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

如何避免“跨站点脚本攻击”

更新时间:2023-01-08 15:54:35


我确信它可以完成fx。在PHP中通过验证表单

I'm sure it can be done fx. in PHP by validating forms

不是。输入阶段完全是解决XSS问题的错误地方。

Not really. The input stage is entirely the wrong place to be addressing XSS issues.

如果用户输入,例如< script> alert(document.cookie) )< / script> 进入输入,这本身没有任何问题。我刚刚在这条消息中做到了,如果***不允许它,我们在网站上谈论JavaScript时会遇到很大困难!在大多数情况下,您希望允许任何输入(*),以便用户可以使用< 字符来表示小于号。

If the user types, say <script>alert(document.cookie)</script> into an input, there is nothing wrong with that in itself. I just did it in this message, and if *** didn't allow it we'd have great difficulty talking about JavaScript on the site! In most cases you want to allow any input(*), so that users can use a < character to literally mean a less-than sign.

问题是,当你将一些文本写入HTML页面时,你必须正确地将其转义为它所进入的上下文。对于PHP,这意味着在输出阶段使用 htmlspecialchars()

The thing is, when you write some text into an HTML page, you must escape it correctly for the context it's going into. For PHP, that means using htmlspecialchars() at the output stage:

<p> Hello, <?php echo htmlspecialchars($name); ?>! </p>

[PHP提示:你可以自己定义一个名字较短的函数 echo htmlspecialchars ,因为每次要将变量放入某些HTML时,这都需要进行大量的输入。]

[PHP hint: you can define yourself a function with a shorter name to do echo htmlspecialchars, since this is quite a lot of typing to do every time you want to put a variable into some HTML.]

这个无论文本来自何处,无论是否来自用户提交的表单,都是必要的。虽然用户提交的数据是忘记HTML编码的最危险的地方,但关键是你要用一种格式的字符串(纯文本)并将其插入另一种格式(HTML)的上下文中。每当您将文本放入不同的上下文时,您将需要一个适合该上下文的编码/转义方案。

This is necessary regardless of where the text comes from, whether it's from a user-submitted form or not. Whilst user-submitted data is the most dangerous place to forget your HTML-encoding, the point is really that you're taking a string in one format (plain text) and inserting it into a context in another format (HTML). Any time you throw text into a different context, you're going to need an encoding/escaping scheme appropriate to that context.

例如,如果您将文本插入JavaScript字符串文字,你必须转义引号字符,反斜杠和换行符。如果将文本插入URL中的查询组件,则需要将大多数非字母数字转换为%xx 序列。每个环境都有自己的规则;你必须知道哪个是你选择的语言/框架中每个上下文的正确功能。你无法通过在输入阶段修改表单提交来解决这些问题 - 虽然很多天真的PHP程序员都会尝试,这就是为什么如此多的应用程序在极端情况下搞砸了你的输入但仍然不安全。

For example if you insert text into a JavaScript string literal, you would have to escape the quote character, the backslash and newlines. If you insert text into a query component in a URL, you will need to convert most non-alphanumerics into %xx sequences. Every context has its own rules; you have to know which is the right function for each context in your chosen language/framework. You cannot solve these problems by mangling form submissions at the input stage—though many naïve PHP programmers try, which is why so many apps mess up your input in corner cases and still aren't secure.

(*:好吧,几乎都是。有一个合理的论据可以过滤掉提交文本中的ASCII控制字符。允许它们做任何好事都是不太可能的。
加上当然你会有您希望执行的特定于应用程序的验证,例如确保电子邮件字段看起来像电子邮件地址,或者这些数字确实是数字。但这不是可以全部应用于所有输入的内容你摆脱了麻烦。)

(*: well, almost any. There's a reasonable argument for filtering out the ASCII control characters from submitted text. It's very unlikely that allowing them would do any good. Plus of course you will have application-specific validations that you'll want to do, like making sure an e-mail field looks like an e-mail address or that numbers really are numeric. But this is not something that can be blanket-applied to all input to get you out of trouble.)