SV.FMTSTR.GENERIC

Format string vulnerability

When format strings aren't explicit, they can be injected from outside the code, which means that an attacker may be able to provide a specially crafted format string to execute arbitrary code. This type of weakness can typically be introduced in

  • code that constructs log messages, in which a constant format string is omitted
  • cases of localization, in which language-specific repositories can be vulnerable

The SV.FMTSTR.GENERIC checker finds instances of format strings that can be affected by the user.

Vulnerability and risk

Externally controlled format strings in printf functions can lead to buffer overflows and data representation problems. This type of vulnerability may allow local or remote attackers to cause a denial-of-service (DoS), and possibly execute arbitrary code through format specifiers that are injected into messages.

Mitigation and prevention

To avoid format string issues

  • Eliminate the possibility of injection of arbitrary format strings. Make sure that all format string functions are passed a static string that cannot be controlled by the user.
  • Validate all user input, and review any format strings that could be injected.
  • If possible, use functions that don't support the %n operator in format strings.

Vulnerable code example 1

Copy
   int main()
   {
       printf(some_unknown_function("This is suspicious"));  /* SV.FMTSTR.GENERIC reported here */
    
       return 0;
   }

Fixed code example 1

Printf(gettext(str)) calls are permissible, as shown in this example.

Copy
   int main()
   {
       printf(gettext("This should be OK"));                 /* No defect reported here */
       return 0;
   }

Vulnerable code example 2

Copy
    int main()
   {
       printf(some_unknown_function("This is suspicious"));  /* SV.FMTSTR.GENERIC reported here */
       return 0;
   }

Fixed code example 2

If possible, replace printf(str) calls with printf("%s",str) to specify a character string.

Copy
   int main()
   {
       printf("%s",some_unknown_function("This is better")); /* SV.FMTSTR.GENERIC not reported */
       return 0;
   }

Related checkers