...
| Code Block |
|---|
|
void incorrect_password(const char *user) {
int ret;
/* user names are restricted to 256 characters or less */
static const char MSGmsg_FORMATformat[] = "%s cannot be authenticated.\n";
size_t len = strlen(user) + sizeof(MSGmsg_FORMATformat);
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 */ ;
fprintf(stderr, msg);
free(msg);
}
|
...
| Code Block |
|---|
|
void incorrect_password(const char *user) {
int ret;
/* user names are restricted to 256 characters or less */
static const char MSGmsg_FORMATformat[] = "%s cannot be authenticated.\n";
size_t len = strlen(user) + sizeof(MSGmsg_FORMATformat);
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 |
|---|
|
#define MSG_FORMAT
void incorrect_password(const char *user) {
static const char msg_format[] = "%s cannot be authenticated.\n"
void incorrect_password(const char *user) {;
fprintf(stderr, MSGmsg_FORMATformat, user);
}
|
Noncompliant Code Example (POSIX)
| Wiki Markup |
|---|
This noncompliant code example is exactly the same as the first noncompliant code example but uses the POSIX function {{syslog()}} \[[Open Group 04|AA. C References#Open Group 04]\] instead of the {{fprintf()}} function, which is also susceptible to format-string vulnerabilities. |
| Code Block |
|---|
|
#define MSG_FORMAT "%s cannot be authenticated.\n"
void incorrect_password(const char *user) {
int ret;
/* user names are restricted to 256 characters or less */
static const char *msg_format[] = MSG_FORMAT; "%s cannot be authenticated.\n";
size_t len = strlen(user) + sizeof(msg_format);
char *msg = (char *)malloc(len);
if (msg !msg= NULL) {
/* Handle error condition */
}
int ret = snprintf(msg, len, msg_format, user);
if (ret < 0 || ) /* Handle error */ ;
else if (ret >= len) {\
/* Handle truncated erroroutput */ ;
}
syslog(LOG_INFO, msg);
free(msg);
msg = NULL;
}
|
The syslog() function first appeared in BSD 4.2 and is supported by Linux and other modern UNIX implementations. It is not available on Windows systems.
...
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 |
|---|
|
#define MSG_FORMAT
void incorrect_password(const char *user) {
static const char msg_format[] = "%s cannot be authenticated.\n"
void incorrect_password(const char *user) {;
syslog(LOG_INFO, MSGmsg_FORMATformat, user);
}
|
Risk Assessment
...