Documentation for ValidatedFormat/ValidFormatSpecifiers

Is there documentation or a video for

-[NSString initWithValidatedFormat:validFormatSpecifiers:locale:error:]

and similar APIs?

Answered by Frameworks Engineer in 891445022

Yes the locale provided is just used for formatting arguments like numbers (and for things like stringsdict case selection, etc.) - exactly the same as the non-validating APIs.

The specifiers in validFormatSpecifiers should be provided in order and match the provided arguments. It's ok if the untrusted specifiers use positional specifiers like %2$@ - NSString will handle finding the right specifier in the trusted string to match to.

The untrusted string is allowed to have fewer specifiers than the trusted string as this is safe, but having more specifiers than the trusted string (unless some are repeated with positional arguments) is unsafe and will return an error.

Looks like this is indeed lacking documentation.

Could you file a feedback for us to document that?

FB23038053

Thanks for filing the feedback so we can update the documentation. In the meantime, I can provide a quick overview:

These functions behave mostly like the equivalent functions without "Validated" in the name that you might have used before. They additionally add validation behavior on top of them. In general, string format specifiers are very powerful, but if provided by untrusted sources they can lead to security vulnerabilities. Format specifiers can lead to interpreting arguments as arbitrary types and dereferencing arbitrary memory, so it's important that your format strings are always trusted. However, in some cases your format string may be untrusted (for example, if the format string is received from a network request). In these cases, the validated APIs allow you to provide two strings: the untrusted format string, and a separate validFormatSpecifiers string that is trusted and guaranteed to match the provided arguments. During formatting, if the untrusted string's specifiers do not match the trusted string's specifiers, this API safely reports an error rather than continuing and crashing (or worse).

For example, if you write the following code:

[[NSString alloc] initWithValidatedFormat:untrustedFormat validFormatSpecifiers:@"%@%ld" locale: nil error: &error, myObject, someInteger]

If untrustedFormat is Hello %@ x%ld! then formatting will succeed. However if the untrusted format string is Malicious multiple objects %@ and %@ formatting will fail with an error because it is not safe to dereference the integer argument as an object.

This can also be very useful when building with -Wformat-nonliteral which requires format strings to be literals (so that the compiler can guarantee they match the provided arguments via -Wformat-security). If you can't make your format string a literal, you can use these validated functions to provide a different literal that we validate against the non-literal format string at runtime.

So the specifiers must be provided in-order? The locale then is just used for numeric types.

Is providing fewer specifiers still considered safe if they match the given order?

Accepted Answer

Yes the locale provided is just used for formatting arguments like numbers (and for things like stringsdict case selection, etc.) - exactly the same as the non-validating APIs.

The specifiers in validFormatSpecifiers should be provided in order and match the provided arguments. It's ok if the untrusted specifiers use positional specifiers like %2$@ - NSString will handle finding the right specifier in the trusted string to match to.

The untrusted string is allowed to have fewer specifiers than the trusted string as this is safe, but having more specifiers than the trusted string (unless some are repeated with positional arguments) is unsafe and will return an error.

Documentation for ValidatedFormat/ValidFormatSpecifiers
 
 
Q