Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This compliant solution fixes the problem by replacing the fprintf() call with a call to fputs(), which does not treat msg like a format string but outputs it to stderr as is.:

Code Block
bgColor#ccccff
langc
void incorrect_password(const char *user) {
  int ret;
  /* User names are restricted to 256 characters or less */
  static const char msg_format[] = "%s cannot be authenticated.\n";
  size_t len = strlen(user) + sizeof(msg_format);
  char *msg = (char *)malloc(len);
  if (msg == NULL) {
    /* Handle error */
  }
  ret = snprintf(msg, len, msg_format, user);
  if (ret < 0) /* Handle error */ ;
  else if (ret >= len) /* Handle truncated output */ ;

  if (fputs(msg, stderr) == EOF) {
    /* Handle error */
  }
  free(msg);
}

...

This simpler compliant solution passes the untrusted user input as one of the variadic arguments to fprintf() and not as part of the format string, eliminating the possibility of a format-string vulnerability.:

Code Block
bgColor#ccccff
langc
void incorrect_password(const char *user) {
  static const char msg_format[] = "%s cannot be authenticated.\n";
  fprintf(stderr, msg_format, user);
}

...

This noncompliant code example is exactly the same as the first noncompliant code example but uses the POSIX function syslog() [Open Group 2004] instead of the fprintf() function, which is also susceptible to format-string vulnerabilities.:

Code Block
bgColor#FFCCCC
langc
void incorrect_password(const char *user) {
  int ret;
  /* User names are restricted to 256 characters or less */
  static const char msg_format[] = "%s cannot be authenticated.\n";
  size_t len = strlen(user) + sizeof(msg_format);
  char *msg = (char *)malloc(len);
  if (msg != NULL) {
    /* Handle error */
  }
  ret = snprintf(msg, len, msg_format, user);
  if (ret < 0) /* Handle error */ ;
  else if (ret >= len) /* Handle truncated output */ ;

  syslog(LOG_INFO, msg);
  free(msg);
}

...

This compliant solution passes the untrusted user input as one of the variadic arguments to syslog() instead of including it in the format string.:

Code Block
bgColor#ccccff
langc
void incorrect_password(const char *user) {
  static const char msg_format[] = "%s cannot be authenticated.\n";
  syslog(LOG_INFO, msg_format, user);
}

...

Tool

Version

Checker

Description

Compass/ROSE

 

 

 
Coverity6.5TAINTED_STRING_WARNINGFully implemented.

Fortify SCA

5.0

  
GCC
Include Page
GCC_V
GCC_V
 

Can detect violations of this rule when the -Wformat-security flag is used.

Klocwork

Include Page
Klocwork_V
Klocwork_V

SV.FMTSTR.GENERIC
SV.TAINTED.FMTSTR

 

LDRA tool suite

Include Page
LDRA_V
LDRA_V

86 D

Partially implemented.

Splint

Include Page
Splint_V
Splint_V
  

...