使用正则表达式解析文本防止XSS
Using regular expression to parse text to prevent XSS
我正在尝试解析 html
格式的文本块,它只允许 bold
<b></b>
和 italic
<i></i>
。
我知道几乎不可能解析 html 文本来保护 XSS。但是只考虑到bold
和italic
的约束,用regex过滤掉不需要的标签是否可行?
谢谢。
--- 编辑 ---
我打算在客户端进行解析,然后立即渲染。
在得出结论之前,请针对此测试您的代码。
http://voog.github.io/wysihtml/examples/simple.html
顺便说一句,为什么问题本身被否决了?
--- 关闭 ---
我选择了@Siguza 的回答来结束这个讨论。
- 解析标签,替换为特殊的分隔符(或存储索引)。
- XSS sanitize the input.
- 用标签替换分隔符。
- 确保您没有任何不匹配的标签。
XSS 清理需要在服务器端完成 - 客户端控制客户端,并且可以绕过那里的任何检查。
我仍然认为 OWASP Cheat Sheet 足以进行 XSS 清理,仅替换 空的粗体和斜体标签不应损害任何规则。
你能用正则表达式做到这一点吗?有点儿。您必须编写一个正则表达式来查找所有不是 b 或 i 标签的标签。下面是一个简单的例子,它匹配任何超过1个字符的标签,只允许<a>
、<b>
、<i>
、<p>
、[=15] =]、<s>
和 <u>
(无空格、无属性且不允许 类),我相信这符合您的需要。很可能有一个更精确的正则表达式,但这很简单。它可能会或可能不会捕获所有内容。应该不会吧。
<[^>]{2,}[^/]>
你应该用正则表达式来做这个吗?不,还有其他更好、更安全的方法。
我能想到的最简单且可能是最安全的方法(使用正则表达式执行此操作)是首先将所有 <
和 >
替换为 <
和 >
分别,然后显式 "un-replace" b
和 i
标签。
要替换 <
和 >
,您只需要文本替换,不需要正则表达式。但我相信你无论如何都知道如何在正则表达式中做到这一点。
要重新启用 i
和 b
标签,您还可以使用四个文本替换:
<b> => <b>
</b> => </b>
<i> => <i>
</i> => </i>
或者,在正则表达式中将 /<(\/?[bi])>/g
替换为 <>
。
但是...
...为了完整起见,实际上 是 可能只需要一个正则表达式替换:
将/<(|\/|[^>\/bi]|\/[^>bi]|[^\/>][^>]+|\/[^>][^>]+)>/g
替换为<>
。
我不保证它是防弹的,但我使用 RegExr 针对以下块对其进行了测试,它似乎可以支撑:
<>Test</>
<i>Test</i>
<iii>Test</iii>
<b>Test</b>
<bbb>Test</bbb>
<a>Test</a>
<abc>Test</abc>
<some tag with="attributes">Test</some>
<br/>
<br />
我正在尝试解析 html
格式的文本块,它只允许 bold
<b></b>
和 italic
<i></i>
。
我知道几乎不可能解析 html 文本来保护 XSS。但是只考虑到bold
和italic
的约束,用regex过滤掉不需要的标签是否可行?
谢谢。
--- 编辑 ---
我打算在客户端进行解析,然后立即渲染。
在得出结论之前,请针对此测试您的代码。 http://voog.github.io/wysihtml/examples/simple.html
顺便说一句,为什么问题本身被否决了?
--- 关闭 ---
我选择了@Siguza 的回答来结束这个讨论。
- 解析标签,替换为特殊的分隔符(或存储索引)。
- XSS sanitize the input.
- 用标签替换分隔符。
- 确保您没有任何不匹配的标签。
XSS 清理需要在服务器端完成 - 客户端控制客户端,并且可以绕过那里的任何检查。
我仍然认为 OWASP Cheat Sheet 足以进行 XSS 清理,仅替换 空的粗体和斜体标签不应损害任何规则。
你能用正则表达式做到这一点吗?有点儿。您必须编写一个正则表达式来查找所有不是 b 或 i 标签的标签。下面是一个简单的例子,它匹配任何超过1个字符的标签,只允许<a>
、<b>
、<i>
、<p>
、[=15] =]、<s>
和 <u>
(无空格、无属性且不允许 类),我相信这符合您的需要。很可能有一个更精确的正则表达式,但这很简单。它可能会或可能不会捕获所有内容。应该不会吧。
<[^>]{2,}[^/]>
你应该用正则表达式来做这个吗?不,还有其他更好、更安全的方法。
我能想到的最简单且可能是最安全的方法(使用正则表达式执行此操作)是首先将所有 <
和 >
替换为 <
和 >
分别,然后显式 "un-replace" b
和 i
标签。
要替换 <
和 >
,您只需要文本替换,不需要正则表达式。但我相信你无论如何都知道如何在正则表达式中做到这一点。
要重新启用 i
和 b
标签,您还可以使用四个文本替换:
<b> => <b>
</b> => </b>
<i> => <i>
</i> => </i>
或者,在正则表达式中将 /<(\/?[bi])>/g
替换为 <>
。
但是...
...为了完整起见,实际上 是 可能只需要一个正则表达式替换:
将/<(|\/|[^>\/bi]|\/[^>bi]|[^\/>][^>]+|\/[^>][^>]+)>/g
替换为<>
。
我不保证它是防弹的,但我使用 RegExr 针对以下块对其进行了测试,它似乎可以支撑:
<>Test</>
<i>Test</i>
<iii>Test</iii>
<b>Test</b>
<bbb>Test</bbb>
<a>Test</a>
<abc>Test</abc>
<some tag with="attributes">Test</some>
<br/>
<br />