允许在表单输入中使用代码片段,同时防止 XSS 和 SQL 注入攻击
如何允许将代码片段输入到 FCKeditor 等编辑器(如 stackoverflow 那样)或任何其他编辑器中,同时防止 XSS、SQL 注入和相关攻击。
How can one allow code snippets to be entered into an editor (as stackoverflow does) like FCKeditor or any other editor while preventing XSS, SQL injection, and related attacks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这里的部分问题是您想要允许某些类型的 HTML,对吧? 例如链接。 但是您需要清理那些可能包含 XSS 攻击的 HTML 标签,例如脚本标签,甚至事件处理程序属性或 href 或以“javascript:”开头的其他属性。 因此,对您的问题的完整答案需要比“替换特殊字符”更复杂,因为这不允许链接。
防止 SQL 注入可能在某种程度上取决于您的平台选择。 我首选的 Web 平台有一个用于参数化查询的内置语法,这将主要防止 SQL 注入(称为 cfqueryparam)。 如果您使用 PHP 和 MySQL,则有一个类似的本机 mysql_escape() 函数。 (我不确定 PHP 函数在技术上创建了参数化查询,但到目前为止,它在防止 sql 注入尝试方面对我来说效果很好,因为我已经看到了一些安全存储在数据库中的尝试。)
关于 XSS 保护,出于这种原因,我曾经使用正则表达式来清理输入,但后来放弃了这种方法,因为既允许链接之类的东西,又删除危险代码,这很困难。 我已经转向使用 XSLT 作为替代方案。 同样,执行 XSL 转换的方式可能会根据您的平台而有所不同。 不久前,我为 ColdFusion 开发者杂志写了一篇关于如何执行此操作的文章,其中包括您可以使用的样板 XSL 工作表,并展示了如何制作它使用本机 XmlTransform() 函数与 CF 配合使用。
我选择转向 XSLT 的原因有两个。
首先验证输入是否是格式良好的 XML,从而消除使用某些字符串连接技巧进行 XSS 攻击的可能性。
其次,使用 XSL 和 XPath 选择器比使用正则表达式更容易操作 XHTML 数据包,因为与为原始字符串操作而设计的正则表达式相比,它们是专门为处理结构化 XML 文档而设计的。 所以它更干净、更容易,我犯错误的可能性更小,如果我确实发现自己犯了错误,也更容易修复。
另外,当我测试它们时,我发现像 CKEditor(他删除了 F)这样的 WYSIWYG 编辑器保留了格式良好的 XML,因此您不必担心这是一个潜在的问题。
Part of the problem here is that you want to allow certain kinds of HTML, right? Links for example. But you need to sanitize out just those HTML tags that might contain XSS attacks like script tags or for that matter even event handler attributes or an href or other attribute starting with "javascript:". And so a complete answer to your question needs to be something more sophisticated than "replace special characters" because that won't allow links.
Preventing SQL injection may be somewhat dependent upon your platform choice. My preferred web platform has a built-in syntax for parameterizing queries that will mostly prevent SQL-Injection (called cfqueryparam). If you're using PHP and MySQL there is a similar native mysql_escape() function. (I'm not sure the PHP function technically creates a parameterized query, but it's worked well for me in preventing sql-injection attempts thus far since I've seen a few that were safely stored in the db.)
On the XSS protection, I used to use regular expressions to sanitize input for this kind of reason, but have since moved away from that method because of the difficulty involved in both allowing things like links while also removing the dangerous code. What I've moved to as an alternative is XSLT. Again, how you execute an XSL transformation may vary dependent upon your platform. I wrote an article for the ColdFusion Developer's Journal a while ago about how to do this, which includes both a boilerplate XSL sheet you can use and shows how to make it work with CF using the native XmlTransform() function.
The reason why I've chosen to move to XSLT for this is two fold.
First validating that the input is well-formed XML eliminates the possibility of an XSS attack using certain string-concatenation tricks.
Second it's then easier to manipulate the XHTML packet using XSL and XPath selectors than it is with regular expressions because they're designed specifically to work with a structured XML document, compared to regular expressions which were designed for raw string-manipulation. So it's a lot cleaner and easier, I'm less likely to make mistakes and if I do find that I've made a mistake, it's easier to fix.
Also when I tested them I found that WYSIWYG editors like CKEditor (he removed the F) preserve well-formed XML, so you shouldn't have to worry about that as a potential issue.
相同的规则适用于保护:过滤输入,转义输出。
在输入包含代码的情况下,过滤仅意味着字符串必须包含可打印字符,并且可能有长度限制。
将文本存储到数据库中时,要么使用查询参数,要么对字符串进行转义,以确保不存在会造成 SQL 注入漏洞的字符。 代码可能包含更多符号和非字母字符,但在 SQL 注入方面您必须注意的字符与普通文本相同。
不要尝试复制正确的转义函数。 大多数数据库库已经包含一个函数,可以对所有需要转义的字符进行正确的转义(例如,这可能是特定于数据库的)。 它还应该处理字符集的特殊问题。 只需使用您的库提供的功能即可。
我不明白为什么人们说“使用存储过程!” 存储过程没有提供针对 SQL 注入的特殊保护。 如果将未转义的值插入 SQL 字符串并执行结果,则很容易受到 SQL 注入的攻击。 无论您是在应用程序代码中还是在存储过程中执行此操作,都没有关系。
输出到 Web 演示文稿时,转义 HTML 特殊字符,就像处理任何文本一样。
The same rules apply for protection: filter input, escape output.
In the case of input containing code, filtering just means that the string must contain printable characters, and maybe you have a length limit.
When storing text into the database, either use query parameters, or else escape the string to ensure you don't have characters that create SQL injection vulnerabilities. Code may contain more symbols and non-alpha characters, but the ones you have to watch out for with respect to SQL injection are the same as for normal text.
Don't try to duplicate the correct escaping function. Most database libraries already contain a function that does correct escaping for all characters that need escaping (e.g. this may be database-specific). It should also handle special issues with character sets. Just use the function provided by your library.
I don't understand why people say "use stored procedures!" Stored procs give no special protection against SQL injection. If you interpolate unescaped values into SQL strings and execute the result, this is vulnerable to SQL injection. It doesn't matter if you are doing it in application code versus in a stored proc.
When outputting to the web presentation, escape HTML-special characters, just as you would with any text.
防止 SQL 注入攻击的最佳方法是确保在进行数据库调用时使用参数化查询或存储过程。 通常,我还建议执行一些基本的输入清理,但由于您需要接受用户的代码,因此这可能不是一个选择。
另一方面(将用户的输入呈现到浏览器时),对数据进行 HTML 编码将导致任何恶意 JavaScript 等被呈现为文字文本,而不是执行在客户端的浏览器中。 任何像样的 Web 应用服务器框架都应该具备此功能。
The best thing that you can do to prevent SQL injection attacks is to make sure that you use parameterized queries or stored procedures when making database calls. Normally, I would also recommend performing some basic input sanitization as well, but since you need to accept code from the user, that might not be an option.
On the other end (when rendering the user's input to the browser), HTML encoding the data will cause any malicious JavaScript or the like to be rendered as literal text rather than executed in the client's browser. Any decent web application server framework should have the capability.
我想说一个可以替换所有 < 通过 < 等(例如,在 PHP 上使用 htmlentities),然后使用某种白名单选择安全标签。 问题是白名单可能有点太严格了。
下面是一个 PHP 示例
为了防止 SQL 注入,您可以将所有 ' 和 \ 字符替换为“无害”的等效字符,例如 \' 和 \,这样下面的 C 行
就不会在数据库中产生任何负面结果。
I'd say one could replace all < by <, etc. (using htmlentities on PHP, for example), and then pick the safe tags with some sort of whitelist. The problem is that the whitelist may be a little too strict.
Here is a PHP example
To prevent SQL injections, you could replace all ' and \ chars by an "innofensive" equivalent, like \' and \, so that the following C line
Wouldn't have any negative results in the database.