这是简单的 JavaScript 注入的一种可能的解决方案。
黑客可以突破这一点,正则表达式是不够的。
查看这个正则表达式:
(?<=<[_a-zA-Z][^<]*?)\s+href\s*=\s*("?)\s*javascript:(\\?[^"])*[\s<>]?\1?
- HTML 属性允许带双引号
",也可以不带引号(只要 URL 中没有空格)。这已在表达式中得到纠正。
- 单引号
' 中的属性也是有效的HTML。您应该运行两次正则表达式,第二次使用' 而不是"。
- 引号存在一般性问题,因为 JavaScript 可能会在其中转义引号以规避您的保护。请参阅下文。
-
\s* 表示“零个或多个空白字符(空格、换行符等)”,因此我们可以忽略可选的空白。
- 捕获第一部分以便替换为
将完全删除href。
- 正则表达式会保留其他属性,见下面的演示链接
演示
您可以在此处查看正在运行的正则表达式:
https://regex101.com/r/1SPJKy/5
它适用于以下测试用例:
<a title="Click me!" href="javascript:console.log(document.cookie)" target="_top"></a>
<a title="Click me!" href = "javascript:console.log(document.cookie)" target="_top"></a>
<a title="Click me!" href=" javascript:console.log('' + document.cookie)" target="_top"></a>
<a title="Click me!" href='javascript:console.log(document.cookie)' target="_top"></a>
<a title="Click me!" href=javascript:console.log(document.cookie) target="_top"></a>
<a title="Click me!"
href=
"javascript:console.log(document.cookie+\"\");"
target="_top">
</a>
Just text: href="javascript:console.log(document.cookie)"
HTML 被替换为这个(使用",所以不要忘记再次使用' 运行它):
<a title="Click me!" target="_top"></a>
<a title="Click me!" target="_top"></a>
<a title="Click me!" target="_top"></a>
<a title="Click me!" href='javascript:console.log(document.cookie)' target="_top"></a>
<a title="Click me!" "_top"></a>
<a title="Click me!" \");"
target="_top">
</a>
Just text: href="javascript:console.log(document.cookie)"
但请不要...
- 如果 JavaScript 使用
'' + 、"" + 、\" 等变得有点聪明,正则表达式将会中断。
- 输出将不再是有效的 HTML,但至少删除了
javascript: 部分。
- 无论如何,您必须确保 HTML 已标准化,因此所有属性都包含在
" 分隔符中。 CKEditor 有一个 HTML Tidy 插件,我敢肯定。
-
[^"] 之类的表达式或您的lookbehind 断言只会看起来到目前为止。黑客可以使 HTML 达到几千字节或几兆字节长。这使得浏览器的 RegEx 引擎“提前”放弃。否则浏览器将面临无限循环或 UI 锁定的风险,因此可以理解,它可以找到的内容是有限的。
-
onclick 之类的事件呢?
您应该查看 CKEditors 最佳实践页面:
https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#security
改为访问 DOM
话虽如此,HTML 需要被解析。将其用作 DOM,而不是文本。
AFAIK CKEditor 的 HTML 元素可作为 DOM 元素访问。例如,您可以使用此 JavaScript 选择这些元素:
document.querySelectorAll('[href*=javascript]')
无论属性是如何编写的,这都会获取这些元素。如果浏览器无法更正它,它将不适用于损坏的 HTML。但是正则表达式也有同样的问题,无论如何都不会导致有效的 href。
也许你可以尝试一下。