[19] Fix format string issue in WebExtension error handling
Severity: Low | Component: WebKit Web Extensions error utilities | 8dea243
Rated Low because reachability requires an installed extension calling these binding APIs (not a normal web origin), and the analyst flags as unverified whether any pre-fix path actually passed an extension-derived string as the format argument — without that, the latent format-string surface remains theoretical.
Source/WebKit/Shared/Extensions/WebExtensionUtilities.cpp
-String toErrorString(const String& callingAPIName, const String& sourceKey, String underlyingErrorString, ...)
+String toErrorString(const String& callingAPIName, const String& sourceKey, const String& underlyingErrorString)
{
ASSERT(!underlyingErrorString.isEmpty());
- va_list arguments;
- va_start(arguments, underlyingErrorString);
- String formattedUnderlyingErrorString = formatString(underlyingErrorString.utf8().data(), arguments).trim(...);
- va_end(arguments);
+ String formattedUnderlyingErrorString = underlyingErrorString.trim(...);
...
- return formatString("Invalid call to %s. The '%s' value is invalid, because %s.", callingAPIName.utf8().data(), source.utf8().data(), lowercaseFirst(formattedUnderlyingErrorString).utf8().data());
+ return makeString("Invalid call to "_s, callingAPIName, ". The '"_s, source, "' value is invalid, because "_s, lowercaseFirst(formattedUnderlyingErrorString), "."_s);
}
Patch Details
toErrorString() loses its trailing variadic and the internal va_list/vsnprintf/CFStringCreateWithFormatAndArguments/_vsnwprintf plumbing (the static formatString helpers are deleted entirely). The companion toWebExtensionError template variadic in WebExtensionUtilities.h collapses to a non-variadic inline. All ~30+ call sites across UIProcess/WebProcess extension API files are rewritten so the formatted error message is built by WTF::makeString(...) — NSString* arguments wrapped in String(...), integers passed natively — and handed to toErrorString/toWebExtensionError as a single fixed const String&.
Use of a runtime-constructed string as a printf-style format argument, allowing %-specifiers in tainted data to be interpreted as conversion specifications.
Background
printf-family functions interpret a format string for conversion specifiers (%s, %@, %n, %llu) and read one variadic argument per specifier from a va_list. WTF::String::utf8().data() returns a const char* view of a possibly runtime-constructed string — including any literal % characters. WTF::makeString(...) builds a String by typed-piece concatenation with no format interpretation. WTF_ATTRIBUTE_PRINTF is a compiler hint that enables -Wformat-family checking — but only when the format is a literal at the call site, not when it flows through a String parameter.
Analysis
The pre-fix toErrorString took a variadic ... and forwarded underlyingErrorString.utf8().data() as the format. Any path where underlyingErrorString could be influenced by attacker-controlled data — extension-supplied script ID, ruleset name, match pattern, URL, NSString fed into a %@ slot — would let %-specifiers in that data be interpreted as conversion specifications, producing mismatched-argument reads (stack disclosure) or, on the vsnprintf path, an OOB write via %n. On Cocoa, CFStringCreateWithFormatAndArguments follows CF semantics where unmatched %@ consumes a pointer-sized argument off the va_list and Objective-C-decodes it.
Aaaa Aa a Aaaaaaaa Aaaa Aa Aaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaa a Aaaaa Aaaaa Aa Aaaaaaa Aaa Aaaaaaaaa Aaaa Aaaaaaa Aaaaaaaaaa Aaaaaaaa Aaaa Aaa Aaaaaa Aa a Aaaaaaa Aa Aaa Aaaa Aaaaa Aaa Aaaa Aaa Aaaaaa Aaaaaa Aaaaaaa a Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaa Aa Aaa Aaaaaaaa Aaaaa Aaa Aaaaaaaaaaa Aaaaa Aaa Aaaaa Aaa a Aaaaaaa Aaaa a Aa Aa Aaaaaa Aaa Aaaaaaaa Aaaaaaa Aaa Aaaaa Aaaaaaa Aaaaaaa Aaaaaaaaaaaa Aaaaaaaaaaaaaa Aaaa Aaaaaaa Aaaaaa Aaaaaa Aaaaaaa Aa Aaaaaaaa a Aaaaaa
Aaaa Aaaaaaaaaaaaa Aaaaaaa Aaaaaaaaaaa Aaaaaa Aaaaaa Aaa Aaaaaaaaa Aaaa Aaaa Aaa Aaaaaaaaa Aaa Aaaaaaaaa Aaaaaaaaaaaa Aaaaaaaa a Aaaaaaaaa Aaaaaaaaa Aaaaaaaaaa Aaa Aaaaa Aaaaaaaa Aaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaa
🔒Detailed analysis of the format-string surface and whether the pre-fix code was ever reachable with attacker-influenced format input.
Subscribe to read more
Audit directions
a Aaaaaaaaaa Aaaaaaaaaaaa Aaaaaaa Aaaaaaaaa a Aaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aa Aaa Aaaaaa Aaaaaaaaaaa Aaaa Aaaa Aaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaa Aaaa Aaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aaaa Aaaaaaaaa
a Aaaaaaaaaaaaaaaaaa Aaaaaa Aaaa Aaaaaaaaaaa Aaaaaaaaaaaaaaaaaaa Aaaaaaa Aaaa Aaaaaa Aaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaaaaaaaaa Aaaaaaaaaaaaaaa Aaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaa
a Aaaaaaaa Aaaaa Aaa Aaaaaaaaa Aa Aaaaaaaaaaaa Aaaaaa Aa Aaaa Aa Aaaaaaaaaaa Aa Aaaaaaaaaaaaaaaa Aaaa Aaaaaaaaaaaaa Aaaa Aaaaaaaa Aaaaaaaaaaa Aa Aaaa Aaaaaaa Aa Aaaaaaaaa Aaaaaaa Aa Aaaaaaaaaaaa Aa a Aaaaaaaa Aaaaaa Aaaa
a Aaaaaaaaa Aaaaaaaaaaaaaaa Aa Aaaa Aaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaa Aaaaaa a Aaa Aaaa Aaaa Aaaaa Aaa Aaaaaaa Aaaa Aaaaa Aaaa Aaaa a Aaaa Aaaaaaaaaaaaa Aaaa Aaaaaaaaaa
🔒Multiple reusable audit patterns identified, including grep starting points for variadic printf-style helpers across WebKit.
Subscribe to read more