CodeQL 文档

从用户控制的来源构建谓词

ID: swift/predicate-injection
Kind: path-problem
Security severity: 8.8
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-943
Query suites:
   - swift-code-scanning.qls
   - swift-security-extended.qls
   - swift-security-and-quality.qls

点击查看 CodeQL 仓库中的查询

谓词表示逻辑条件,可用于检查对象是否与之匹配。如果谓词是从用户提供的数据构建的,而没有进行足够的清理,攻击者可能会改变谓词的总体含义。

建议

从不受信任的数据构建谓词时,应将其传递到初始化过程中的适当 arguments 参数,或作为评估前的替换变量数组。不应将其追加或连接到谓词主体。

示例

在以下不安全的示例中,NSPredicate 直接从 HTTP 请求获取的数据构建。这是不可信的,并且攻击者可以任意设置它以改变谓词的含义

let remoteString = try String(contentsOf: URL(string: "https://example.com/")!)

let filenames: [String] = ["img1.png", "img2.png", "img3.png", "img.txt", "img.csv"]

let predicate = NSPredicate(format: "SELF LIKE \(remoteString)")
let filtered = filenames.filter(){ filename in
    predicate.evaluate(with: filename)
}
print(filtered)

更好的方法是使用 NSPredicate 初始化程序的 arguments 参数。即使攻击者控制外部获取的数据,这也能防止攻击者改变谓词的含义,如以下安全示例所示

let remoteString = try String(contentsOf: URL(string: "https://example.com/")!)

let filenames: [String] = ["img1.png", "img2.png", "img3.png", "img.txt", "img.csv"]

let predicate = NSPredicate(format: "SELF LIKE %@", remoteString)
let filtered = filenames.filter(){ filename in
    predicate.evaluate(with: filename)
}
print(filtered)

参考资料

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