Skip to content

Unified: Add Uncontrolled format string query - #22985

Open
geoffw0 wants to merge 10 commits into
github:mainfrom
geoffw0:unifiedformat
Open

geoffw0 wants to merge 10 commits into
github:mainfrom
geoffw0:unifiedformat

Conversation

@geoffw0

@geoffw0 geoffw0 commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Adds a unified/swift/uncontrolled-format-string query for unified Swift. Created with the usual Copilot skill + some manual fixup + TODOs to follow-up on later.

Does quite well on tests, though there are certainly missing cases.

DCA to follow. DCA LGTM.

geoffw0 and others added 10 commits November 2, 2026 10:43
Establish a byte-for-byte original Swift baseline for the unified Swift port, including query help and samples. Adaptations follow separately.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Inline the original query configuration and extension declarations unchanged, recording their provenance before adapting them to unified APIs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use models-as-data sources and format-string sinks, update the query ID and test reference, and record the compiling baseline with missing expectations. Formatting sink models, the variadic-call heuristic and numeric barriers remain to be ported.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Translate the standard formatting sinks into models-as-data for String and Foundation formatting APIs and common printf variants. The original cases now produce ten results; omitted variadic arguments, closure-based C string flow and custom formatting heuristics remain missing. All unified security query tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add positive and safe comparisons for localized formatting, NSLog and imported C format functions without closure-based conversion. All ten prior results are preserved and eight additional sink locations are covered.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rence

Record the remaining printf models and extraction prerequisite for custom variadic-call heuristics. Use the verified canonical OWASP reference and clarify the predicate-injection negative case. Help XML and samples validate, and all five affected query and model tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@geoffw0 geoffw0 added no-change-note-required This PR does not need a change note Unified labels Nov 2, 2026
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

QHelp previews:

unified/ql/src/queries/security/CWE-134/UncontrolledFormatString.qhelp

Uncontrolled format string

Passing untrusted format strings to functions that use printf style formatting can lead to buffer overflows and data representation problems. An attacker may be able to exploit this weakness to crash the program or obtain sensitive information from its internal state.

Recommendation

Use a constant string literal for the format string to prevent the possibility of data flow from an untrusted source. This also helps to prevent errors where the format arguments do not match the format string.

If the format string cannot be constant, ensure that it comes from a secure data source or is compiled into the source code. If you need to include a string value from the user, use an appropriate specifier (such as %@) in the format string and include the user provided value as a format argument.

Example

In this example, the format string includes a user-controlled inputString:

print(String(format: "User input: " + inputString)) // vulnerable

To fix it, make inputString a format argument rather than part of the format string, as in the following code:

print(String(format: "User input: %@", inputString)) // fixed

References

@geoffw0
geoffw0 marked this pull request as ready for review November 3, 2026 12:14
Copilot AI auto review requested due to automatic review settings November 3, 2026 12:14
@geoffw0
geoffw0 requested a review from a team as a code owner November 3, 2026 12:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The format-string model misses calls with zero or multiple variadic values and incorrectly flags NSException’s plain-message initializer as a format-string sink.

2 open issues
What changed in this PR

Adds unified/swift/uncontrolled-format-string, a security query that uses Unified’s data-flow libraries to trace untrusted input into printf-style format strings.

Changes:

  • Introduces the CWE-134 path query and formatting sink models.
  • Adds Swift regression tests, including known detection gaps, and expected flow paths.
  • Provides query help with vulnerable and corrected examples.
File Description
unified/​ql/​test/​query-tests/​security/​CWE-134/​UncontrolledFormatString/​UncontrolledFormatString.swift Tests formatting APIs, safe inputs, and known gaps.
unified/​ql/​test/​query-tests/​security/​CWE-134/​UncontrolledFormatString/​UncontrolledFormatString.qlref Connects the query to inline-expectation checks.
unified/​ql/​test/​query-tests/​security/​CWE-134/​UncontrolledFormatString/​UncontrolledFormatString.expected Records expected alerts and flow paths.
unified/​ql/​src/​queries/​security/​CWE-134/​UncontrolledFormatStringGood.swift Demonstrates a constant-format fix.
unified/​ql/​src/​queries/​security/​CWE-134/​UncontrolledFormatStringBad.swift Demonstrates a user-controlled format string.
unified/​ql/​src/​queries/​security/​CWE-134/​UncontrolledFormatString.ql Implements the taint-flow query and metadata.
unified/​ql/​src/​queries/​security/​CWE-134/​UncontrolledFormatString.qhelp Explains the risk and remediation.
unified/​ql/​lib/​ext/​format-string.model.yml Defines Foundation and C formatting sinks.

Review effort: Max (auto)

pack: codeql/unified-all
extensible: legacySinkModel
data: # namespace, type, subtypes, name, signature, ext, input, kind, provenance
- ["", "String", true, "init(_:format:)", "", "", "Argument[format:]", "format-string", "manual"]
- ["", "NSMutableString", true, "localizedStringWithFormat(_:_:)", "", "", "Argument[0]", "format-string", "manual"]
- ["", "NSMutableString", true, "appendFormat(_:_:)", "", "", "Argument[0]", "format-string", "manual"]
- ["", "StringProtocol", true, "appendingFormat(_:_:)", "", "", "Argument[0]", "format-string", "manual"]
- ["", "NSException", true, "init(name:reason:userInfo:)", "", "", "Argument[reason:]", "format-string", "manual"]

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation no-change-note-required This PR does not need a change note Unified

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants