CodeQL 文档

不完整的字符串转义或编码

ID: js/incomplete-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 代码库中的查询

清理不受信任的输入是防止注入攻击(如 SQL 注入或跨站脚本攻击)的常见技术。通常,这是通过以特定于域的方式转义元字符(如引号)来完成的,这样它们就被视为普通字符。

但是,直接使用字符串 replace 方法执行转义非常容易出错。常见的错误包括只替换元字符的第一次出现,或者反斜杠转义各种元字符,但不转义反斜杠本身。

在第一种情况下,后面的元字符保持不变,可以用来破坏清理。在第二种情况下,在元字符前面加上反斜杠会导致反斜杠被转义,但元字符显示为未转义,这再次使清理无效。

即使转义的字符串没有在安全敏感的上下文中使用,不完整的转义也可能产生不良影响,例如渲染效果差或输出混乱。

建议

尽可能使用(经过充分测试的)清理库。与自定义实现相比,这些库更有可能正确处理极端情况。

一种更安全的替代方案是设计应用程序,使其无需清理,例如对 SQL 查询使用预处理语句。

否则,请确保使用带有g 标志的正则表达式,以确保替换所有出现的情况,并请记住在适用时转义反斜杠。

示例

例如,假设我们希望将用户控制的字符串accountNumber 嵌入到 SQL 查询中,作为字符串文字的一部分。为了避免 SQL 注入,我们需要确保字符串不包含未转义的单引号字符。以下函数试图通过将单引号加倍来确保这一点,从而对它们进行转义

function escapeQuotes(s) {
  return s.replace("'", "''");
}

按照目前的形式,这个清理器无效:如果 replace 的第一个参数是字符串文字(如本例所示),则只替换该字符串的第一次出现。

如上所述,函数escapeQuotes 应该替换为专门的清理库,例如 npm 模块sqlstring。许多其他清理库可从 npm 和其他来源获得。

如果这不是一个选项,则应将escapeQuotes 重写为使用带有g(“全局”)标志的正则表达式

function escapeQuotes(s) {
  return s.replace(/'/g, "''");
}

请注意,包含全局标志非常重要:s.replace(/'/, "''")带有全局标志等效于上面的第一个示例,并且只替换第一个引号。

参考资料

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