CodeQL 文档

不完整的多字符清理

ID: js/incomplete-multi-character-sanitization
Kind: problem
Security severity: 7.8
Severity: warning
Precision: high
Tags:
   - correctness
   - security
   - external/cwe/cwe-020
   - external/cwe/cwe-080
   - external/cwe/cwe-116
Query suites:
   - javascript-code-scanning.qls
   - javascript-security-extended.qls
   - javascript-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

清理不受信任的输入是防止注入攻击和其他安全漏洞的常见技术。正则表达式经常被用于执行此清理。但是,当正则表达式匹配多个连续字符时,仅替换一次会导致不安全文本在清理后的输入中重新出现。

攻击者可以利用此问题来构造输入,这些输入在使用无效的正则表达式清理后仍然包含恶意代码或内容。这会导致代码执行、数据泄露或其他漏洞。

建议

为了防止此问题,强烈建议尽可能使用经过良好测试的清理库。这些库更有可能处理边缘情况并确保有效清理。

如果库不可用,您可以考虑其他策略来解决此问题。例如,反复应用正则表达式替换,直到不再进行任何替换,或者重写正则表达式以匹配单个字符而不是整个不安全文本。

示例

考虑以下旨在删除所有 HTML 注释开始和结束标签的 JavaScript 代码

str.replace(/<!--|--!?>/g, "");   

给定输入字符串“<!<!— comment —>>”,输出将为“<!– comment –>”,其中仍然包含 HTML 注释。

解决此问题的一种可能方法是反复应用正则表达式替换,直到不再进行任何替换。这可以确保不安全文本不会在清理后的输入中重新出现,从而有效地删除目标模式的所有实例

function removeHtmlComments(input) {  
  let previous;  
  do {  
    previous = input;  
    input = input.replace(/<!--|--!?>/g, "");  
  } while (input !== previous);  
  return input;  
}  

示例

另一个示例是以下旨在删除脚本标签的正则表达式

str.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/g, "");  

如果输入字符串为“<scrip<script>is removed</script>t>alert(123)</script>”,输出将为“<script>alert(123)</script>”,其中仍然包含脚本标签。

解决此问题的一种方法是重写正则表达式以匹配单个字符(“<”和“>”),而不是整个不安全文本。这简化了清理过程,并确保所有潜在的不安全字符都被删除

function removeAllHtmlTags(input) {  
  return input.replace(/<|>/g, "");  
}

另一种可能的解决方案是使用流行的 sanitize-html npm 库。它保留了大多数安全的 HTML 标签,同时删除所有不安全的标签和属性。

const sanitizeHtml = require("sanitize-html");
function removeAllHtmlTags(input) {  
  return sanitizeHtml(input);  
}

示例

最后,考虑使用正则表达式 /\.\.\// 的路径清理器

str.replace(/\.\.\//g, "");  

正则表达式试图从 str 中删除所有 /../ 的出现。这不会按预期工作:例如,对于字符串 /./.././,它将删除中间的 /../ 的单个出现,但字符串的其余部分将变为 /../,这是我们试图删除的子字符串的另一个实例。

解决此问题的一种可能方法是使用“sanitize-filename” npm 库进行路径清理。此库专门设计用于处理路径清理,并且应该处理所有边缘情况并确保有效清理

const sanitize = require("sanitize-filename");  
  
function sanitizePath(input) {  
  return sanitize(input);  
}  

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私