【问题标题】:Regex to find specific word and remove complete tag attrubute from html正则表达式查找特定单词并从 html 中删除完整的标记属性
【发布时间】:2022-01-12 16:24:07
【问题描述】:

我想在我的 HTML 文本中捕获javascript:***,当正则表达式找到它时,我希望它的属性也被删除,我还创建了一个正则表达式,但它并没有涵盖所有情况,我附上了我的代码以及该正则表达式未涵盖的情况。

正则表达式:

/(?<=<[_a-zA-Z][^<]*?)\s+href="javascript:[^"]*"/

不包括以下情况:

href='javascript:
href = "javascript:
href=" javascript:

href=
   "javascript:

所以我想要找到javascript: 并删除其完整属性的东西

【问题讨论】:

  • 你可以设置一个 content-security-policy 来阻止任何这个内联 JavaScript 运行
  • @ControlAltDel 基本上,我正在使用 CKEditor,我想阻止 XSS。
  • 是的,这正是 content-security-policy 的用途:防止 XSS
  • 不,它在 CKEditor 中不起作用
  • 不要试图用正则表达式操作 HTML。那就是疯狂:stackoverflow.com/questions/1732348/…

标签: javascript regex


【解决方案1】:

这是简单的 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)"

但请不要...

  1. 如果 JavaScript 使用 '' + "" + \" 等变得有点聪明,正则表达式将会中断。
  2. 输出将不再是有效的 HTML,但至少删除了 javascript: 部分。
  3. 无论如何,您必须确保 HTML 已标准化,因此所有属性都包含在 " 分隔符中。 CKEditor 有一个 HTML Tidy 插件,我敢肯定。
  4. [^"] 之类的表达式或您的lookbehind 断言只会看起来到目前为止。黑客可以使 HTML 达到几千字节或几兆字节长。这使得浏览器的 RegEx 引擎“提前”放弃。否则浏览器将面临无限循环或 UI 锁定的风险,因此可以理解,它可以找到的内容是有限的。
  5. 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。
也许你可以尝试一下。

【讨论】:

  • 如果除了href之外还有其他属性怎么办?
  • 您可以点击 regex101 的链接并自己尝试一下。其他属性将被保留。
  • @ZainKhan 我已经更新了答案并进行了更详细的介绍。还再次更新了正则表达式和匹配的 regex101 链接。严格强调使用 DOM 代替(请参阅答案的最后一部分)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
  • 2019-04-12
  • 2019-11-26
  • 1970-01-01
  • 2017-01-18
  • 2022-07-14
  • 1970-01-01
相关资源
最近更新 更多