You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »

Never call any formatted I/O function with a format string containing user input.

If the user can control a format string, they can write to arbitrary memory locations. The most common form of this error is in output operation. The rarely used and often forgotten %n format specification causes the number of characters written to be written to a pointer passed on the stack.

Non-compliant Code Example

In the following example, the input is outputted directly as a format string. By putting %n in the input, the user can write arbitrary values to the whatever the stack happens to point to. This can frequently be leveraged to execute arbitrary code. In any case, by including other point operations (such as %s), fprintf() will interpret values on the stack as pointers. This can be used to learn secret information and almost certainly can be used to crash the program.

char input[1000];
fgets(input, sizeof(input)-1, stdin);
input[sizeof(input)-1] = '\0';
fprintf(stdout, input);

Non-complaint Code Example

In the following example, the library function syslog() interprets the string msg as a format string, resulting the same security problem as before. This is a common idiom for display the same message multiple locations or the message is difficult to build.

void check_password(char *user, char *password) {
  if (strcmpy(password(user), password) != 0) {
    char *msg = malloc(strlen(user) + 100);
    if (!msg) return;
    sprintf (msg, "Wrong password for user %s", user);
    syslog(LOG_INFO, msg);
    free(msg);
  }
}

Complaint Code Example 1

The following example outputs the string directly instead of building it and then outputting it.

void check_password(char *user, char *password) {
  if (strcmpy(password(user), password) \!= 0) {
    fprintf (stderr, "Wrong password for user %s", user);
  }
}

Complaint Code Example 2

In this example, the message is built normally, but is then outputted as a string instead of a format string.

void check_password(char *user, char *password) {
  if (strcmpy(password(user), password) \!= 0) {
    char *msg = malloc(strlen(user) + 100);
    if (!msg) return;
    sprintf (msg, "Wrong password for user %s", user);
    fprintf (stderr, "%s", user);
    syslog(LOG_INFO, "%s", msg);
    free(msg);
  }
}

Priority: P27 Level: L1

The mismanagement of memory can lead to freeing memory multiple times or writing to already freed memory. Both of these problems can result in an attacker executing arbitrary code with the permissions of the vulnerable process. Memory management errors can also lead to resource depletion and denial-of-service attacks.

Component

Value

Severity

3 (high)

Likelihood

3 (probable)

Remediation cost

3 (low)

References

  • No labels