Uploaded image for project: 'Rules Repository'
  1. Rules Repository
  2. RSPEC-6069

"sprintf" should not be used

    XMLWordPrintable

    Details

    • Message:
      Remove the use of this insecure 'sprintf' function.
    • Default Severity:
      Critical
    • Impact:
      High
    • Likelihood:
      Low
    • Default Quality Profiles:
      Sonar way, MISRA C++ 2008 recommended
    • Covered Languages:
      C, C++, Objective-C
    • Remediation Function:
      Constant/Issue
    • Constant Cost:
      20min
    • Analysis Scope:
      Main Sources
    • CERT:
      STR07-C.
    • CWE:
      CWE-676, CWE-119
    • OWASP:
      A9
    • SANS Top 25:
      Risky Resource Management

      Description

      When using sprintf , it's up to the developer to make sure the size of the buffer to be written to is large enough to avoid buffer overflows. Buffer overflows can cause the program to crash at a minimum. At worst, a carefully crafted overflow can cause malicious code to be executed.

      Ask Yourself Whether

      • if the provided buffer is large enough for the result of any possible call to the sprintf function (including all possible format strings and all possible additional arguments).

      There is a risk if you answered no to the above question.

      Recommended Secure Coding Practices

      There are fundamentally safer alternatives. snprintf is one of them. It takes the size of the buffer as an additional argument, preventing the function from overflowing the buffer.

      • Use snprintf instead of sprintf. The slight performance overhead can be afforded in a vast majority of projects.
      • Check the buffer size passed to snprintf.

      If you are working in C++, other safe alternative exist:

      • std::string should be the prefered type to store strings
      • You can format to a string using std::ostringstream
      • Since C++20, std::format is also available to format strings

      Sensitive Code Example

      sprintf(str, "%s", message);   // Sensitive: `str` buffer size is not checked and it is vulnerable to overflows
      

      Compliant Solution

      snprintf(str, sizeof(str), "%s", message); // Prevent overflows by enforcing a maximum size for `str` buffer
      

      Exceptions

      It is a very common and acceptable pattern to compute the required size of the buffer with a call to snprintf with the same arguments into an empty buffer (this will fail, but return the necessary size), then to call sprintf as the bound check is not needed anymore. Note that 1 needs to be added by the size reported by snprintf to account for the terminal null character.

      size_t buflen = snprintf(0, 0, "%s", message);
      char* buf = malloc(buflen) + 1; // For the final 0
      sprintf(buf, "%s", message);

      See

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              loic.joly Loïc Joly
              Reporter:
              geoffray.adde Geoffray Adde
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated: