From 871e1153c4fcfcff7be9495817c5cdab1955f372 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 13 Nov 2026 13:19:43 +0000 Subject: [PATCH 01/10] Unified: Port the full test for cleartext-logging from original Swift. --- .../CleartextLogging.expected | 106 +++++ .../CleartextLoggingTest.swift | 396 ++++++++++++++++++ 2 files changed, 502 insertions(+) create mode 100644 unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift diff --git a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected index cb3f1cb61f2f..75df1da5a60e 100644 --- a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected +++ b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected @@ -1,8 +1,114 @@ #select | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | Logging of $@ | CleartextLoggingBad.swift:2:35:2:42 | password | sensitive data | +| CleartextLoggingTest.swift:167:11:167:18 | password | CleartextLoggingTest.swift:167:11:167:18 | password | CleartextLoggingTest.swift:167:11:167:18 | password | Logging of $@ | CleartextLoggingTest.swift:167:11:167:18 | password | sensitive data | +| CleartextLoggingTest.swift:168:11:168:18 | password | CleartextLoggingTest.swift:168:11:168:18 | password | CleartextLoggingTest.swift:168:11:168:18 | password | Logging of $@ | CleartextLoggingTest.swift:168:11:168:18 | password | sensitive data | +| CleartextLoggingTest.swift:169:26:169:33 | password | CleartextLoggingTest.swift:169:26:169:33 | password | CleartextLoggingTest.swift:169:26:169:33 | password | Logging of $@ | CleartextLoggingTest.swift:169:26:169:33 | password | sensitive data | +| CleartextLoggingTest.swift:170:11:170:18 | password | CleartextLoggingTest.swift:170:11:170:18 | password | CleartextLoggingTest.swift:170:11:170:18 | password | Logging of $@ | CleartextLoggingTest.swift:170:11:170:18 | password | sensitive data | +| CleartextLoggingTest.swift:171:26:171:33 | password | CleartextLoggingTest.swift:171:26:171:33 | password | CleartextLoggingTest.swift:171:26:171:33 | password | Logging of $@ | CleartextLoggingTest.swift:171:26:171:33 | password | sensitive data | +| CleartextLoggingTest.swift:172:42:172:49 | password | CleartextLoggingTest.swift:172:42:172:49 | password | CleartextLoggingTest.swift:172:42:172:49 | password | Logging of $@ | CleartextLoggingTest.swift:172:42:172:49 | password | sensitive data | +| CleartextLoggingTest.swift:179:11:179:18 | password | CleartextLoggingTest.swift:179:11:179:18 | password | CleartextLoggingTest.swift:179:11:179:18 | password | Logging of $@ | CleartextLoggingTest.swift:179:11:179:18 | password | sensitive data | +| CleartextLoggingTest.swift:180:17:180:24 | password | CleartextLoggingTest.swift:180:17:180:24 | password | CleartextLoggingTest.swift:180:17:180:24 | password | Logging of $@ | CleartextLoggingTest.swift:180:17:180:24 | password | sensitive data | +| CleartextLoggingTest.swift:181:24:181:31 | password | CleartextLoggingTest.swift:181:24:181:31 | password | CleartextLoggingTest.swift:181:24:181:31 | password | Logging of $@ | CleartextLoggingTest.swift:181:24:181:31 | password | sensitive data | +| CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | Logging of $@ | CleartextLoggingTest.swift:182:14:182:21 | password | sensitive data | +| CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | CleartextLoggingTest.swift:183:29:183:36 | password | CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | Logging of $@ | CleartextLoggingTest.swift:183:29:183:36 | password | sensitive data | +| CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | Logging of $@ | CleartextLoggingTest.swift:184:36:184:43 | password | sensitive data | +| CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | Logging of $@ | CleartextLoggingTest.swift:191:16:191:23 | password | sensitive data | +| CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | Logging of $@ | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | sensitive data | +| CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | Logging of $@ | CleartextLoggingTest.swift:220:11:220:20 | passphrase | sensitive data | +| CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | Logging of $@ | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | sensitive data | +| CleartextLoggingTest.swift:248:8:248:17 | ... .password | CleartextLoggingTest.swift:248:8:248:17 | ... .password | CleartextLoggingTest.swift:248:8:248:17 | ... .password | Logging of $@ | CleartextLoggingTest.swift:248:8:248:17 | ... .password | sensitive data | +| CleartextLoggingTest.swift:286:8:286:15 | password | CleartextLoggingTest.swift:286:8:286:15 | password | CleartextLoggingTest.swift:286:8:286:15 | password | Logging of $@ | CleartextLoggingTest.swift:286:8:286:15 | password | sensitive data | +| CleartextLoggingTest.swift:289:8:289:25 | ... + ... | CleartextLoggingTest.swift:289:18:289:25 | password | CleartextLoggingTest.swift:289:8:289:25 | ... + ... | Logging of $@ | CleartextLoggingTest.swift:289:18:289:25 | password | sensitive data | +| CleartextLoggingTest.swift:308:8:308:16 | myString9 | CleartextLoggingTest.swift:307:18:307:25 | password | CleartextLoggingTest.swift:308:8:308:16 | myString9 | Logging of $@ | CleartextLoggingTest.swift:307:18:307:25 | password | sensitive data | +| CleartextLoggingTest.swift:313:8:313:17 | myString10 | CleartextLoggingTest.swift:311:19:311:26 | password | CleartextLoggingTest.swift:313:8:313:17 | myString10 | Logging of $@ | CleartextLoggingTest.swift:311:19:311:26 | password | sensitive data | +| CleartextLoggingTest.swift:319:8:319:17 | myString12 | CleartextLoggingTest.swift:318:2:318:9 | password | CleartextLoggingTest.swift:319:8:319:17 | myString12 | Logging of $@ | CleartextLoggingTest.swift:318:2:318:9 | password | sensitive data | +| CleartextLoggingTest.swift:321:8:321:15 | password | CleartextLoggingTest.swift:321:8:321:15 | password | CleartextLoggingTest.swift:321:8:321:15 | password | Logging of $@ | CleartextLoggingTest.swift:321:8:321:15 | password | sensitive data | +| CleartextLoggingTest.swift:365:18:365:24 | authKey | CleartextLoggingTest.swift:365:18:365:24 | authKey | CleartextLoggingTest.swift:365:18:365:24 | authKey | Logging of $@ | CleartextLoggingTest.swift:365:18:365:24 | authKey | sensitive data | +| CleartextLoggingTest.swift:366:18:366:33 | String(...) | CleartextLoggingTest.swift:366:25:366:32 | authKey2 | CleartextLoggingTest.swift:366:18:366:33 | String(...) | Logging of $@ | CleartextLoggingTest.swift:366:25:366:32 | authKey2 | sensitive data | +| CleartextLoggingTest.swift:367:22:367:28 | authKey | CleartextLoggingTest.swift:367:22:367:28 | authKey | CleartextLoggingTest.swift:367:22:367:28 | authKey | Logging of $@ | CleartextLoggingTest.swift:367:22:367:28 | authKey | sensitive data | +| CleartextLoggingTest.swift:368:31:368:37 | authKey | CleartextLoggingTest.swift:368:31:368:37 | authKey | CleartextLoggingTest.swift:368:31:368:37 | authKey | Logging of $@ | CleartextLoggingTest.swift:368:31:368:37 | authKey | sensitive data | +| CleartextLoggingTest.swift:369:16:369:40 | NSString(...) | CleartextLoggingTest.swift:369:33:369:39 | authKey | CleartextLoggingTest.swift:369:16:369:40 | NSString(...) | Logging of $@ | CleartextLoggingTest.swift:369:33:369:39 | authKey | sensitive data | +| CleartextLoggingTest.swift:370:13:370:19 | authKey | CleartextLoggingTest.swift:370:13:370:19 | authKey | CleartextLoggingTest.swift:370:13:370:19 | authKey | Logging of $@ | CleartextLoggingTest.swift:370:13:370:19 | authKey | sensitive data | +| CleartextLoggingTest.swift:371:24:371:30 | authKey | CleartextLoggingTest.swift:371:24:371:30 | authKey | CleartextLoggingTest.swift:371:24:371:30 | authKey | Logging of $@ | CleartextLoggingTest.swift:371:24:371:30 | authKey | sensitive data | +| CleartextLoggingTest.swift:373:19:373:26 | authKey3 | CleartextLoggingTest.swift:373:19:373:26 | authKey3 | CleartextLoggingTest.swift:373:19:373:26 | authKey3 | Logging of $@ | CleartextLoggingTest.swift:373:19:373:26 | authKey3 | sensitive data | +| CleartextLoggingTest.swift:378:16:378:18 | msg | CleartextLoggingTest.swift:377:29:377:35 | authKey | CleartextLoggingTest.swift:378:16:378:18 | msg | Logging of $@ | CleartextLoggingTest.swift:377:29:377:35 | authKey | sensitive data | +| CleartextLoggingTest.swift:383:20:383:22 | msg | CleartextLoggingTest.swift:377:29:377:35 | authKey | CleartextLoggingTest.swift:383:20:383:22 | msg | Logging of $@ | CleartextLoggingTest.swift:377:29:377:35 | authKey | sensitive data | +| CleartextLoggingTest.swift:384:18:384:20 | msg | CleartextLoggingTest.swift:377:29:377:35 | authKey | CleartextLoggingTest.swift:384:18:384:20 | msg | Logging of $@ | CleartextLoggingTest.swift:377:29:377:35 | authKey | sensitive data | +| CleartextLoggingTest.swift:394:29:394:36 | password | CleartextLoggingTest.swift:394:29:394:36 | password | CleartextLoggingTest.swift:394:29:394:36 | password | Logging of $@ | CleartextLoggingTest.swift:394:29:394:36 | password | sensitive data | +| CleartextLoggingTest.swift:395:28:395:33 | secret | CleartextLoggingTest.swift:395:28:395:33 | secret | CleartextLoggingTest.swift:395:28:395:33 | secret | Logging of $@ | CleartextLoggingTest.swift:395:28:395:33 | secret | sensitive data | edges | CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | provenance | | +| CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | provenance | | +| CleartextLoggingTest.swift:183:28:183:37 | ArrayLiteral [ArrayElement] | CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | provenance | | +| CleartextLoggingTest.swift:183:29:183:36 | password | CleartextLoggingTest.swift:183:28:183:37 | ArrayLiteral [ArrayElement] | provenance | | +| CleartextLoggingTest.swift:184:31:184:44 | ArrayLiteral [ArrayElement] | CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | provenance | | +| CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:31:184:44 | ArrayLiteral [ArrayElement] | provenance | | +| CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | provenance | | +| CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | provenance | | +| CleartextLoggingTest.swift:289:18:289:25 | password | CleartextLoggingTest.swift:289:8:289:25 | ... + ... | provenance | | +| CleartextLoggingTest.swift:307:18:307:25 | password | CleartextLoggingTest.swift:308:8:308:16 | myString9 | provenance | | +| CleartextLoggingTest.swift:311:19:311:26 | password | CleartextLoggingTest.swift:313:8:313:17 | myString10 | provenance | | +| CleartextLoggingTest.swift:318:2:318:9 | password | CleartextLoggingTest.swift:318:21:318:31 | [post] & ... | provenance | | +| CleartextLoggingTest.swift:318:21:318:31 | [post] & ... | CleartextLoggingTest.swift:319:8:319:17 | myString12 | provenance | | +| CleartextLoggingTest.swift:366:25:366:32 | authKey2 | CleartextLoggingTest.swift:366:18:366:33 | String(...) | provenance | | +| CleartextLoggingTest.swift:369:33:369:39 | authKey | CleartextLoggingTest.swift:369:16:369:40 | NSString(...) | provenance | | +| CleartextLoggingTest.swift:377:9:377:11 | msg | CleartextLoggingTest.swift:378:16:378:18 | msg | provenance | | +| CleartextLoggingTest.swift:377:9:377:11 | msg | CleartextLoggingTest.swift:383:20:383:22 | msg | provenance | | +| CleartextLoggingTest.swift:377:9:377:11 | msg | CleartextLoggingTest.swift:384:18:384:20 | msg | provenance | | +| CleartextLoggingTest.swift:377:29:377:35 | authKey | CleartextLoggingTest.swift:377:9:377:11 | msg | provenance | | nodes | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | semmle.label | StringInterpolationExpr | | CleartextLoggingBad.swift:2:35:2:42 | password | semmle.label | password | +| CleartextLoggingTest.swift:167:11:167:18 | password | semmle.label | password | +| CleartextLoggingTest.swift:168:11:168:18 | password | semmle.label | password | +| CleartextLoggingTest.swift:169:26:169:33 | password | semmle.label | password | +| CleartextLoggingTest.swift:170:11:170:18 | password | semmle.label | password | +| CleartextLoggingTest.swift:171:26:171:33 | password | semmle.label | password | +| CleartextLoggingTest.swift:172:42:172:49 | password | semmle.label | password | +| CleartextLoggingTest.swift:179:11:179:18 | password | semmle.label | password | +| CleartextLoggingTest.swift:180:17:180:24 | password | semmle.label | password | +| CleartextLoggingTest.swift:181:24:181:31 | password | semmle.label | password | +| CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | semmle.label | StringInterpolationExpr | +| CleartextLoggingTest.swift:182:14:182:21 | password | semmle.label | password | +| CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | semmle.label | getVaList(...) | +| CleartextLoggingTest.swift:183:28:183:37 | ArrayLiteral [ArrayElement] | semmle.label | ArrayLiteral [ArrayElement] | +| CleartextLoggingTest.swift:183:29:183:36 | password | semmle.label | password | +| CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | semmle.label | getVaList(...) | +| CleartextLoggingTest.swift:184:31:184:44 | ArrayLiteral [ArrayElement] | semmle.label | ArrayLiteral [ArrayElement] | +| CleartextLoggingTest.swift:184:36:184:43 | password | semmle.label | password | +| CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | semmle.label | StringInterpolationExpr | +| CleartextLoggingTest.swift:191:16:191:23 | password | semmle.label | password | +| CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | semmle.label | StringInterpolationExpr | +| CleartextLoggingTest.swift:197:16:197:26 | bankAccount | semmle.label | bankAccount | +| CleartextLoggingTest.swift:220:11:220:20 | passphrase | semmle.label | passphrase | +| CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | semmle.label | pass_phrase | +| CleartextLoggingTest.swift:248:8:248:17 | ... .password | semmle.label | ... .password | +| CleartextLoggingTest.swift:286:8:286:15 | password | semmle.label | password | +| CleartextLoggingTest.swift:289:8:289:25 | ... + ... | semmle.label | ... + ... | +| CleartextLoggingTest.swift:289:18:289:25 | password | semmle.label | password | +| CleartextLoggingTest.swift:307:18:307:25 | password | semmle.label | password | +| CleartextLoggingTest.swift:308:8:308:16 | myString9 | semmle.label | myString9 | +| CleartextLoggingTest.swift:311:19:311:26 | password | semmle.label | password | +| CleartextLoggingTest.swift:313:8:313:17 | myString10 | semmle.label | myString10 | +| CleartextLoggingTest.swift:318:2:318:9 | password | semmle.label | password | +| CleartextLoggingTest.swift:318:21:318:31 | [post] & ... | semmle.label | [post] & ... | +| CleartextLoggingTest.swift:319:8:319:17 | myString12 | semmle.label | myString12 | +| CleartextLoggingTest.swift:321:8:321:15 | password | semmle.label | password | +| CleartextLoggingTest.swift:365:18:365:24 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:366:18:366:33 | String(...) | semmle.label | String(...) | +| CleartextLoggingTest.swift:366:25:366:32 | authKey2 | semmle.label | authKey2 | +| CleartextLoggingTest.swift:367:22:367:28 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:368:31:368:37 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:369:16:369:40 | NSString(...) | semmle.label | NSString(...) | +| CleartextLoggingTest.swift:369:33:369:39 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:370:13:370:19 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:371:24:371:30 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:373:19:373:26 | authKey3 | semmle.label | authKey3 | +| CleartextLoggingTest.swift:377:9:377:11 | msg | semmle.label | msg | +| CleartextLoggingTest.swift:377:29:377:35 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:378:16:378:18 | msg | semmle.label | msg | +| CleartextLoggingTest.swift:383:20:383:22 | msg | semmle.label | msg | +| CleartextLoggingTest.swift:384:18:384:20 | msg | semmle.label | msg | +| CleartextLoggingTest.swift:394:29:394:36 | password | semmle.label | password | +| CleartextLoggingTest.swift:395:28:395:33 | secret | semmle.label | secret | subpaths diff --git a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift new file mode 100644 index 000000000000..f4bb1ba71ad2 --- /dev/null +++ b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift @@ -0,0 +1,396 @@ +// --- stubs --- + +class NSObject { } + +func NSLog(_ format: String, _ args: CVarArg...) {} +func NSLogv(_ format: String, _ args: CVaListPointer) {} + +func getVaList(_ args: [CVarArg]) -> CVaListPointer { return CVaListPointer(_fromUnsafeMutablePointer: UnsafeMutablePointer(bitPattern: 0)!) } + +struct OSLogType : RawRepresentable { + static let `default` = OSLogType(rawValue: 0) + let rawValue: UInt8 + init(rawValue: UInt8) { self.rawValue = rawValue} +} + +struct OSLogStringAlignment { + static var none = OSLogStringAlignment() +} + +enum OSLogIntegerFormatting { case decimal } +enum OSLogInt32ExtendedFormat { case none } +enum OSLogFloatFormatting { case fixed } +enum OSLogBoolFormat { case truth } + +struct OSLogPrivacy { + enum Mask { case none } + static var auto = OSLogPrivacy() + static var `private` = OSLogPrivacy() + static var `public` = OSLogPrivacy() + static var sensitive = OSLogPrivacy() + + static func auto(mask: OSLogPrivacy.Mask) -> OSLogPrivacy { return .auto } + static func `private`(mask: OSLogPrivacy.Mask) -> OSLogPrivacy { return .private } + static func `sensitive`(mask: OSLogPrivacy.Mask) -> OSLogPrivacy { return .sensitive } +} + +struct OSLogInterpolation : StringInterpolationProtocol { + typealias StringLiteralType = String + init(literalCapacity: Int, interpolationCount: Int) {} + func appendLiteral(_: Self.StringLiteralType) {} + mutating func appendInterpolation(_ argumentString: @autoclosure @escaping () -> String, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ argumentString: @autoclosure @escaping () -> String, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto, attributes: String) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> Int, format: OSLogIntegerFormatting = .decimal, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> Int8, format: OSLogIntegerFormatting = .decimal, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> Int16, format: OSLogIntegerFormatting = .decimal, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> Int32, format: OSLogInt32ExtendedFormat, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> Int32, format: OSLogInt32ExtendedFormat, privacy: OSLogPrivacy = .auto, attributes: String) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> Int32, format: OSLogIntegerFormatting = .decimal, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> Int64, format: OSLogIntegerFormatting = .decimal, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> UInt, format: OSLogIntegerFormatting = .decimal, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> UInt8, format: OSLogIntegerFormatting = .decimal, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> UInt16, format: OSLogIntegerFormatting = .decimal, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> UInt32, format: OSLogIntegerFormatting = .decimal, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> UInt64, format: OSLogIntegerFormatting = .decimal, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> Double, format: OSLogFloatFormatting = .fixed, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> Double, format: OSLogFloatFormatting = .fixed, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto, attributes: String) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> Float,format: OSLogFloatFormatting = .fixed, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto) {} + mutating func appendInterpolation(_ number: @autoclosure @escaping () -> Float, format: OSLogFloatFormatting = .fixed, align: OSLogStringAlignment = .none, privacy: OSLogPrivacy = .auto, attributes: String) {} + mutating func appendInterpolation(_ boolean: @autoclosure @escaping () -> Bool, format: OSLogBoolFormat = .truth, privacy: OSLogPrivacy = .auto) {} +} + +struct OSLogMessage : ExpressibleByStringInterpolation { + typealias StringInterpolation = OSLogInterpolation + typealias StringLiteralType = String + typealias ExtendedGraphemeClusterLiteralType = String + typealias UnicodeScalarLiteralType = String + init(stringInterpolation: OSLogInterpolation) {} + init(stringLiteral: String) {} + init(extendedGraphemeClusterLiteral: String) {} + init(unicodeScalarLiteral: String) {} +} + +struct Logger { + func log(_ message: OSLogMessage) {} + func log(level: OSLogType, _ message: OSLogMessage) {} + func notice(_: OSLogMessage) {} + func debug(_: OSLogMessage) {} + func trace(_: OSLogMessage) {} + func info(_: OSLogMessage) {} + func error(_: OSLogMessage) {} + func warning(_: OSLogMessage) {} + func fault(_: OSLogMessage) {} + func critical(_: OSLogMessage) {} +} + +class OSLog : NSObject { + static let `default` = OSLog(rawValue: 0) + let rawValue: UInt8 + init(rawValue: UInt8) { self.rawValue = rawValue} +} + +extension String : CVarArg { + public var _cVarArgEncoding: [Int] { get { return [] } } +} + +struct NSExceptionName { + init(_ rawValue: String) {} +} + +class NSException : NSObject +{ + init(name aName: NSExceptionName, reason aReason: String?, userInfo aUserInfo: [AnyHashable : Any]? = nil) {} + class func raise(_ name: NSExceptionName, format: String, arguments argList: CVaListPointer) {} + func raise() {} +} + +class NSString : NSObject { + convenience init(string aString: String) { self.init() } +} + +// from ObjC API; slightly simplified. +func os_log(_ message: StaticString, + dso: UnsafeRawPointer? = nil, + log: OSLog = .default, + type: OSLogType = .default, + _ args: CVarArg...) { } + +// imported from C +typealias FILE = Int32 // this is a simplification +typealias wchar_t = Int32 +typealias locale_t = OpaquePointer +func dprintf(_ fd: Int, _ format: UnsafePointer, _ args: CVarArg...) -> Int32 { return 0 } +func vprintf(_ format: UnsafePointer, _ arg: CVaListPointer) -> Int32 { return 0 } +func vfprintf(_ file: UnsafeMutablePointer?, _ format: UnsafePointer?, _ arg: CVaListPointer) -> Int32 { return 0 } +func vasprintf_l(_ ret: UnsafeMutablePointer?>?, _ loc: locale_t?, _ format: UnsafePointer?, _ ap: CVaListPointer) -> Int32 { return 0 } + +// custom +func log(message: String) {} +func logging(message: String) {} +func logfile(file: Int, message: String) {} +func logMessage(_ msg: NSString) {} +func logInfo(_ infoMsg: String) {} +func logError(errorMsg str: String) {} +func harmless(_ str: String) {} // safe +func logarithm(_ val: Float) -> Float { return 0.0 } // safe +func doLogin(login: String) {} // safe + +// custom +class LogFile { + func log(_ str: String) {} + func trace(_ message: String?) {} + func debug(_ message: String) {} + func info(_ info: NSString) {} + func notice(_ notice: String) {} + func warning(_ warningMessage: String) {} + func error(_ msg: String) {} + func critical(_ criticalMsg: String) {} + func fatal(_ str: String) {} +} + +// custom +class Logic { + func addInt(_ val: Int) {} // safe + func addString(_ str: String) {} // safe +} + +// custom +class MyRemoteLogger { + func setPassword(password: String) { } + func login(password: String) { } + func logout(secret: String) { } +} + +// --- tests --- + +func test1(password: String, passwordHash : String, passphrase: String, pass_phrase: String) { + print(password) // $ Alert[unified/swift/cleartext-logging] + print(password, separator: "") // $ Alert[unified/swift/cleartext-logging] + print("", separator: password) // $ Alert[unified/swift/cleartext-logging] + print(password, separator: "", terminator: "") // $ Alert[unified/swift/cleartext-logging] + print("", separator: password, terminator: "") // $ Alert[unified/swift/cleartext-logging] + print("", separator: "", terminator: password) // $ Alert[unified/swift/cleartext-logging] + print(passwordHash) // safe + + debugPrint(password) // $ MISSING: Alert[unified/swift/cleartext-logging] + + dump(password) // $ MISSING: Alert[unified/swift/cleartext-logging] + + NSLog(password) // $ Alert[unified/swift/cleartext-logging] + NSLog("%@", password) // $ Alert[unified/swift/cleartext-logging] + NSLog("%@ %@", "", password) // $ Alert[unified/swift/cleartext-logging] + NSLog("\(password)") // $ Alert[unified/swift/cleartext-logging] + NSLogv("%@", getVaList([password])) // $ Alert[unified/swift/cleartext-logging] + NSLogv("%@ %@", getVaList(["", password])) // $ Alert[unified/swift/cleartext-logging] + NSLog(passwordHash) // safe + NSLogv("%@", getVaList([passwordHash])) // safe + + let bankAccount: Int = 0 + let log = Logger() + // These MISSING test cases will be fixed when we properly generate the CFG around autoclosures. + log.log("\(password)") // $ SPURIOUS: Alert[unified/swift/cleartext-logging] safe + log.log("\(password, privacy: .auto)") // safe + log.log("\(password, privacy: .private)") // safe + log.log("\(password, privacy: .public)") // $ MISSING: Alert[unified/swift/cleartext-logging] + log.log("\(passwordHash, privacy: .public)") // safe + log.log("\(password, privacy: .sensitive)") // safe + log.log("\(bankAccount)") // $ Alert[unified/swift/cleartext-logging] + log.log("\(bankAccount, privacy: .auto)") // $ MISSING: Alert[unified/swift/cleartext-logging] + log.log("\(bankAccount, privacy: .private)") // safe + log.log("\(bankAccount, privacy: .public)") // $ MISSING: Alert[unified/swift/cleartext-logging] + log.log("\(bankAccount, privacy: .sensitive)") // safe + log.log(level: .default, "\(password, privacy: .public)") // $ MISSING: Alert[unified/swift/cleartext-logging] + log.trace("\(password, privacy: .public)") // $ MISSING: Alert[unified/swift/cleartext-logging] + log.trace("\(passwordHash, privacy: .public)") // safe + log.debug("\(password, privacy: .public)") // $ MISSING: Alert[unified/swift/cleartext-logging] + log.debug("\(passwordHash, privacy: .public)") // safe + log.info("\(password, privacy: .public)") // $ MISSING: Alert[unified/swift/cleartext-logging] + log.info("\(passwordHash, privacy: .public)") // safe + log.notice("\(password, privacy: .public)") // $ MISSING: Alert[unified/swift/cleartext-logging] + log.notice("\(passwordHash, privacy: .public)") // safe + log.warning("\(password, privacy: .public)") // $ MISSING: Alert[unified/swift/cleartext-logging] + log.warning("\(passwordHash, privacy: .public)") // safe + log.error("\(password, privacy: .public)") // $ MISSING: Alert[unified/swift/cleartext-logging] + log.error("\(passwordHash, privacy: .public)") // safe + log.critical("\(password, privacy: .public)") // $ MISSING: Alert[unified/swift/cleartext-logging] + log.critical("\(passwordHash, privacy: .public)") // safe + log.fault("\(password, privacy: .public)") // $ MISSING: Alert[unified/swift/cleartext-logging] + log.fault("\(passwordHash, privacy: .public)") // safe + + NSLog(passphrase) // $ Alert[unified/swift/cleartext-logging] + NSLog(pass_phrase) // $ Alert[unified/swift/cleartext-logging] + + os_log("%@", log: .default, type: .default, "") // safe + os_log("%@", log: .default, type: .default, password) // $ MISSING: Alert[unified/swift/cleartext-logging] + os_log("%@ %@ %@", log: .default, type: .default, "", "", password) // $ MISSING: Alert[unified/swift/cleartext-logging] +} + +class MyClass { + var harmless = "abc" + var password = "123" +} + +func getPassword() -> String { return "" } +func doSomething(password: String) { } + +func test3(x: String) { + // alternative evidence of sensitivity... + + NSLog(x) // $ MISSING: Alert + doSomething(password: x); // $ MISSING: Source[unified/swift/cleartext-logging] + NSLog(x) // $ MISSING: Alert[unified/swift/cleartext-logging] + + let y = getPassword(); // $ MISSING: Source[unified/swift/cleartext-logging] + NSLog(y) // $ MISSING: Alert[unified/swift/cleartext-logging] + + let z = MyClass() + NSLog(z.harmless) // safe + NSLog(z.password) // $ Alert[unified/swift/cleartext-logging] +} + +struct MyOuter { + struct MyInner { + var value: String + } + + var password: MyInner + var harmless: MyInner +} + +func test3(mo : MyOuter) { + // struct members... + + NSLog(mo.password.value) // $ MISSING: Alert[unified/swift/cleartext-logging] + NSLog(mo.harmless.value) // safe +} + +func test4(harmless: String, password: String) { + // functions with an `in:` target for the write... + var myString1 = "" + var myString2 = "" + var myString3 = "" + var myString4 = "" + var myString5 = "" + var myString6 = "" + var myString7 = "" + var myString8 = "" + var myString9 = "" + var myString10 = "" + var myString11 = "" + var myString12 = "" + var myString13 = "" + + print(harmless, to: &myString1) + print(myString1) // safe + + print(password, to: &myString2) // $ MISSING: Source[unified/swift/cleartext-logging] SPURIOUS: Alert[unified/swift/cleartext-logging] + print(myString2) // $ MISSING: Alert[unified/swift/cleartext-logging] + + print("log: " + password, to: &myString3) // $ MISSING: Source[unified/swift/cleartext-logging] SPURIOUS: Alert[unified/swift/cleartext-logging] + print(myString3) // $ MISSING: Alert[unified/swift/cleartext-logging] + + debugPrint(harmless, to: &myString4) + debugPrint(myString4) // safe + + debugPrint(password, to: &myString5) // $ MISSING: Source[unified/swift/cleartext-logging] + debugPrint(myString5) // $ MISSING: Alert[unified/swift/cleartext-logging] + + dump(harmless, to: &myString6) + dump(myString6) // safe + + dump(password, to: &myString7) // $ MISSING: Source[unified/swift/cleartext-logging] + dump(myString7) // $ MISSING: Alert[unified/swift/cleartext-logging] + + myString8.write(harmless) + print(myString8) + + myString9.write(password) // $ Source[unified/swift/cleartext-logging] + print(myString9) // $ Alert[unified/swift/cleartext-logging] + + myString10.write(harmless) + myString10.write(password) // $ Source[unified/swift/cleartext-logging] + myString10.write(harmless) + print(myString10) // $ Alert[unified/swift/cleartext-logging] + + harmless.write(to: &myString11) + print(myString11) + + password.write(to: &myString12) // $ Source[unified/swift/cleartext-logging] + print(myString12) // $ Alert[unified/swift/cleartext-logging] + + print(password, to: &myString13) // $ SPURIOUS: Alert[unified/swift/cleartext-logging] safe - only printed to another string + debugPrint(password, to: &myString13) // safe - only printed to another string + dump(password, to: &myString13) // safe - only printed to another string + myString13.write(password) // safe - only printed to another string + password.write(to: &myString13) // safe - only printed to another string +} + +func test5(password: String, caseNum: Int) { + // `assert` methods... + // (these would only be a danger in certain builds) + + switch caseNum { + case 0: + assert(false, password) // $ MISSING: Alert[unified/swift/cleartext-logging] + case 1: + assertionFailure(password) // $ MISSING: Alert[unified/swift/cleartext-logging] + case 2: + precondition(false, password) // $ MISSING: Alert[unified/swift/cleartext-logging] + case 3: + preconditionFailure(password) // $ MISSING: Alert[unified/swift/cleartext-logging] + default: + fatalError(password) // $ MISSING: Alert[unified/swift/cleartext-logging] + } +} + +func test6(passwordString: String) { + let e = NSException(name: NSExceptionName("exception"), reason: "\(passwordString) is incorrect!", userInfo: nil) // $ MISSING: Alert[unified/swift/cleartext-logging] + e.raise() + + NSException.raise(NSExceptionName("exception"), format: "\(passwordString) is incorrect!", arguments: getVaList([])) // $ MISSING: Alert[unified/swift/cleartext-logging] + NSException.raise(NSExceptionName("exception"), format: "%s is incorrect!", arguments: getVaList([passwordString])) // $ MISSING: Alert[unified/swift/cleartext-logging] + + _ = dprintf(0, "\(passwordString) is incorrect!") // $ MISSING: Alert[unified/swift/cleartext-logging] + _ = dprintf(0, "%s is incorrect!", passwordString) // $ MISSING: Alert[unified/swift/cleartext-logging] + _ = dprintf(0, "%s: %s is incorrect!", "foo", passwordString) // $ MISSING: Alert[unified/swift/cleartext-logging] + _ = vprintf("\(passwordString) is incorrect!", getVaList([])) // $ MISSING: Alert[unified/swift/cleartext-logging] + _ = vprintf("%s is incorrect!", getVaList([passwordString])) // $ MISSING: Alert[unified/swift/cleartext-logging] + _ = vfprintf(nil, "\(passwordString) is incorrect!", getVaList([])) // $ MISSING: Alert[unified/swift/cleartext-logging] + _ = vfprintf(nil, "%s is incorrect!", getVaList([passwordString])) // $ MISSING: Alert[unified/swift/cleartext-logging] + _ = vasprintf_l(nil, nil, "\(passwordString) is incorrect!", getVaList([])) // good (`sprintf` is not logging) + _ = vasprintf_l(nil, nil, "%s is incorrect!", getVaList([passwordString])) // good (`sprintf` is not logging) +} + +func test7(authKey: String, authKey2: Int, authKey3: Float, password: String, secret: String) { + log(message: authKey) // $ Alert[unified/swift/cleartext-logging] + log(message: String(authKey2)) // $ Alert[unified/swift/cleartext-logging] + logging(message: authKey) // $ Alert[unified/swift/cleartext-logging] + logfile(file: 0, message: authKey) // $ Alert[unified/swift/cleartext-logging] + logMessage(NSString(string: authKey)) // $ Alert[unified/swift/cleartext-logging] + logInfo(authKey) // $ Alert[unified/swift/cleartext-logging] + logError(errorMsg: authKey) // $ Alert[unified/swift/cleartext-logging] + harmless(authKey) // GOOD: not logging + _ = logarithm(authKey3) // $ SPURIOUS: Alert[unified/swift/cleartext-logging] GOOD: not logging + doLogin(login: authKey) // GOOD: not logging + + let logger = LogFile() + let msg = "authKey: " + authKey // $ Source[unified/swift/cleartext-logging] + logger.log(msg) // $ Alert[unified/swift/cleartext-logging] + logger.trace(msg) // $ MISSING: Alert[unified/swift/cleartext-logging] + logger.debug(msg) // $ MISSING: Alert[unified/swift/cleartext-logging] + logger.info(NSString(string: msg)) // $ MISSING: Alert[unified/swift/cleartext-logging] + logger.notice(msg) // $ MISSING: Alert[unified/swift/cleartext-logging] + logger.warning(msg) // $ Alert[unified/swift/cleartext-logging] + logger.error(msg) // $ Alert[unified/swift/cleartext-logging] + logger.critical(msg) // $ MISSING: Alert[unified/swift/cleartext-logging] + logger.fatal(msg) // $ MISSING: Alert[unified/swift/cleartext-logging] + + let logic = Logic() + logic.addInt(authKey2) // GOOD: not logging + logic.addString(authKey) // GOOD: not logging + + let rlogger = MyRemoteLogger() + rlogger.setPassword(password: password) // GOOD: not logging + rlogger.login(password: password) // $ SPURIOUS: Alert[unified/swift/cleartext-logging] GOOD: not logging + rlogger.logout(secret: secret) // $ SPURIOUS: Alert[unified/swift/cleartext-logging] GOOD: not logging +} From ce00358c35616e8ee6645bf4669823a043f0a94f Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 13 Nov 2026 13:37:32 +0000 Subject: [PATCH 02/10] Unified: Add test cases for globals, enum values, member functions. --- .../CleartextLogging.expected | 122 +++++++++--------- .../CleartextLoggingTest.swift | 40 ++++++ 2 files changed, 102 insertions(+), 60 deletions(-) diff --git a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected index 75df1da5a60e..5cd889560923 100644 --- a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected +++ b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected @@ -16,26 +16,27 @@ | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | Logging of $@ | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | sensitive data | | CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | Logging of $@ | CleartextLoggingTest.swift:220:11:220:20 | passphrase | sensitive data | | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | Logging of $@ | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | sensitive data | -| CleartextLoggingTest.swift:248:8:248:17 | ... .password | CleartextLoggingTest.swift:248:8:248:17 | ... .password | CleartextLoggingTest.swift:248:8:248:17 | ... .password | Logging of $@ | CleartextLoggingTest.swift:248:8:248:17 | ... .password | sensitive data | -| CleartextLoggingTest.swift:286:8:286:15 | password | CleartextLoggingTest.swift:286:8:286:15 | password | CleartextLoggingTest.swift:286:8:286:15 | password | Logging of $@ | CleartextLoggingTest.swift:286:8:286:15 | password | sensitive data | -| CleartextLoggingTest.swift:289:8:289:25 | ... + ... | CleartextLoggingTest.swift:289:18:289:25 | password | CleartextLoggingTest.swift:289:8:289:25 | ... + ... | Logging of $@ | CleartextLoggingTest.swift:289:18:289:25 | password | sensitive data | -| CleartextLoggingTest.swift:308:8:308:16 | myString9 | CleartextLoggingTest.swift:307:18:307:25 | password | CleartextLoggingTest.swift:308:8:308:16 | myString9 | Logging of $@ | CleartextLoggingTest.swift:307:18:307:25 | password | sensitive data | -| CleartextLoggingTest.swift:313:8:313:17 | myString10 | CleartextLoggingTest.swift:311:19:311:26 | password | CleartextLoggingTest.swift:313:8:313:17 | myString10 | Logging of $@ | CleartextLoggingTest.swift:311:19:311:26 | password | sensitive data | -| CleartextLoggingTest.swift:319:8:319:17 | myString12 | CleartextLoggingTest.swift:318:2:318:9 | password | CleartextLoggingTest.swift:319:8:319:17 | myString12 | Logging of $@ | CleartextLoggingTest.swift:318:2:318:9 | password | sensitive data | -| CleartextLoggingTest.swift:321:8:321:15 | password | CleartextLoggingTest.swift:321:8:321:15 | password | CleartextLoggingTest.swift:321:8:321:15 | password | Logging of $@ | CleartextLoggingTest.swift:321:8:321:15 | password | sensitive data | -| CleartextLoggingTest.swift:365:18:365:24 | authKey | CleartextLoggingTest.swift:365:18:365:24 | authKey | CleartextLoggingTest.swift:365:18:365:24 | authKey | Logging of $@ | CleartextLoggingTest.swift:365:18:365:24 | authKey | sensitive data | -| CleartextLoggingTest.swift:366:18:366:33 | String(...) | CleartextLoggingTest.swift:366:25:366:32 | authKey2 | CleartextLoggingTest.swift:366:18:366:33 | String(...) | Logging of $@ | CleartextLoggingTest.swift:366:25:366:32 | authKey2 | sensitive data | -| CleartextLoggingTest.swift:367:22:367:28 | authKey | CleartextLoggingTest.swift:367:22:367:28 | authKey | CleartextLoggingTest.swift:367:22:367:28 | authKey | Logging of $@ | CleartextLoggingTest.swift:367:22:367:28 | authKey | sensitive data | -| CleartextLoggingTest.swift:368:31:368:37 | authKey | CleartextLoggingTest.swift:368:31:368:37 | authKey | CleartextLoggingTest.swift:368:31:368:37 | authKey | Logging of $@ | CleartextLoggingTest.swift:368:31:368:37 | authKey | sensitive data | -| CleartextLoggingTest.swift:369:16:369:40 | NSString(...) | CleartextLoggingTest.swift:369:33:369:39 | authKey | CleartextLoggingTest.swift:369:16:369:40 | NSString(...) | Logging of $@ | CleartextLoggingTest.swift:369:33:369:39 | authKey | sensitive data | -| CleartextLoggingTest.swift:370:13:370:19 | authKey | CleartextLoggingTest.swift:370:13:370:19 | authKey | CleartextLoggingTest.swift:370:13:370:19 | authKey | Logging of $@ | CleartextLoggingTest.swift:370:13:370:19 | authKey | sensitive data | -| CleartextLoggingTest.swift:371:24:371:30 | authKey | CleartextLoggingTest.swift:371:24:371:30 | authKey | CleartextLoggingTest.swift:371:24:371:30 | authKey | Logging of $@ | CleartextLoggingTest.swift:371:24:371:30 | authKey | sensitive data | -| CleartextLoggingTest.swift:373:19:373:26 | authKey3 | CleartextLoggingTest.swift:373:19:373:26 | authKey3 | CleartextLoggingTest.swift:373:19:373:26 | authKey3 | Logging of $@ | CleartextLoggingTest.swift:373:19:373:26 | authKey3 | sensitive data | -| CleartextLoggingTest.swift:378:16:378:18 | msg | CleartextLoggingTest.swift:377:29:377:35 | authKey | CleartextLoggingTest.swift:378:16:378:18 | msg | Logging of $@ | CleartextLoggingTest.swift:377:29:377:35 | authKey | sensitive data | -| CleartextLoggingTest.swift:383:20:383:22 | msg | CleartextLoggingTest.swift:377:29:377:35 | authKey | CleartextLoggingTest.swift:383:20:383:22 | msg | Logging of $@ | CleartextLoggingTest.swift:377:29:377:35 | authKey | sensitive data | -| CleartextLoggingTest.swift:384:18:384:20 | msg | CleartextLoggingTest.swift:377:29:377:35 | authKey | CleartextLoggingTest.swift:384:18:384:20 | msg | Logging of $@ | CleartextLoggingTest.swift:377:29:377:35 | authKey | sensitive data | -| CleartextLoggingTest.swift:394:29:394:36 | password | CleartextLoggingTest.swift:394:29:394:36 | password | CleartextLoggingTest.swift:394:29:394:36 | password | Logging of $@ | CleartextLoggingTest.swift:394:29:394:36 | password | sensitive data | -| CleartextLoggingTest.swift:395:28:395:33 | secret | CleartextLoggingTest.swift:395:28:395:33 | secret | CleartextLoggingTest.swift:395:28:395:33 | secret | Logging of $@ | CleartextLoggingTest.swift:395:28:395:33 | secret | sensitive data | +| CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | Logging of $@ | CleartextLoggingTest.swift:250:8:250:17 | ... .password | sensitive data | +| CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | Logging of $@ | CleartextLoggingTest.swift:294:8:294:15 | password | sensitive data | +| CleartextLoggingTest.swift:297:8:297:25 | ... + ... | CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | Logging of $@ | CleartextLoggingTest.swift:297:18:297:25 | password | sensitive data | +| CleartextLoggingTest.swift:316:8:316:16 | myString9 | CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:316:8:316:16 | myString9 | Logging of $@ | CleartextLoggingTest.swift:315:18:315:25 | password | sensitive data | +| CleartextLoggingTest.swift:321:8:321:17 | myString10 | CleartextLoggingTest.swift:319:19:319:26 | password | CleartextLoggingTest.swift:321:8:321:17 | myString10 | Logging of $@ | CleartextLoggingTest.swift:319:19:319:26 | password | sensitive data | +| CleartextLoggingTest.swift:327:8:327:17 | myString12 | CleartextLoggingTest.swift:326:2:326:9 | password | CleartextLoggingTest.swift:327:8:327:17 | myString12 | Logging of $@ | CleartextLoggingTest.swift:326:2:326:9 | password | sensitive data | +| CleartextLoggingTest.swift:329:8:329:15 | password | CleartextLoggingTest.swift:329:8:329:15 | password | CleartextLoggingTest.swift:329:8:329:15 | password | Logging of $@ | CleartextLoggingTest.swift:329:8:329:15 | password | sensitive data | +| CleartextLoggingTest.swift:373:18:373:24 | authKey | CleartextLoggingTest.swift:373:18:373:24 | authKey | CleartextLoggingTest.swift:373:18:373:24 | authKey | Logging of $@ | CleartextLoggingTest.swift:373:18:373:24 | authKey | sensitive data | +| CleartextLoggingTest.swift:374:18:374:33 | String(...) | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | CleartextLoggingTest.swift:374:18:374:33 | String(...) | Logging of $@ | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | sensitive data | +| CleartextLoggingTest.swift:375:22:375:28 | authKey | CleartextLoggingTest.swift:375:22:375:28 | authKey | CleartextLoggingTest.swift:375:22:375:28 | authKey | Logging of $@ | CleartextLoggingTest.swift:375:22:375:28 | authKey | sensitive data | +| CleartextLoggingTest.swift:376:31:376:37 | authKey | CleartextLoggingTest.swift:376:31:376:37 | authKey | CleartextLoggingTest.swift:376:31:376:37 | authKey | Logging of $@ | CleartextLoggingTest.swift:376:31:376:37 | authKey | sensitive data | +| CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | CleartextLoggingTest.swift:377:33:377:39 | authKey | CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | Logging of $@ | CleartextLoggingTest.swift:377:33:377:39 | authKey | sensitive data | +| CleartextLoggingTest.swift:378:13:378:19 | authKey | CleartextLoggingTest.swift:378:13:378:19 | authKey | CleartextLoggingTest.swift:378:13:378:19 | authKey | Logging of $@ | CleartextLoggingTest.swift:378:13:378:19 | authKey | sensitive data | +| CleartextLoggingTest.swift:379:24:379:30 | authKey | CleartextLoggingTest.swift:379:24:379:30 | authKey | CleartextLoggingTest.swift:379:24:379:30 | authKey | Logging of $@ | CleartextLoggingTest.swift:379:24:379:30 | authKey | sensitive data | +| CleartextLoggingTest.swift:381:19:381:26 | authKey3 | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | Logging of $@ | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | sensitive data | +| CleartextLoggingTest.swift:386:16:386:18 | msg | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:386:16:386:18 | msg | Logging of $@ | CleartextLoggingTest.swift:385:29:385:35 | authKey | sensitive data | +| CleartextLoggingTest.swift:391:20:391:22 | msg | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:391:20:391:22 | msg | Logging of $@ | CleartextLoggingTest.swift:385:29:385:35 | authKey | sensitive data | +| CleartextLoggingTest.swift:392:18:392:20 | msg | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:392:18:392:20 | msg | Logging of $@ | CleartextLoggingTest.swift:385:29:385:35 | authKey | sensitive data | +| CleartextLoggingTest.swift:402:29:402:36 | password | CleartextLoggingTest.swift:402:29:402:36 | password | CleartextLoggingTest.swift:402:29:402:36 | password | Logging of $@ | CleartextLoggingTest.swift:402:29:402:36 | password | sensitive data | +| CleartextLoggingTest.swift:403:28:403:33 | secret | CleartextLoggingTest.swift:403:28:403:33 | secret | CleartextLoggingTest.swift:403:28:403:33 | secret | Logging of $@ | CleartextLoggingTest.swift:403:28:403:33 | secret | sensitive data | +| CleartextLoggingTest.swift:411:11:411:24 | globalPassword | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | Logging of $@ | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | sensitive data | edges | CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | provenance | | | CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | provenance | | @@ -45,17 +46,17 @@ edges | CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:31:184:44 | ArrayLiteral [ArrayElement] | provenance | | | CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | provenance | | | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | provenance | | -| CleartextLoggingTest.swift:289:18:289:25 | password | CleartextLoggingTest.swift:289:8:289:25 | ... + ... | provenance | | -| CleartextLoggingTest.swift:307:18:307:25 | password | CleartextLoggingTest.swift:308:8:308:16 | myString9 | provenance | | -| CleartextLoggingTest.swift:311:19:311:26 | password | CleartextLoggingTest.swift:313:8:313:17 | myString10 | provenance | | -| CleartextLoggingTest.swift:318:2:318:9 | password | CleartextLoggingTest.swift:318:21:318:31 | [post] & ... | provenance | | -| CleartextLoggingTest.swift:318:21:318:31 | [post] & ... | CleartextLoggingTest.swift:319:8:319:17 | myString12 | provenance | | -| CleartextLoggingTest.swift:366:25:366:32 | authKey2 | CleartextLoggingTest.swift:366:18:366:33 | String(...) | provenance | | -| CleartextLoggingTest.swift:369:33:369:39 | authKey | CleartextLoggingTest.swift:369:16:369:40 | NSString(...) | provenance | | -| CleartextLoggingTest.swift:377:9:377:11 | msg | CleartextLoggingTest.swift:378:16:378:18 | msg | provenance | | -| CleartextLoggingTest.swift:377:9:377:11 | msg | CleartextLoggingTest.swift:383:20:383:22 | msg | provenance | | -| CleartextLoggingTest.swift:377:9:377:11 | msg | CleartextLoggingTest.swift:384:18:384:20 | msg | provenance | | -| CleartextLoggingTest.swift:377:29:377:35 | authKey | CleartextLoggingTest.swift:377:9:377:11 | msg | provenance | | +| CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | provenance | | +| CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:316:8:316:16 | myString9 | provenance | | +| CleartextLoggingTest.swift:319:19:319:26 | password | CleartextLoggingTest.swift:321:8:321:17 | myString10 | provenance | | +| CleartextLoggingTest.swift:326:2:326:9 | password | CleartextLoggingTest.swift:326:21:326:31 | [post] & ... | provenance | | +| CleartextLoggingTest.swift:326:21:326:31 | [post] & ... | CleartextLoggingTest.swift:327:8:327:17 | myString12 | provenance | | +| CleartextLoggingTest.swift:374:25:374:32 | authKey2 | CleartextLoggingTest.swift:374:18:374:33 | String(...) | provenance | | +| CleartextLoggingTest.swift:377:33:377:39 | authKey | CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | provenance | | +| CleartextLoggingTest.swift:385:9:385:11 | msg | CleartextLoggingTest.swift:386:16:386:18 | msg | provenance | | +| CleartextLoggingTest.swift:385:9:385:11 | msg | CleartextLoggingTest.swift:391:20:391:22 | msg | provenance | | +| CleartextLoggingTest.swift:385:9:385:11 | msg | CleartextLoggingTest.swift:392:18:392:20 | msg | provenance | | +| CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:385:9:385:11 | msg | provenance | | nodes | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | semmle.label | StringInterpolationExpr | | CleartextLoggingBad.swift:2:35:2:42 | password | semmle.label | password | @@ -82,33 +83,34 @@ nodes | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | semmle.label | bankAccount | | CleartextLoggingTest.swift:220:11:220:20 | passphrase | semmle.label | passphrase | | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | semmle.label | pass_phrase | -| CleartextLoggingTest.swift:248:8:248:17 | ... .password | semmle.label | ... .password | -| CleartextLoggingTest.swift:286:8:286:15 | password | semmle.label | password | -| CleartextLoggingTest.swift:289:8:289:25 | ... + ... | semmle.label | ... + ... | -| CleartextLoggingTest.swift:289:18:289:25 | password | semmle.label | password | -| CleartextLoggingTest.swift:307:18:307:25 | password | semmle.label | password | -| CleartextLoggingTest.swift:308:8:308:16 | myString9 | semmle.label | myString9 | -| CleartextLoggingTest.swift:311:19:311:26 | password | semmle.label | password | -| CleartextLoggingTest.swift:313:8:313:17 | myString10 | semmle.label | myString10 | -| CleartextLoggingTest.swift:318:2:318:9 | password | semmle.label | password | -| CleartextLoggingTest.swift:318:21:318:31 | [post] & ... | semmle.label | [post] & ... | -| CleartextLoggingTest.swift:319:8:319:17 | myString12 | semmle.label | myString12 | -| CleartextLoggingTest.swift:321:8:321:15 | password | semmle.label | password | -| CleartextLoggingTest.swift:365:18:365:24 | authKey | semmle.label | authKey | -| CleartextLoggingTest.swift:366:18:366:33 | String(...) | semmle.label | String(...) | -| CleartextLoggingTest.swift:366:25:366:32 | authKey2 | semmle.label | authKey2 | -| CleartextLoggingTest.swift:367:22:367:28 | authKey | semmle.label | authKey | -| CleartextLoggingTest.swift:368:31:368:37 | authKey | semmle.label | authKey | -| CleartextLoggingTest.swift:369:16:369:40 | NSString(...) | semmle.label | NSString(...) | -| CleartextLoggingTest.swift:369:33:369:39 | authKey | semmle.label | authKey | -| CleartextLoggingTest.swift:370:13:370:19 | authKey | semmle.label | authKey | -| CleartextLoggingTest.swift:371:24:371:30 | authKey | semmle.label | authKey | -| CleartextLoggingTest.swift:373:19:373:26 | authKey3 | semmle.label | authKey3 | -| CleartextLoggingTest.swift:377:9:377:11 | msg | semmle.label | msg | -| CleartextLoggingTest.swift:377:29:377:35 | authKey | semmle.label | authKey | -| CleartextLoggingTest.swift:378:16:378:18 | msg | semmle.label | msg | -| CleartextLoggingTest.swift:383:20:383:22 | msg | semmle.label | msg | -| CleartextLoggingTest.swift:384:18:384:20 | msg | semmle.label | msg | -| CleartextLoggingTest.swift:394:29:394:36 | password | semmle.label | password | -| CleartextLoggingTest.swift:395:28:395:33 | secret | semmle.label | secret | +| CleartextLoggingTest.swift:250:8:250:17 | ... .password | semmle.label | ... .password | +| CleartextLoggingTest.swift:294:8:294:15 | password | semmle.label | password | +| CleartextLoggingTest.swift:297:8:297:25 | ... + ... | semmle.label | ... + ... | +| CleartextLoggingTest.swift:297:18:297:25 | password | semmle.label | password | +| CleartextLoggingTest.swift:315:18:315:25 | password | semmle.label | password | +| CleartextLoggingTest.swift:316:8:316:16 | myString9 | semmle.label | myString9 | +| CleartextLoggingTest.swift:319:19:319:26 | password | semmle.label | password | +| CleartextLoggingTest.swift:321:8:321:17 | myString10 | semmle.label | myString10 | +| CleartextLoggingTest.swift:326:2:326:9 | password | semmle.label | password | +| CleartextLoggingTest.swift:326:21:326:31 | [post] & ... | semmle.label | [post] & ... | +| CleartextLoggingTest.swift:327:8:327:17 | myString12 | semmle.label | myString12 | +| CleartextLoggingTest.swift:329:8:329:15 | password | semmle.label | password | +| CleartextLoggingTest.swift:373:18:373:24 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:374:18:374:33 | String(...) | semmle.label | String(...) | +| CleartextLoggingTest.swift:374:25:374:32 | authKey2 | semmle.label | authKey2 | +| CleartextLoggingTest.swift:375:22:375:28 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:376:31:376:37 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | semmle.label | NSString(...) | +| CleartextLoggingTest.swift:377:33:377:39 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:378:13:378:19 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:379:24:379:30 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:381:19:381:26 | authKey3 | semmle.label | authKey3 | +| CleartextLoggingTest.swift:385:9:385:11 | msg | semmle.label | msg | +| CleartextLoggingTest.swift:385:29:385:35 | authKey | semmle.label | authKey | +| CleartextLoggingTest.swift:386:16:386:18 | msg | semmle.label | msg | +| CleartextLoggingTest.swift:391:20:391:22 | msg | semmle.label | msg | +| CleartextLoggingTest.swift:392:18:392:20 | msg | semmle.label | msg | +| CleartextLoggingTest.swift:402:29:402:36 | password | semmle.label | password | +| CleartextLoggingTest.swift:403:28:403:33 | secret | semmle.label | secret | +| CleartextLoggingTest.swift:411:11:411:24 | globalPassword | semmle.label | globalPassword | subpaths diff --git a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift index f4bb1ba71ad2..8b2e5c92d52d 100644 --- a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift +++ b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift @@ -228,6 +228,8 @@ func test1(password: String, passwordHash : String, passphrase: String, pass_phr class MyClass { var harmless = "abc" var password = "123" + + func getPassword() -> String { return "" } } func getPassword() -> String { return "" } @@ -246,11 +248,14 @@ func test3(x: String) { let z = MyClass() NSLog(z.harmless) // safe NSLog(z.password) // $ Alert[unified/swift/cleartext-logging] + NSLog(z.getPassword()) // $ MISSING: Alert[unified/swift/cleartext-logging] } struct MyOuter { struct MyInner { var value: String + + func getValue() -> String { return "" } } var password: MyInner @@ -262,6 +267,9 @@ func test3(mo : MyOuter) { NSLog(mo.password.value) // $ MISSING: Alert[unified/swift/cleartext-logging] NSLog(mo.harmless.value) // safe + + NSLog(mo.password.getValue()) // $ MISSING: Alert[unified/swift/cleartext-logging] + NSLog(mo.harmless.getValue()) // safe } func test4(harmless: String, password: String) { @@ -394,3 +402,35 @@ func test7(authKey: String, authKey2: Int, authKey3: Float, password: String, se rlogger.login(password: password) // $ SPURIOUS: Alert[unified/swift/cleartext-logging] GOOD: not logging rlogger.logout(secret: secret) // $ SPURIOUS: Alert[unified/swift/cleartext-logging] GOOD: not logging } + +let globalMessage = "example" +let globalPassword = "example" + +func testGlobals(a: Password, b: Info) { + print(globalMessage) // safe + print(globalPassword) // $ Alert[unified/swift/cleartext-logging] +} + +enum Password { + case value(String) +} + +enum Info { + case password(String) + case message(String) +} + +func testEnums(p: Password, i: Info) { + // print the value from the Password enum + if case .value(let contents) = p { + print(contents) // $ MISSING: Alert[unified/swift/cleartext-logging] + } + + // print the values from the Info enum + switch i { + case .password(let contents): + print(contents) // $ MISSING: Alert[unified/swift/cleartext-logging] + case .message(let contents): + print(contents) // safe + } +} From ed3b1a9b04051885048314df40a0a29047b31c9e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 13 Nov 2026 10:59:16 +0000 Subject: [PATCH 03/10] Unified: Clean up unified/swift/cleartext-logging a little. --- .../queries/security/CWE-312/CleartextLogging.ql | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql b/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql index 4aa751a1e91a..ef38439ab6c1 100644 --- a/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql +++ b/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql @@ -25,7 +25,10 @@ private string getNameFromExpr(Expr e) { result = e.(MemberAccessExpr).getMemberName() } -module DummyConfig implements DataFlow::ConfigSig { +/** + * A taint-tracking configuration for cleartext logging vulnerabilities. + */ +module CleartextLoggingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { exists(string name | name = getNameFromExpr(node.asExpr()) and @@ -43,10 +46,10 @@ module DummyConfig implements DataFlow::ConfigSig { predicate isBarrierIn(DataFlow::Node node) { isSource(node) } } -module DummyFlow = TaintTracking::Global; +module CleartextLoggingFlow = TaintTracking::Global; -import DummyFlow::PathGraph +import CleartextLoggingFlow::PathGraph -from DummyFlow::PathNode source, DummyFlow::PathNode sink -where DummyFlow::flowPath(source, sink) +from CleartextLoggingFlow::PathNode source, CleartextLoggingFlow::PathNode sink +where CleartextLoggingFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Logging of $@", source.getNode(), "sensitive data" From 33817d1e58528b0f040aa9ac142a1c1624376210 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 13 Nov 2026 11:20:08 +0000 Subject: [PATCH 04/10] Unified: Add Swift-specific sensitive data library layer. --- .../codeql/unified/security/SensitiveData.qll | 52 +++++++++++++++++++ .../security/CWE-312/CleartextLogging.ql | 7 +-- 2 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 unified/ql/lib/codeql/unified/security/SensitiveData.qll diff --git a/unified/ql/lib/codeql/unified/security/SensitiveData.qll b/unified/ql/lib/codeql/unified/security/SensitiveData.qll new file mode 100644 index 000000000000..40a5a8080ca2 --- /dev/null +++ b/unified/ql/lib/codeql/unified/security/SensitiveData.qll @@ -0,0 +1,52 @@ +/** + * Provides classes and predicates for identifying sensitive data. + * + * 'Sensitive' data is anything that should not be sent in unencrypted form. This library tries to + * guess where sensitive data may either be stored in a variable or produced by a method. + */ + +import unified +import codeql.concepts.internal.SensitiveDataHeuristics +private import codeql.unified.internal.typeinference.TypeInference as TypeInference + +/** + * A data flow node that might contain sensitive data. + */ +cached +abstract class SensitiveData extends DataFlow::Node { + /** + * Gets the classification of sensitive data this expression might contain. + */ + cached + abstract SensitiveDataClassification getClassification(); +} + +/** + * An identifier that might contain sensitive data. + */ +private class SensitiveDataIdentifier extends SensitiveData { + SensitiveDataClassification classification; + + SensitiveDataIdentifier() { + exists(IdentifierExpr e | e = this.asExpr() | + HeuristicNames::nameIndicatesSensitiveData(e.getValue(), classification) + ) + } + + override SensitiveDataClassification getClassification() { result = classification } +} + +/** + * A member access that might contain sensitive data. + */ +private class SensitiveDataMemberAccess extends SensitiveData { + SensitiveDataClassification classification; + + SensitiveDataMemberAccess() { + exists(MemberAccessExpr e | e = this.asExpr() | + HeuristicNames::nameIndicatesSensitiveData(e.getMemberName(), classification) + ) + } + + override SensitiveDataClassification getClassification() { result = classification } +} diff --git a/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql b/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql index ef38439ab6c1..e96f8d769cdd 100644 --- a/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql +++ b/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql @@ -17,7 +17,7 @@ // FIXME: This is a deliberately dumb and noisy version of the query used to exercise data flow early on. // import unified -import codeql.concepts.internal.SensitiveDataHeuristics +import codeql.unified.security.SensitiveData private string getNameFromExpr(Expr e) { result = e.(IdentifierExpr).getValue() @@ -30,10 +30,7 @@ private string getNameFromExpr(Expr e) { */ module CleartextLoggingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { - exists(string name | - name = getNameFromExpr(node.asExpr()) and - HeuristicNames::nameIndicatesSensitiveData(name) - ) + node instanceof SensitiveData } predicate isSink(DataFlow::Node node) { From e676316922a6a8eee38f41a5a5a6538dbf07ca41 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 13 Nov 2026 14:42:28 +0000 Subject: [PATCH 05/10] Unified: Use the standard alert message for this query. --- .../security/CWE-312/CleartextLogging.ql | 3 +- .../CleartextLogging.expected | 76 +++++++++---------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql b/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql index e96f8d769cdd..6c837a82372e 100644 --- a/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql +++ b/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql @@ -49,4 +49,5 @@ import CleartextLoggingFlow::PathGraph from CleartextLoggingFlow::PathNode source, CleartextLoggingFlow::PathNode sink where CleartextLoggingFlow::flowPath(source, sink) -select sink.getNode(), source, sink, "Logging of $@", source.getNode(), "sensitive data" +select sink.getNode(), source, sink, "This operation writes $@ to a log file.", source, + source.getNode().toString() diff --git a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected index 5cd889560923..953bfd72db8a 100644 --- a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected +++ b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected @@ -1,42 +1,42 @@ #select -| CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | Logging of $@ | CleartextLoggingBad.swift:2:35:2:42 | password | sensitive data | -| CleartextLoggingTest.swift:167:11:167:18 | password | CleartextLoggingTest.swift:167:11:167:18 | password | CleartextLoggingTest.swift:167:11:167:18 | password | Logging of $@ | CleartextLoggingTest.swift:167:11:167:18 | password | sensitive data | -| CleartextLoggingTest.swift:168:11:168:18 | password | CleartextLoggingTest.swift:168:11:168:18 | password | CleartextLoggingTest.swift:168:11:168:18 | password | Logging of $@ | CleartextLoggingTest.swift:168:11:168:18 | password | sensitive data | -| CleartextLoggingTest.swift:169:26:169:33 | password | CleartextLoggingTest.swift:169:26:169:33 | password | CleartextLoggingTest.swift:169:26:169:33 | password | Logging of $@ | CleartextLoggingTest.swift:169:26:169:33 | password | sensitive data | -| CleartextLoggingTest.swift:170:11:170:18 | password | CleartextLoggingTest.swift:170:11:170:18 | password | CleartextLoggingTest.swift:170:11:170:18 | password | Logging of $@ | CleartextLoggingTest.swift:170:11:170:18 | password | sensitive data | -| CleartextLoggingTest.swift:171:26:171:33 | password | CleartextLoggingTest.swift:171:26:171:33 | password | CleartextLoggingTest.swift:171:26:171:33 | password | Logging of $@ | CleartextLoggingTest.swift:171:26:171:33 | password | sensitive data | -| CleartextLoggingTest.swift:172:42:172:49 | password | CleartextLoggingTest.swift:172:42:172:49 | password | CleartextLoggingTest.swift:172:42:172:49 | password | Logging of $@ | CleartextLoggingTest.swift:172:42:172:49 | password | sensitive data | -| CleartextLoggingTest.swift:179:11:179:18 | password | CleartextLoggingTest.swift:179:11:179:18 | password | CleartextLoggingTest.swift:179:11:179:18 | password | Logging of $@ | CleartextLoggingTest.swift:179:11:179:18 | password | sensitive data | -| CleartextLoggingTest.swift:180:17:180:24 | password | CleartextLoggingTest.swift:180:17:180:24 | password | CleartextLoggingTest.swift:180:17:180:24 | password | Logging of $@ | CleartextLoggingTest.swift:180:17:180:24 | password | sensitive data | -| CleartextLoggingTest.swift:181:24:181:31 | password | CleartextLoggingTest.swift:181:24:181:31 | password | CleartextLoggingTest.swift:181:24:181:31 | password | Logging of $@ | CleartextLoggingTest.swift:181:24:181:31 | password | sensitive data | -| CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | Logging of $@ | CleartextLoggingTest.swift:182:14:182:21 | password | sensitive data | -| CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | CleartextLoggingTest.swift:183:29:183:36 | password | CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | Logging of $@ | CleartextLoggingTest.swift:183:29:183:36 | password | sensitive data | -| CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | Logging of $@ | CleartextLoggingTest.swift:184:36:184:43 | password | sensitive data | -| CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | Logging of $@ | CleartextLoggingTest.swift:191:16:191:23 | password | sensitive data | -| CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | Logging of $@ | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | sensitive data | -| CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | Logging of $@ | CleartextLoggingTest.swift:220:11:220:20 | passphrase | sensitive data | -| CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | Logging of $@ | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | sensitive data | -| CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | Logging of $@ | CleartextLoggingTest.swift:250:8:250:17 | ... .password | sensitive data | -| CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | Logging of $@ | CleartextLoggingTest.swift:294:8:294:15 | password | sensitive data | -| CleartextLoggingTest.swift:297:8:297:25 | ... + ... | CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | Logging of $@ | CleartextLoggingTest.swift:297:18:297:25 | password | sensitive data | -| CleartextLoggingTest.swift:316:8:316:16 | myString9 | CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:316:8:316:16 | myString9 | Logging of $@ | CleartextLoggingTest.swift:315:18:315:25 | password | sensitive data | -| CleartextLoggingTest.swift:321:8:321:17 | myString10 | CleartextLoggingTest.swift:319:19:319:26 | password | CleartextLoggingTest.swift:321:8:321:17 | myString10 | Logging of $@ | CleartextLoggingTest.swift:319:19:319:26 | password | sensitive data | -| CleartextLoggingTest.swift:327:8:327:17 | myString12 | CleartextLoggingTest.swift:326:2:326:9 | password | CleartextLoggingTest.swift:327:8:327:17 | myString12 | Logging of $@ | CleartextLoggingTest.swift:326:2:326:9 | password | sensitive data | -| CleartextLoggingTest.swift:329:8:329:15 | password | CleartextLoggingTest.swift:329:8:329:15 | password | CleartextLoggingTest.swift:329:8:329:15 | password | Logging of $@ | CleartextLoggingTest.swift:329:8:329:15 | password | sensitive data | -| CleartextLoggingTest.swift:373:18:373:24 | authKey | CleartextLoggingTest.swift:373:18:373:24 | authKey | CleartextLoggingTest.swift:373:18:373:24 | authKey | Logging of $@ | CleartextLoggingTest.swift:373:18:373:24 | authKey | sensitive data | -| CleartextLoggingTest.swift:374:18:374:33 | String(...) | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | CleartextLoggingTest.swift:374:18:374:33 | String(...) | Logging of $@ | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | sensitive data | -| CleartextLoggingTest.swift:375:22:375:28 | authKey | CleartextLoggingTest.swift:375:22:375:28 | authKey | CleartextLoggingTest.swift:375:22:375:28 | authKey | Logging of $@ | CleartextLoggingTest.swift:375:22:375:28 | authKey | sensitive data | -| CleartextLoggingTest.swift:376:31:376:37 | authKey | CleartextLoggingTest.swift:376:31:376:37 | authKey | CleartextLoggingTest.swift:376:31:376:37 | authKey | Logging of $@ | CleartextLoggingTest.swift:376:31:376:37 | authKey | sensitive data | -| CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | CleartextLoggingTest.swift:377:33:377:39 | authKey | CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | Logging of $@ | CleartextLoggingTest.swift:377:33:377:39 | authKey | sensitive data | -| CleartextLoggingTest.swift:378:13:378:19 | authKey | CleartextLoggingTest.swift:378:13:378:19 | authKey | CleartextLoggingTest.swift:378:13:378:19 | authKey | Logging of $@ | CleartextLoggingTest.swift:378:13:378:19 | authKey | sensitive data | -| CleartextLoggingTest.swift:379:24:379:30 | authKey | CleartextLoggingTest.swift:379:24:379:30 | authKey | CleartextLoggingTest.swift:379:24:379:30 | authKey | Logging of $@ | CleartextLoggingTest.swift:379:24:379:30 | authKey | sensitive data | -| CleartextLoggingTest.swift:381:19:381:26 | authKey3 | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | Logging of $@ | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | sensitive data | -| CleartextLoggingTest.swift:386:16:386:18 | msg | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:386:16:386:18 | msg | Logging of $@ | CleartextLoggingTest.swift:385:29:385:35 | authKey | sensitive data | -| CleartextLoggingTest.swift:391:20:391:22 | msg | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:391:20:391:22 | msg | Logging of $@ | CleartextLoggingTest.swift:385:29:385:35 | authKey | sensitive data | -| CleartextLoggingTest.swift:392:18:392:20 | msg | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:392:18:392:20 | msg | Logging of $@ | CleartextLoggingTest.swift:385:29:385:35 | authKey | sensitive data | -| CleartextLoggingTest.swift:402:29:402:36 | password | CleartextLoggingTest.swift:402:29:402:36 | password | CleartextLoggingTest.swift:402:29:402:36 | password | Logging of $@ | CleartextLoggingTest.swift:402:29:402:36 | password | sensitive data | -| CleartextLoggingTest.swift:403:28:403:33 | secret | CleartextLoggingTest.swift:403:28:403:33 | secret | CleartextLoggingTest.swift:403:28:403:33 | secret | Logging of $@ | CleartextLoggingTest.swift:403:28:403:33 | secret | sensitive data | -| CleartextLoggingTest.swift:411:11:411:24 | globalPassword | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | Logging of $@ | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | sensitive data | +| CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingBad.swift:2:35:2:42 | password | password | +| CleartextLoggingTest.swift:167:11:167:18 | password | CleartextLoggingTest.swift:167:11:167:18 | password | CleartextLoggingTest.swift:167:11:167:18 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:167:11:167:18 | password | password | +| CleartextLoggingTest.swift:168:11:168:18 | password | CleartextLoggingTest.swift:168:11:168:18 | password | CleartextLoggingTest.swift:168:11:168:18 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:168:11:168:18 | password | password | +| CleartextLoggingTest.swift:169:26:169:33 | password | CleartextLoggingTest.swift:169:26:169:33 | password | CleartextLoggingTest.swift:169:26:169:33 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:169:26:169:33 | password | password | +| CleartextLoggingTest.swift:170:11:170:18 | password | CleartextLoggingTest.swift:170:11:170:18 | password | CleartextLoggingTest.swift:170:11:170:18 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:170:11:170:18 | password | password | +| CleartextLoggingTest.swift:171:26:171:33 | password | CleartextLoggingTest.swift:171:26:171:33 | password | CleartextLoggingTest.swift:171:26:171:33 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:171:26:171:33 | password | password | +| CleartextLoggingTest.swift:172:42:172:49 | password | CleartextLoggingTest.swift:172:42:172:49 | password | CleartextLoggingTest.swift:172:42:172:49 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:172:42:172:49 | password | password | +| CleartextLoggingTest.swift:179:11:179:18 | password | CleartextLoggingTest.swift:179:11:179:18 | password | CleartextLoggingTest.swift:179:11:179:18 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:179:11:179:18 | password | password | +| CleartextLoggingTest.swift:180:17:180:24 | password | CleartextLoggingTest.swift:180:17:180:24 | password | CleartextLoggingTest.swift:180:17:180:24 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:180:17:180:24 | password | password | +| CleartextLoggingTest.swift:181:24:181:31 | password | CleartextLoggingTest.swift:181:24:181:31 | password | CleartextLoggingTest.swift:181:24:181:31 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:181:24:181:31 | password | password | +| CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:182:14:182:21 | password | password | +| CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | CleartextLoggingTest.swift:183:29:183:36 | password | CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:183:29:183:36 | password | password | +| CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:184:36:184:43 | password | password | +| CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:191:16:191:23 | password | password | +| CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | bankAccount | +| CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | This operation writes $@ to a log file. | CleartextLoggingTest.swift:220:11:220:20 | passphrase | passphrase | +| CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | This operation writes $@ to a log file. | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | pass_phrase | +| CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:250:8:250:17 | ... .password | ... .password | +| CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:294:8:294:15 | password | password | +| CleartextLoggingTest.swift:297:8:297:25 | ... + ... | CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | This operation writes $@ to a log file. | CleartextLoggingTest.swift:297:18:297:25 | password | password | +| CleartextLoggingTest.swift:316:8:316:16 | myString9 | CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:316:8:316:16 | myString9 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:315:18:315:25 | password | password | +| CleartextLoggingTest.swift:321:8:321:17 | myString10 | CleartextLoggingTest.swift:319:19:319:26 | password | CleartextLoggingTest.swift:321:8:321:17 | myString10 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:319:19:319:26 | password | password | +| CleartextLoggingTest.swift:327:8:327:17 | myString12 | CleartextLoggingTest.swift:326:2:326:9 | password | CleartextLoggingTest.swift:327:8:327:17 | myString12 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:326:2:326:9 | password | password | +| CleartextLoggingTest.swift:329:8:329:15 | password | CleartextLoggingTest.swift:329:8:329:15 | password | CleartextLoggingTest.swift:329:8:329:15 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:329:8:329:15 | password | password | +| CleartextLoggingTest.swift:373:18:373:24 | authKey | CleartextLoggingTest.swift:373:18:373:24 | authKey | CleartextLoggingTest.swift:373:18:373:24 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:373:18:373:24 | authKey | authKey | +| CleartextLoggingTest.swift:374:18:374:33 | String(...) | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | CleartextLoggingTest.swift:374:18:374:33 | String(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | authKey2 | +| CleartextLoggingTest.swift:375:22:375:28 | authKey | CleartextLoggingTest.swift:375:22:375:28 | authKey | CleartextLoggingTest.swift:375:22:375:28 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:375:22:375:28 | authKey | authKey | +| CleartextLoggingTest.swift:376:31:376:37 | authKey | CleartextLoggingTest.swift:376:31:376:37 | authKey | CleartextLoggingTest.swift:376:31:376:37 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:376:31:376:37 | authKey | authKey | +| CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | CleartextLoggingTest.swift:377:33:377:39 | authKey | CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:377:33:377:39 | authKey | authKey | +| CleartextLoggingTest.swift:378:13:378:19 | authKey | CleartextLoggingTest.swift:378:13:378:19 | authKey | CleartextLoggingTest.swift:378:13:378:19 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:378:13:378:19 | authKey | authKey | +| CleartextLoggingTest.swift:379:24:379:30 | authKey | CleartextLoggingTest.swift:379:24:379:30 | authKey | CleartextLoggingTest.swift:379:24:379:30 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:379:24:379:30 | authKey | authKey | +| CleartextLoggingTest.swift:381:19:381:26 | authKey3 | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | authKey3 | +| CleartextLoggingTest.swift:386:16:386:18 | msg | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:386:16:386:18 | msg | This operation writes $@ to a log file. | CleartextLoggingTest.swift:385:29:385:35 | authKey | authKey | +| CleartextLoggingTest.swift:391:20:391:22 | msg | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:391:20:391:22 | msg | This operation writes $@ to a log file. | CleartextLoggingTest.swift:385:29:385:35 | authKey | authKey | +| CleartextLoggingTest.swift:392:18:392:20 | msg | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:392:18:392:20 | msg | This operation writes $@ to a log file. | CleartextLoggingTest.swift:385:29:385:35 | authKey | authKey | +| CleartextLoggingTest.swift:402:29:402:36 | password | CleartextLoggingTest.swift:402:29:402:36 | password | CleartextLoggingTest.swift:402:29:402:36 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:402:29:402:36 | password | password | +| CleartextLoggingTest.swift:403:28:403:33 | secret | CleartextLoggingTest.swift:403:28:403:33 | secret | CleartextLoggingTest.swift:403:28:403:33 | secret | This operation writes $@ to a log file. | CleartextLoggingTest.swift:403:28:403:33 | secret | secret | +| CleartextLoggingTest.swift:411:11:411:24 | globalPassword | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | This operation writes $@ to a log file. | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | globalPassword | edges | CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | provenance | | | CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | provenance | | From c9dfbee2b2e6eea84c152bbb87030afbf1811d5a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 13 Nov 2026 14:50:54 +0000 Subject: [PATCH 06/10] Unified: Add function call targets as potential sensitive data sources. --- .../codeql/unified/security/SensitiveData.qll | 17 +++++++++++++++++ .../CleartextLogging/CleartextLogging.expected | 8 ++++++++ .../CleartextLogging/CleartextLoggingTest.swift | 6 +++--- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/unified/ql/lib/codeql/unified/security/SensitiveData.qll b/unified/ql/lib/codeql/unified/security/SensitiveData.qll index 40a5a8080ca2..3209e74b7a24 100644 --- a/unified/ql/lib/codeql/unified/security/SensitiveData.qll +++ b/unified/ql/lib/codeql/unified/security/SensitiveData.qll @@ -50,3 +50,20 @@ private class SensitiveDataMemberAccess extends SensitiveData { override SensitiveDataClassification getClassification() { result = classification } } + +/** + * A function call that might produce sensitive data. + */ +private class SensitiveDataCall extends SensitiveData { + SensitiveDataClassification classification; + + SensitiveDataCall() { + exists(CallExpr call, string name | + call = this.asExpr() and + name = TypeInference::resolveCallTarget(call).(Member).getNameNode().getValue() and + HeuristicNames::nameIndicatesSensitiveData(name, classification) + ) + } + + override SensitiveDataClassification getClassification() { result = classification } +} diff --git a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected index 953bfd72db8a..c6bc7729ff5e 100644 --- a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected +++ b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected @@ -16,7 +16,9 @@ | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | bankAccount | | CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | This operation writes $@ to a log file. | CleartextLoggingTest.swift:220:11:220:20 | passphrase | passphrase | | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | This operation writes $@ to a log file. | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | pass_phrase | +| CleartextLoggingTest.swift:246:8:246:8 | y | CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | CleartextLoggingTest.swift:246:8:246:8 | y | This operation writes $@ to a log file. | CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | getPassword(...) | | CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:250:8:250:17 | ... .password | ... .password | +| CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | ... .getPassword(...) | | CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:294:8:294:15 | password | password | | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | This operation writes $@ to a log file. | CleartextLoggingTest.swift:297:18:297:25 | password | password | | CleartextLoggingTest.swift:316:8:316:16 | myString9 | CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:316:8:316:16 | myString9 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:315:18:315:25 | password | password | @@ -46,6 +48,8 @@ edges | CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:31:184:44 | ArrayLiteral [ArrayElement] | provenance | | | CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | provenance | | | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | provenance | | +| CleartextLoggingTest.swift:245:6:245:6 | y | CleartextLoggingTest.swift:246:8:246:8 | y | provenance | | +| CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | CleartextLoggingTest.swift:245:6:245:6 | y | provenance | | | CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | provenance | | | CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:316:8:316:16 | myString9 | provenance | | | CleartextLoggingTest.swift:319:19:319:26 | password | CleartextLoggingTest.swift:321:8:321:17 | myString10 | provenance | | @@ -83,7 +87,11 @@ nodes | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | semmle.label | bankAccount | | CleartextLoggingTest.swift:220:11:220:20 | passphrase | semmle.label | passphrase | | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | semmle.label | pass_phrase | +| CleartextLoggingTest.swift:245:6:245:6 | y | semmle.label | y | +| CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | semmle.label | getPassword(...) | +| CleartextLoggingTest.swift:246:8:246:8 | y | semmle.label | y | | CleartextLoggingTest.swift:250:8:250:17 | ... .password | semmle.label | ... .password | +| CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | semmle.label | ... .getPassword(...) | | CleartextLoggingTest.swift:294:8:294:15 | password | semmle.label | password | | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | semmle.label | ... + ... | | CleartextLoggingTest.swift:297:18:297:25 | password | semmle.label | password | diff --git a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift index 8b2e5c92d52d..f9fa38c2c6e6 100644 --- a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift +++ b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift @@ -242,13 +242,13 @@ func test3(x: String) { doSomething(password: x); // $ MISSING: Source[unified/swift/cleartext-logging] NSLog(x) // $ MISSING: Alert[unified/swift/cleartext-logging] - let y = getPassword(); // $ MISSING: Source[unified/swift/cleartext-logging] - NSLog(y) // $ MISSING: Alert[unified/swift/cleartext-logging] + let y = getPassword(); // $ Source[unified/swift/cleartext-logging] + NSLog(y) // $ Alert[unified/swift/cleartext-logging] let z = MyClass() NSLog(z.harmless) // safe NSLog(z.password) // $ Alert[unified/swift/cleartext-logging] - NSLog(z.getPassword()) // $ MISSING: Alert[unified/swift/cleartext-logging] + NSLog(z.getPassword()) // $ Alert[unified/swift/cleartext-logging] } struct MyOuter { From 941120a1f2fbb6642d1af7f6653ea48f9e30578f Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 13 Nov 2026 15:04:59 +0000 Subject: [PATCH 07/10] Unified: Add full receiver chains as potential sensitive data. --- .../ql/lib/codeql/unified/security/SensitiveData.qll | 12 ++++++++++-- .../CleartextLogging/CleartextLogging.expected | 4 ++++ .../CleartextLogging/CleartextLoggingTest.swift | 4 ++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/unified/ql/lib/codeql/unified/security/SensitiveData.qll b/unified/ql/lib/codeql/unified/security/SensitiveData.qll index 3209e74b7a24..553488c00704 100644 --- a/unified/ql/lib/codeql/unified/security/SensitiveData.qll +++ b/unified/ql/lib/codeql/unified/security/SensitiveData.qll @@ -36,14 +36,22 @@ private class SensitiveDataIdentifier extends SensitiveData { override SensitiveDataClassification getClassification() { result = classification } } +private Expr memberAccessParent(MemberAccessExpr e) { result = e.getParent() } + /** - * A member access that might contain sensitive data. + * A member access that might contain sensitive data. This includes a member itself and + * components of a receiver chain, for example: + * ``` + * object.password + * password.value + * password.getValue() + * ``` */ private class SensitiveDataMemberAccess extends SensitiveData { SensitiveDataClassification classification; SensitiveDataMemberAccess() { - exists(MemberAccessExpr e | e = this.asExpr() | + exists(MemberAccessExpr e | memberAccessParent*(e) = this.asExpr() | HeuristicNames::nameIndicatesSensitiveData(e.getMemberName(), classification) ) } diff --git a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected index c6bc7729ff5e..59a04077284a 100644 --- a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected +++ b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected @@ -19,6 +19,8 @@ | CleartextLoggingTest.swift:246:8:246:8 | y | CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | CleartextLoggingTest.swift:246:8:246:8 | y | This operation writes $@ to a log file. | CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | getPassword(...) | | CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:250:8:250:17 | ... .password | ... .password | | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | ... .getPassword(...) | +| CleartextLoggingTest.swift:268:8:268:24 | ... .value | CleartextLoggingTest.swift:268:8:268:24 | ... .value | CleartextLoggingTest.swift:268:8:268:24 | ... .value | This operation writes $@ to a log file. | CleartextLoggingTest.swift:268:8:268:24 | ... .value | ... .value | +| CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | ... .getValue(...) | | CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:294:8:294:15 | password | password | | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | This operation writes $@ to a log file. | CleartextLoggingTest.swift:297:18:297:25 | password | password | | CleartextLoggingTest.swift:316:8:316:16 | myString9 | CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:316:8:316:16 | myString9 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:315:18:315:25 | password | password | @@ -92,6 +94,8 @@ nodes | CleartextLoggingTest.swift:246:8:246:8 | y | semmle.label | y | | CleartextLoggingTest.swift:250:8:250:17 | ... .password | semmle.label | ... .password | | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | semmle.label | ... .getPassword(...) | +| CleartextLoggingTest.swift:268:8:268:24 | ... .value | semmle.label | ... .value | +| CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | semmle.label | ... .getValue(...) | | CleartextLoggingTest.swift:294:8:294:15 | password | semmle.label | password | | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | semmle.label | ... + ... | | CleartextLoggingTest.swift:297:18:297:25 | password | semmle.label | password | diff --git a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift index f9fa38c2c6e6..344205f1516e 100644 --- a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift +++ b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift @@ -265,10 +265,10 @@ struct MyOuter { func test3(mo : MyOuter) { // struct members... - NSLog(mo.password.value) // $ MISSING: Alert[unified/swift/cleartext-logging] + NSLog(mo.password.value) // $ Alert[unified/swift/cleartext-logging] NSLog(mo.harmless.value) // safe - NSLog(mo.password.getValue()) // $ MISSING: Alert[unified/swift/cleartext-logging] + NSLog(mo.password.getValue()) // $ Alert[unified/swift/cleartext-logging] NSLog(mo.harmless.getValue()) // safe } From 8ad7588fb9e06517b3f8c7491a44c48cccf6dd5d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 13 Nov 2026 17:42:19 +0000 Subject: [PATCH 08/10] Unified: Swap alert location from the sink to the source (as requested, to reduce noise). --- .../security/CWE-312/CleartextLogging.ql | 2 +- .../CleartextLogging.expected | 32 ++++++++--------- .../CleartextLoggingTest.swift | 36 +++++++++---------- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql b/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql index 6c837a82372e..c37af43f4062 100644 --- a/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql +++ b/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql @@ -49,5 +49,5 @@ import CleartextLoggingFlow::PathGraph from CleartextLoggingFlow::PathNode source, CleartextLoggingFlow::PathNode sink where CleartextLoggingFlow::flowPath(source, sink) -select sink.getNode(), source, sink, "This operation writes $@ to a log file.", source, +select source.getNode(), source, sink, "This operation writes $@ to a log file.", source, source.getNode().toString() diff --git a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected index 59a04077284a..da1be3fad3b3 100644 --- a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected +++ b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected @@ -1,5 +1,5 @@ #select -| CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingBad.swift:2:35:2:42 | password | password | +| CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingBad.swift:2:35:2:42 | password | password | | CleartextLoggingTest.swift:167:11:167:18 | password | CleartextLoggingTest.swift:167:11:167:18 | password | CleartextLoggingTest.swift:167:11:167:18 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:167:11:167:18 | password | password | | CleartextLoggingTest.swift:168:11:168:18 | password | CleartextLoggingTest.swift:168:11:168:18 | password | CleartextLoggingTest.swift:168:11:168:18 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:168:11:168:18 | password | password | | CleartextLoggingTest.swift:169:26:169:33 | password | CleartextLoggingTest.swift:169:26:169:33 | password | CleartextLoggingTest.swift:169:26:169:33 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:169:26:169:33 | password | password | @@ -9,35 +9,35 @@ | CleartextLoggingTest.swift:179:11:179:18 | password | CleartextLoggingTest.swift:179:11:179:18 | password | CleartextLoggingTest.swift:179:11:179:18 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:179:11:179:18 | password | password | | CleartextLoggingTest.swift:180:17:180:24 | password | CleartextLoggingTest.swift:180:17:180:24 | password | CleartextLoggingTest.swift:180:17:180:24 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:180:17:180:24 | password | password | | CleartextLoggingTest.swift:181:24:181:31 | password | CleartextLoggingTest.swift:181:24:181:31 | password | CleartextLoggingTest.swift:181:24:181:31 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:181:24:181:31 | password | password | -| CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:182:14:182:21 | password | password | -| CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | CleartextLoggingTest.swift:183:29:183:36 | password | CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:183:29:183:36 | password | password | -| CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:184:36:184:43 | password | password | -| CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:191:16:191:23 | password | password | -| CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | bankAccount | +| CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:182:14:182:21 | password | password | +| CleartextLoggingTest.swift:183:29:183:36 | password | CleartextLoggingTest.swift:183:29:183:36 | password | CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:183:29:183:36 | password | password | +| CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:184:36:184:43 | password | password | +| CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:191:16:191:23 | password | password | +| CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | bankAccount | | CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | This operation writes $@ to a log file. | CleartextLoggingTest.swift:220:11:220:20 | passphrase | passphrase | | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | This operation writes $@ to a log file. | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | pass_phrase | -| CleartextLoggingTest.swift:246:8:246:8 | y | CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | CleartextLoggingTest.swift:246:8:246:8 | y | This operation writes $@ to a log file. | CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | getPassword(...) | +| CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | CleartextLoggingTest.swift:246:8:246:8 | y | This operation writes $@ to a log file. | CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | getPassword(...) | | CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:250:8:250:17 | ... .password | ... .password | | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | ... .getPassword(...) | | CleartextLoggingTest.swift:268:8:268:24 | ... .value | CleartextLoggingTest.swift:268:8:268:24 | ... .value | CleartextLoggingTest.swift:268:8:268:24 | ... .value | This operation writes $@ to a log file. | CleartextLoggingTest.swift:268:8:268:24 | ... .value | ... .value | | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | ... .getValue(...) | | CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:294:8:294:15 | password | password | -| CleartextLoggingTest.swift:297:8:297:25 | ... + ... | CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | This operation writes $@ to a log file. | CleartextLoggingTest.swift:297:18:297:25 | password | password | -| CleartextLoggingTest.swift:316:8:316:16 | myString9 | CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:316:8:316:16 | myString9 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:315:18:315:25 | password | password | -| CleartextLoggingTest.swift:321:8:321:17 | myString10 | CleartextLoggingTest.swift:319:19:319:26 | password | CleartextLoggingTest.swift:321:8:321:17 | myString10 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:319:19:319:26 | password | password | -| CleartextLoggingTest.swift:327:8:327:17 | myString12 | CleartextLoggingTest.swift:326:2:326:9 | password | CleartextLoggingTest.swift:327:8:327:17 | myString12 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:326:2:326:9 | password | password | +| CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | This operation writes $@ to a log file. | CleartextLoggingTest.swift:297:18:297:25 | password | password | +| CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:316:8:316:16 | myString9 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:315:18:315:25 | password | password | +| CleartextLoggingTest.swift:319:19:319:26 | password | CleartextLoggingTest.swift:319:19:319:26 | password | CleartextLoggingTest.swift:321:8:321:17 | myString10 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:319:19:319:26 | password | password | +| CleartextLoggingTest.swift:326:2:326:9 | password | CleartextLoggingTest.swift:326:2:326:9 | password | CleartextLoggingTest.swift:327:8:327:17 | myString12 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:326:2:326:9 | password | password | | CleartextLoggingTest.swift:329:8:329:15 | password | CleartextLoggingTest.swift:329:8:329:15 | password | CleartextLoggingTest.swift:329:8:329:15 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:329:8:329:15 | password | password | | CleartextLoggingTest.swift:373:18:373:24 | authKey | CleartextLoggingTest.swift:373:18:373:24 | authKey | CleartextLoggingTest.swift:373:18:373:24 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:373:18:373:24 | authKey | authKey | -| CleartextLoggingTest.swift:374:18:374:33 | String(...) | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | CleartextLoggingTest.swift:374:18:374:33 | String(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | authKey2 | +| CleartextLoggingTest.swift:374:25:374:32 | authKey2 | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | CleartextLoggingTest.swift:374:18:374:33 | String(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | authKey2 | | CleartextLoggingTest.swift:375:22:375:28 | authKey | CleartextLoggingTest.swift:375:22:375:28 | authKey | CleartextLoggingTest.swift:375:22:375:28 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:375:22:375:28 | authKey | authKey | | CleartextLoggingTest.swift:376:31:376:37 | authKey | CleartextLoggingTest.swift:376:31:376:37 | authKey | CleartextLoggingTest.swift:376:31:376:37 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:376:31:376:37 | authKey | authKey | -| CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | CleartextLoggingTest.swift:377:33:377:39 | authKey | CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:377:33:377:39 | authKey | authKey | +| CleartextLoggingTest.swift:377:33:377:39 | authKey | CleartextLoggingTest.swift:377:33:377:39 | authKey | CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:377:33:377:39 | authKey | authKey | | CleartextLoggingTest.swift:378:13:378:19 | authKey | CleartextLoggingTest.swift:378:13:378:19 | authKey | CleartextLoggingTest.swift:378:13:378:19 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:378:13:378:19 | authKey | authKey | | CleartextLoggingTest.swift:379:24:379:30 | authKey | CleartextLoggingTest.swift:379:24:379:30 | authKey | CleartextLoggingTest.swift:379:24:379:30 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:379:24:379:30 | authKey | authKey | | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | authKey3 | -| CleartextLoggingTest.swift:386:16:386:18 | msg | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:386:16:386:18 | msg | This operation writes $@ to a log file. | CleartextLoggingTest.swift:385:29:385:35 | authKey | authKey | -| CleartextLoggingTest.swift:391:20:391:22 | msg | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:391:20:391:22 | msg | This operation writes $@ to a log file. | CleartextLoggingTest.swift:385:29:385:35 | authKey | authKey | -| CleartextLoggingTest.swift:392:18:392:20 | msg | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:392:18:392:20 | msg | This operation writes $@ to a log file. | CleartextLoggingTest.swift:385:29:385:35 | authKey | authKey | +| CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:386:16:386:18 | msg | This operation writes $@ to a log file. | CleartextLoggingTest.swift:385:29:385:35 | authKey | authKey | +| CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:391:20:391:22 | msg | This operation writes $@ to a log file. | CleartextLoggingTest.swift:385:29:385:35 | authKey | authKey | +| CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:392:18:392:20 | msg | This operation writes $@ to a log file. | CleartextLoggingTest.swift:385:29:385:35 | authKey | authKey | | CleartextLoggingTest.swift:402:29:402:36 | password | CleartextLoggingTest.swift:402:29:402:36 | password | CleartextLoggingTest.swift:402:29:402:36 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:402:29:402:36 | password | password | | CleartextLoggingTest.swift:403:28:403:33 | secret | CleartextLoggingTest.swift:403:28:403:33 | secret | CleartextLoggingTest.swift:403:28:403:33 | secret | This operation writes $@ to a log file. | CleartextLoggingTest.swift:403:28:403:33 | secret | secret | | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | This operation writes $@ to a log file. | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | globalPassword | diff --git a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift index 344205f1516e..38c20943ea1a 100644 --- a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift +++ b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLoggingTest.swift @@ -242,8 +242,8 @@ func test3(x: String) { doSomething(password: x); // $ MISSING: Source[unified/swift/cleartext-logging] NSLog(x) // $ MISSING: Alert[unified/swift/cleartext-logging] - let y = getPassword(); // $ Source[unified/swift/cleartext-logging] - NSLog(y) // $ Alert[unified/swift/cleartext-logging] + let y = getPassword(); // $ Alert[unified/swift/cleartext-logging] + NSLog(y) // $ Sink[unified/swift/cleartext-logging] let z = MyClass() NSLog(z.harmless) // safe @@ -312,19 +312,19 @@ func test4(harmless: String, password: String) { myString8.write(harmless) print(myString8) - myString9.write(password) // $ Source[unified/swift/cleartext-logging] - print(myString9) // $ Alert[unified/swift/cleartext-logging] + myString9.write(password) // $ Alert[unified/swift/cleartext-logging] + print(myString9) // $ Sink[unified/swift/cleartext-logging] myString10.write(harmless) - myString10.write(password) // $ Source[unified/swift/cleartext-logging] + myString10.write(password) // $ Alert[unified/swift/cleartext-logging] myString10.write(harmless) - print(myString10) // $ Alert[unified/swift/cleartext-logging] + print(myString10) // $ Sink[unified/swift/cleartext-logging] harmless.write(to: &myString11) print(myString11) - password.write(to: &myString12) // $ Source[unified/swift/cleartext-logging] - print(myString12) // $ Alert[unified/swift/cleartext-logging] + password.write(to: &myString12) // $ Alert[unified/swift/cleartext-logging] + print(myString12) // $ Sink[unified/swift/cleartext-logging] print(password, to: &myString13) // $ SPURIOUS: Alert[unified/swift/cleartext-logging] safe - only printed to another string debugPrint(password, to: &myString13) // safe - only printed to another string @@ -382,16 +382,16 @@ func test7(authKey: String, authKey2: Int, authKey3: Float, password: String, se doLogin(login: authKey) // GOOD: not logging let logger = LogFile() - let msg = "authKey: " + authKey // $ Source[unified/swift/cleartext-logging] - logger.log(msg) // $ Alert[unified/swift/cleartext-logging] - logger.trace(msg) // $ MISSING: Alert[unified/swift/cleartext-logging] - logger.debug(msg) // $ MISSING: Alert[unified/swift/cleartext-logging] - logger.info(NSString(string: msg)) // $ MISSING: Alert[unified/swift/cleartext-logging] - logger.notice(msg) // $ MISSING: Alert[unified/swift/cleartext-logging] - logger.warning(msg) // $ Alert[unified/swift/cleartext-logging] - logger.error(msg) // $ Alert[unified/swift/cleartext-logging] - logger.critical(msg) // $ MISSING: Alert[unified/swift/cleartext-logging] - logger.fatal(msg) // $ MISSING: Alert[unified/swift/cleartext-logging] + let msg = "authKey: " + authKey // $ Alert[unified/swift/cleartext-logging] + logger.log(msg) // $ Sink[unified/swift/cleartext-logging] + logger.trace(msg) // $ MISSING: Sink[unified/swift/cleartext-logging] + logger.debug(msg) // $ MISSING: Sink[unified/swift/cleartext-logging] + logger.info(NSString(string: msg)) // $ MISSING: Sink[unified/swift/cleartext-logging] + logger.notice(msg) // $ MISSING: Sink[unified/swift/cleartext-logging] + logger.warning(msg) // $ Sink[unified/swift/cleartext-logging] + logger.error(msg) // $ Sink[unified/swift/cleartext-logging] + logger.critical(msg) // $ MISSING: Sink[unified/swift/cleartext-logging] + logger.fatal(msg) // $ MISSING: Sink[unified/swift/cleartext-logging] let logic = Logic() logic.addInt(authKey2) // GOOD: not logging From 87ee517d3ff967eec166d16939c5b64e51af4872 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 13 Nov 2026 17:54:45 +0000 Subject: [PATCH 09/10] Unified: Update the alert message now that the source is the alert location. --- .../security/CWE-312/CleartextLogging.ql | 9 +- .../CleartextLogging.expected | 84 +++++++++---------- 2 files changed, 46 insertions(+), 47 deletions(-) diff --git a/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql b/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql index c37af43f4062..93486da06d97 100644 --- a/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql +++ b/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql @@ -29,9 +29,7 @@ private string getNameFromExpr(Expr e) { * A taint-tracking configuration for cleartext logging vulnerabilities. */ module CleartextLoggingConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node node) { - node instanceof SensitiveData - } + predicate isSource(DataFlow::Node node) { node instanceof SensitiveData } predicate isSink(DataFlow::Node node) { exists(CallExpr call | @@ -49,5 +47,6 @@ import CleartextLoggingFlow::PathGraph from CleartextLoggingFlow::PathNode source, CleartextLoggingFlow::PathNode sink where CleartextLoggingFlow::flowPath(source, sink) -select source.getNode(), source, sink, "This operation writes $@ to a log file.", source, - source.getNode().toString() +select source.getNode(), source, sink, + "This sensitive information is to $@ to a log file.", sink, + "written" diff --git a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected index da1be3fad3b3..bce43bade02b 100644 --- a/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected +++ b/unified/ql/test/query-tests/security/CWE-312/CleartextLogging/CleartextLogging.expected @@ -1,46 +1,46 @@ #select -| CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingBad.swift:2:35:2:42 | password | password | -| CleartextLoggingTest.swift:167:11:167:18 | password | CleartextLoggingTest.swift:167:11:167:18 | password | CleartextLoggingTest.swift:167:11:167:18 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:167:11:167:18 | password | password | -| CleartextLoggingTest.swift:168:11:168:18 | password | CleartextLoggingTest.swift:168:11:168:18 | password | CleartextLoggingTest.swift:168:11:168:18 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:168:11:168:18 | password | password | -| CleartextLoggingTest.swift:169:26:169:33 | password | CleartextLoggingTest.swift:169:26:169:33 | password | CleartextLoggingTest.swift:169:26:169:33 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:169:26:169:33 | password | password | -| CleartextLoggingTest.swift:170:11:170:18 | password | CleartextLoggingTest.swift:170:11:170:18 | password | CleartextLoggingTest.swift:170:11:170:18 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:170:11:170:18 | password | password | -| CleartextLoggingTest.swift:171:26:171:33 | password | CleartextLoggingTest.swift:171:26:171:33 | password | CleartextLoggingTest.swift:171:26:171:33 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:171:26:171:33 | password | password | -| CleartextLoggingTest.swift:172:42:172:49 | password | CleartextLoggingTest.swift:172:42:172:49 | password | CleartextLoggingTest.swift:172:42:172:49 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:172:42:172:49 | password | password | -| CleartextLoggingTest.swift:179:11:179:18 | password | CleartextLoggingTest.swift:179:11:179:18 | password | CleartextLoggingTest.swift:179:11:179:18 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:179:11:179:18 | password | password | -| CleartextLoggingTest.swift:180:17:180:24 | password | CleartextLoggingTest.swift:180:17:180:24 | password | CleartextLoggingTest.swift:180:17:180:24 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:180:17:180:24 | password | password | -| CleartextLoggingTest.swift:181:24:181:31 | password | CleartextLoggingTest.swift:181:24:181:31 | password | CleartextLoggingTest.swift:181:24:181:31 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:181:24:181:31 | password | password | -| CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:182:14:182:21 | password | password | -| CleartextLoggingTest.swift:183:29:183:36 | password | CleartextLoggingTest.swift:183:29:183:36 | password | CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:183:29:183:36 | password | password | -| CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:184:36:184:43 | password | password | -| CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:191:16:191:23 | password | password | -| CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | This operation writes $@ to a log file. | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | bankAccount | -| CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | This operation writes $@ to a log file. | CleartextLoggingTest.swift:220:11:220:20 | passphrase | passphrase | -| CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | This operation writes $@ to a log file. | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | pass_phrase | -| CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | CleartextLoggingTest.swift:246:8:246:8 | y | This operation writes $@ to a log file. | CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | getPassword(...) | -| CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:250:8:250:17 | ... .password | ... .password | -| CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | ... .getPassword(...) | -| CleartextLoggingTest.swift:268:8:268:24 | ... .value | CleartextLoggingTest.swift:268:8:268:24 | ... .value | CleartextLoggingTest.swift:268:8:268:24 | ... .value | This operation writes $@ to a log file. | CleartextLoggingTest.swift:268:8:268:24 | ... .value | ... .value | -| CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | ... .getValue(...) | -| CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:294:8:294:15 | password | password | -| CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | This operation writes $@ to a log file. | CleartextLoggingTest.swift:297:18:297:25 | password | password | -| CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:316:8:316:16 | myString9 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:315:18:315:25 | password | password | -| CleartextLoggingTest.swift:319:19:319:26 | password | CleartextLoggingTest.swift:319:19:319:26 | password | CleartextLoggingTest.swift:321:8:321:17 | myString10 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:319:19:319:26 | password | password | -| CleartextLoggingTest.swift:326:2:326:9 | password | CleartextLoggingTest.swift:326:2:326:9 | password | CleartextLoggingTest.swift:327:8:327:17 | myString12 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:326:2:326:9 | password | password | -| CleartextLoggingTest.swift:329:8:329:15 | password | CleartextLoggingTest.swift:329:8:329:15 | password | CleartextLoggingTest.swift:329:8:329:15 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:329:8:329:15 | password | password | -| CleartextLoggingTest.swift:373:18:373:24 | authKey | CleartextLoggingTest.swift:373:18:373:24 | authKey | CleartextLoggingTest.swift:373:18:373:24 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:373:18:373:24 | authKey | authKey | -| CleartextLoggingTest.swift:374:25:374:32 | authKey2 | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | CleartextLoggingTest.swift:374:18:374:33 | String(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | authKey2 | -| CleartextLoggingTest.swift:375:22:375:28 | authKey | CleartextLoggingTest.swift:375:22:375:28 | authKey | CleartextLoggingTest.swift:375:22:375:28 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:375:22:375:28 | authKey | authKey | -| CleartextLoggingTest.swift:376:31:376:37 | authKey | CleartextLoggingTest.swift:376:31:376:37 | authKey | CleartextLoggingTest.swift:376:31:376:37 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:376:31:376:37 | authKey | authKey | -| CleartextLoggingTest.swift:377:33:377:39 | authKey | CleartextLoggingTest.swift:377:33:377:39 | authKey | CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | This operation writes $@ to a log file. | CleartextLoggingTest.swift:377:33:377:39 | authKey | authKey | -| CleartextLoggingTest.swift:378:13:378:19 | authKey | CleartextLoggingTest.swift:378:13:378:19 | authKey | CleartextLoggingTest.swift:378:13:378:19 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:378:13:378:19 | authKey | authKey | -| CleartextLoggingTest.swift:379:24:379:30 | authKey | CleartextLoggingTest.swift:379:24:379:30 | authKey | CleartextLoggingTest.swift:379:24:379:30 | authKey | This operation writes $@ to a log file. | CleartextLoggingTest.swift:379:24:379:30 | authKey | authKey | -| CleartextLoggingTest.swift:381:19:381:26 | authKey3 | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | This operation writes $@ to a log file. | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | authKey3 | -| CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:386:16:386:18 | msg | This operation writes $@ to a log file. | CleartextLoggingTest.swift:385:29:385:35 | authKey | authKey | -| CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:391:20:391:22 | msg | This operation writes $@ to a log file. | CleartextLoggingTest.swift:385:29:385:35 | authKey | authKey | -| CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:392:18:392:20 | msg | This operation writes $@ to a log file. | CleartextLoggingTest.swift:385:29:385:35 | authKey | authKey | -| CleartextLoggingTest.swift:402:29:402:36 | password | CleartextLoggingTest.swift:402:29:402:36 | password | CleartextLoggingTest.swift:402:29:402:36 | password | This operation writes $@ to a log file. | CleartextLoggingTest.swift:402:29:402:36 | password | password | -| CleartextLoggingTest.swift:403:28:403:33 | secret | CleartextLoggingTest.swift:403:28:403:33 | secret | CleartextLoggingTest.swift:403:28:403:33 | secret | This operation writes $@ to a log file. | CleartextLoggingTest.swift:403:28:403:33 | secret | secret | -| CleartextLoggingTest.swift:411:11:411:24 | globalPassword | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | This operation writes $@ to a log file. | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | globalPassword | +| CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | This sensitive information is to $@ to a log file. | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | written | +| CleartextLoggingTest.swift:167:11:167:18 | password | CleartextLoggingTest.swift:167:11:167:18 | password | CleartextLoggingTest.swift:167:11:167:18 | password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:167:11:167:18 | password | written | +| CleartextLoggingTest.swift:168:11:168:18 | password | CleartextLoggingTest.swift:168:11:168:18 | password | CleartextLoggingTest.swift:168:11:168:18 | password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:168:11:168:18 | password | written | +| CleartextLoggingTest.swift:169:26:169:33 | password | CleartextLoggingTest.swift:169:26:169:33 | password | CleartextLoggingTest.swift:169:26:169:33 | password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:169:26:169:33 | password | written | +| CleartextLoggingTest.swift:170:11:170:18 | password | CleartextLoggingTest.swift:170:11:170:18 | password | CleartextLoggingTest.swift:170:11:170:18 | password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:170:11:170:18 | password | written | +| CleartextLoggingTest.swift:171:26:171:33 | password | CleartextLoggingTest.swift:171:26:171:33 | password | CleartextLoggingTest.swift:171:26:171:33 | password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:171:26:171:33 | password | written | +| CleartextLoggingTest.swift:172:42:172:49 | password | CleartextLoggingTest.swift:172:42:172:49 | password | CleartextLoggingTest.swift:172:42:172:49 | password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:172:42:172:49 | password | written | +| CleartextLoggingTest.swift:179:11:179:18 | password | CleartextLoggingTest.swift:179:11:179:18 | password | CleartextLoggingTest.swift:179:11:179:18 | password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:179:11:179:18 | password | written | +| CleartextLoggingTest.swift:180:17:180:24 | password | CleartextLoggingTest.swift:180:17:180:24 | password | CleartextLoggingTest.swift:180:17:180:24 | password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:180:17:180:24 | password | written | +| CleartextLoggingTest.swift:181:24:181:31 | password | CleartextLoggingTest.swift:181:24:181:31 | password | CleartextLoggingTest.swift:181:24:181:31 | password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:181:24:181:31 | password | written | +| CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | written | +| CleartextLoggingTest.swift:183:29:183:36 | password | CleartextLoggingTest.swift:183:29:183:36 | password | CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:183:18:183:38 | getVaList(...) | written | +| CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:36:184:43 | password | CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:184:21:184:45 | getVaList(...) | written | +| CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:16:191:23 | password | CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:191:13:191:25 | StringInterpolationExpr | written | +| CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:16:197:26 | bankAccount | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:197:13:197:28 | StringInterpolationExpr | written | +| CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | CleartextLoggingTest.swift:220:11:220:20 | passphrase | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:220:11:220:20 | passphrase | written | +| CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:221:11:221:21 | pass_phrase | written | +| CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | CleartextLoggingTest.swift:245:10:245:22 | getPassword(...) | CleartextLoggingTest.swift:246:8:246:8 | y | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:246:8:246:8 | y | written | +| CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | CleartextLoggingTest.swift:250:8:250:17 | ... .password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:250:8:250:17 | ... .password | written | +| CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:251:8:251:22 | ... .getPassword(...) | written | +| CleartextLoggingTest.swift:268:8:268:24 | ... .value | CleartextLoggingTest.swift:268:8:268:24 | ... .value | CleartextLoggingTest.swift:268:8:268:24 | ... .value | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:268:8:268:24 | ... .value | written | +| CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:271:8:271:29 | ... .getValue(...) | written | +| CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | CleartextLoggingTest.swift:294:8:294:15 | password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:294:8:294:15 | password | written | +| CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:18:297:25 | password | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:297:8:297:25 | ... + ... | written | +| CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:315:18:315:25 | password | CleartextLoggingTest.swift:316:8:316:16 | myString9 | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:316:8:316:16 | myString9 | written | +| CleartextLoggingTest.swift:319:19:319:26 | password | CleartextLoggingTest.swift:319:19:319:26 | password | CleartextLoggingTest.swift:321:8:321:17 | myString10 | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:321:8:321:17 | myString10 | written | +| CleartextLoggingTest.swift:326:2:326:9 | password | CleartextLoggingTest.swift:326:2:326:9 | password | CleartextLoggingTest.swift:327:8:327:17 | myString12 | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:327:8:327:17 | myString12 | written | +| CleartextLoggingTest.swift:329:8:329:15 | password | CleartextLoggingTest.swift:329:8:329:15 | password | CleartextLoggingTest.swift:329:8:329:15 | password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:329:8:329:15 | password | written | +| CleartextLoggingTest.swift:373:18:373:24 | authKey | CleartextLoggingTest.swift:373:18:373:24 | authKey | CleartextLoggingTest.swift:373:18:373:24 | authKey | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:373:18:373:24 | authKey | written | +| CleartextLoggingTest.swift:374:25:374:32 | authKey2 | CleartextLoggingTest.swift:374:25:374:32 | authKey2 | CleartextLoggingTest.swift:374:18:374:33 | String(...) | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:374:18:374:33 | String(...) | written | +| CleartextLoggingTest.swift:375:22:375:28 | authKey | CleartextLoggingTest.swift:375:22:375:28 | authKey | CleartextLoggingTest.swift:375:22:375:28 | authKey | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:375:22:375:28 | authKey | written | +| CleartextLoggingTest.swift:376:31:376:37 | authKey | CleartextLoggingTest.swift:376:31:376:37 | authKey | CleartextLoggingTest.swift:376:31:376:37 | authKey | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:376:31:376:37 | authKey | written | +| CleartextLoggingTest.swift:377:33:377:39 | authKey | CleartextLoggingTest.swift:377:33:377:39 | authKey | CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:377:16:377:40 | NSString(...) | written | +| CleartextLoggingTest.swift:378:13:378:19 | authKey | CleartextLoggingTest.swift:378:13:378:19 | authKey | CleartextLoggingTest.swift:378:13:378:19 | authKey | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:378:13:378:19 | authKey | written | +| CleartextLoggingTest.swift:379:24:379:30 | authKey | CleartextLoggingTest.swift:379:24:379:30 | authKey | CleartextLoggingTest.swift:379:24:379:30 | authKey | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:379:24:379:30 | authKey | written | +| CleartextLoggingTest.swift:381:19:381:26 | authKey3 | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:381:19:381:26 | authKey3 | written | +| CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:386:16:386:18 | msg | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:386:16:386:18 | msg | written | +| CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:391:20:391:22 | msg | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:391:20:391:22 | msg | written | +| CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:385:29:385:35 | authKey | CleartextLoggingTest.swift:392:18:392:20 | msg | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:392:18:392:20 | msg | written | +| CleartextLoggingTest.swift:402:29:402:36 | password | CleartextLoggingTest.swift:402:29:402:36 | password | CleartextLoggingTest.swift:402:29:402:36 | password | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:402:29:402:36 | password | written | +| CleartextLoggingTest.swift:403:28:403:33 | secret | CleartextLoggingTest.swift:403:28:403:33 | secret | CleartextLoggingTest.swift:403:28:403:33 | secret | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:403:28:403:33 | secret | written | +| CleartextLoggingTest.swift:411:11:411:24 | globalPassword | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | This sensitive information is to $@ to a log file. | CleartextLoggingTest.swift:411:11:411:24 | globalPassword | written | edges | CleartextLoggingBad.swift:2:35:2:42 | password | CleartextLoggingBad.swift:2:7:2:44 | StringInterpolationExpr | provenance | | | CleartextLoggingTest.swift:182:14:182:21 | password | CleartextLoggingTest.swift:182:11:182:23 | StringInterpolationExpr | provenance | | From 7a33cb8895ee58d6cd4153a41035642223a990db Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 13 Nov 2026 18:36:10 +0000 Subject: [PATCH 10/10] Unified: Autoformat. --- unified/ql/src/queries/security/CWE-312/CleartextLogging.ql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql b/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql index 93486da06d97..7f72eb6ed7e0 100644 --- a/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql +++ b/unified/ql/src/queries/security/CWE-312/CleartextLogging.ql @@ -47,6 +47,5 @@ import CleartextLoggingFlow::PathGraph from CleartextLoggingFlow::PathNode source, CleartextLoggingFlow::PathNode sink where CleartextLoggingFlow::flowPath(source, sink) -select source.getNode(), source, sink, - "This sensitive information is to $@ to a log file.", sink, +select source.getNode(), source, sink, "This sensitive information is to $@ to a log file.", sink, "written"