+
+
+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.
+
+
+
+
+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.
+
+
+
+
+
+In this example, the format string includes a user-controlled inputString:
+
+
+
+To fix it, make inputString a format argument rather than part of the format string, as in the following code:
+
+
+
+
+
+
+
+OWASP:
+Format string attack.
+
+
+
+
diff --git a/unified/ql/src/queries/security/CWE-134/UncontrolledFormatString.ql b/unified/ql/src/queries/security/CWE-134/UncontrolledFormatString.ql
new file mode 100644
index 000000000000..ffc109e08e7a
--- /dev/null
+++ b/unified/ql/src/queries/security/CWE-134/UncontrolledFormatString.ql
@@ -0,0 +1,49 @@
+/**
+ * @name Uncontrolled format string
+ * @description Using external input in format strings can lead to exceptions or information leaks.
+ * @kind path-problem
+ * @problem.severity error
+ * @security-severity 7.3
+ * @precision high
+ * @id unified/swift/uncontrolled-format-string
+ * @tags security
+ * external/cwe/cwe-134
+ */
+
+import unified
+
+/**
+ * A taint configuration for tainted data that reaches a format string.
+ */
+module TaintedFormatConfig implements DataFlow::ConfigSig {
+ predicate isSource(DataFlow::Node node) { Models::isSource(node, _) }
+
+ predicate isSink(DataFlow::Node node) {
+ // TODO: the MaD format currently has the varargs argument first in the
+ // signature, rather than in its normal position.
+ // TODO: we currently model `printf(_:_:)` etc explicitly, rather than with a
+ // more flexible pattern as in the original Swift's `StringFormat.qll`.
+ // TODO: Port the variadic-call heuristic from original Swift's
+ // `UncontrolledFormatStringExtensions.qll` once variadic parameters are extracted.
+ Models::isSink(node, "format-string")
+ }
+
+ predicate isBarrier(DataFlow::Node node) {
+ // TODO: Port the numeric-type barrier from original Swift's UncontrolledFormatStringExtensions.qll.
+ none()
+ }
+
+ predicate observeDiffInformedIncrementalMode() { any() }
+}
+
+/**
+ * Detect taint flow of tainted data that reaches a format string.
+ */
+module TaintedFormatFlow = TaintTracking::Global