Appendix B. ITS4 Rules


ITS4 <http://www.cigital.com/its4/> and its counterparts RATS and Flawfinder provided an early set of software security rules built into very basic static analysis tools. See Chapter 4 for more on static analysis tools and their use.

The rules shown here are enforced in ITS4 by essentially greping through source code looking for simple patternsan approach filled with potential false positives. Not surprisingly, most of these rules are about APIs in UNIX- or Windows-based systems. What follows is a complete list of the kinds of rules that were built into ITS4. RATS added several hundred more rules of a very similar nature.[1]

[1] A Venn diagram of rules overlap for early tools can be seen in Figure 4-1 (of Chapter 4).

The rules shown here were taken from Cigital's extensive knowledge base of software security rules. Only three (of many more) fields are shown. Every basic security scanner should include these rules. Any scanner that doesn't is not worth its salt. Consider this the tiniest minimum set of security rules that every static analysis tool should cover. A better minimum set would include all rules from ITS4, RATS, and SourceScope (see Chapter 4).

This is not an endorsement of ITS4, which is ancient technology that should no longer be used. Instead, the idea is to give you an idea of the kinds of rules that static analysis tools enforce.

Surgeon General's Warning

Use of ITS4 by clueless security people in the name of imposing software security on unsuspecting developers may cause a severe allergic reaction.


API

Kingdom

Description

access

Time and State

The access() function should not be used to attempt to eliminate the need to change to a less privileged mode.

The access() function allows one to check the permissions of a file. access() is vulnerable to TOCTOU attacks. It's commonly accepted that one should never use access() as a way of avoiding changing to a less privileged mode. Because this is the typical usage, this function should be avoided.

On Windows platforms the APIs _access and _waccess are synonymous with access.

acct

Time and State

acct can be abused if an arbitrary path is passed as an argument, specifically if NULL is passed in.

au_to_path

Time and State

Vulnerable to malicious changes to path passed as a parameter.

basename

Time and State

Note: dirname and basename functions should be analyzed together.

The basename() function returns the last component from the pathname pointed to by path, deleting any trailing "/" characters. If path consists entirely of "/" characters, a pointer to the string "/" is returned. If path is a null pointer or the empty string, a pointer to the string "."is returned.

bcopy

Input Validation and Representation

Many functions are susceptible to off-by-one and bounds-checking errors.

There are many generic types of errors that can apply to usage of a wide variety of functions. These include:

  • Using a function that does not permit one to specify the size of a buffer to prevent overflows.

  • Mis-specifying the size of a buffer or the amount of data to be written. Off-by-one errors are common.

  • Failing to plan for correct behavior when input is larger than expected.

  • Failing to allow space for a terminating null character.

  • Failing to ensure that a terminating null character is present; many standard functions consistently experience this failure.

  • Specifying the size of a buffer or the amount of data to be transferred using incorrect units. This is particularly a problem with multibyte strings. On the Windows platform, these functions tend to include a "W" in the name.

  • Assuming the wrong semantics for a parameter that controls data transfer and prevents buffer overflows. Because various functions use the buffer size, buffer size minus one, the remaining space in the buffer, etc., it is important to understand the bounding semantics for each function.

Note that while some functions, such as strcpy(), are intrinsically dangerous, even the "safe" functions like strncpy() are still susceptible to subtle errors if bounds checks are not done properly.

bind

Time and State

Potential race condition with access, according to CERT/CC. Also, bind(s, INADDR_ANY, ) followed by setsockopt(s, SOL_SOCKET, SO_REUSEADDR) leads to potential packet-stealing vulnerability.

catopen

Input Validation and Representation

The catopen() function is vulnerable to manipulations that will substitute a different catalog file than the expected one.

The catopen(char *name, int oflag) function is used to open a message catalog and returns a catalog descriptor. The first argument is the name of the message catalog to be opened. If it contains a /, then the name is a pathname, otherwise it is a basename. The second input is used to specify locale differences.

The function implicitly uses the values of environment variables, even when the name argument contains a /. It can do vaguely printf()-like substitutions on the filename. It does things like replacing %L with the value of the LANG environment variable.

chdir

API Abuse

Call chdir("/") after using the chroot() function.

The chroot() function establishes a virtual root directory for the owning process. This may be used to limit the amount of filesystem access a potential hacker could use if he or she gained control of the process. Programs like ftp and httpd commonly make use of this function.

One weakness of the chroot() function is that it does not work as advertised unless a chdir("/") call is issued after the chroot(). Otherwise, the current working directory could be outside the isolated hierarchy and provide the attacker with access via relative paths.

Use of chroot is desirable but should also be a flag to indicate that one needs to carefully check to ensure that related security issues are addressed.

chgrp

Time and State

The chown() function sets the owner ID and group ID of the file specified by path or referenced by the open file descriptor fildes to owner and group, respectively. If owner or group is specified as -1, chown() does not change the corresponding ID of the file.

The lchown() function sets the owner ID and group ID of the named file in the same manner as chown(), unless the named file is a symbolic link. In this case, lchown() changes the ownership of the symbolic link file itself, while chown() changes the ownership of the file or directory to which the symbolic link refers.

The fchownat() function sets the owner ID and group ID of the named file in the same manner as chown(). If, however, the path argument is relative, the path is resolved relative to the fildes argument rather than the current working directory. If the fildes argument has the special value FDCWD, the path resolution reverts back to the current working directory relative. If the flag argument is set to SYMLNK, the function behaves like lchown() with respect to symbolic links. If the path argument is absolute, the fildes argument is ignored. If the path argument is a null pointer, the function behaves like fchown().

If chown(), lchown(), fchown(), or fchownat() is invoked by a process other than super-user, the set-user-ID and set-group-ID bits of the file mode, S_ISUID and S_ISGID, respectively, are cleared.

chown() is vulnerable to TOCTOU attacks. The existence of a call to this function should be flagged regardless of whether a "check" function precedes it.

chmod

Time and State

The chmod() and fchmod() functions set the access permission portion of the mode of the file whose name is given by path or referenced by the open file descriptor files to the bit pattern contained in mode. This function is used to change the read/write permissions of a file.

Note: The functions of the chmod class have significantly differing functionality and warrant individual description.

lchmod(), while having the same function signature as chmod, differs from chmod in that it does not follow symbolic links.

fchmod(), while performing the same function as chmod, operates on a file descriptor, and not a filename.

chmod() is vulnerable to TOCTOU attacks. The existence of a call to this function should be flagged regardless of whether a "check" function precedes it.

chown

Time and State

The chown() function sets the owner ID and group ID of the file specified by path or referenced by the open file descriptor fildes to owner and group, respectively. If owner or group is specified as -1, chown() does not change the corresponding ID of the file.

The lchown() function sets the owner ID and group ID of the named file in the same manner as chown(), unless the named file is a symbolic link. In this case, lchown() changes the ownership of the symbolic link file itself, while chown() changes the ownership of the file or directory to which the symbolic link refers.

The fchownat() function sets the owner ID and group ID of the named file in the same manner as chown(). If, however, the path argument is relative, the path is resolved relative to the fildes argument rather than the current working directory. If the fildes argument has the special value FDCWD, the path resolution reverts back to current working directory relative. If the flag argument is set to SYMLNK, the function behaves like lchown() with respect to symbolic links. If the path argument is absolute, the fildes argument is ignored. If the path argument is a null pointer, the function behaves like fchown().

If chown(), lchown(), fchown(), or fchownat() is invoked by a process other than super-user, the set-user-ID and set-group-ID bits of the file mode, S_ISUID and S_ISGID, respectively, are cleared.

chown() is vulnerable to TOCTOU attacks. The existence of a call to this function should be flagged regardless of whether a "check" function precedes it.

chroot

Time and State

Unset root SUID after calling chroot().

The chroot() function establishes a virtual root directory for the owning process. This may be used to limit the amount of filesystem access a potential hacker could use if he or she gained control of the process. Programs like ftp and httpd commonly make use of this function.

The chroot() function requires root (super-user) access to call. If the programmer continues to run as root after the chroot() call, he or she opens up a potential vulnerability window for an attacker to use elevated privilege.

Use of chroot is desirable, but should also be a flag to indicate that one needs to carefully check to ensure that related security issues are addressed.

copylist

Time and State

Care must be taken when accessing files from passed-in filenames.

creat

Time and State

The creat function creates a new ordinary file or prepares to rewrite an existing file named by the pathname pointed to by path.

If the file exists, the length is truncated to 0 and the mode and owner are unchanged.

If the file does not exist, the file's owner ID is set to the effective user ID of the process. The group ID of the file is set to the effective group ID of the process, or if the S_ISGID bit is set in the parent directory, then the group ID of the file is inherited from the parent directory. The access permission bits of the file mode are set to the value of mode modified as follows:

If the group ID of the new file does not match the effective group ID or one of the supplementary group IDs, the S_ISGID bit is cleared.

All bits set in the process's file mode creation mask (see umask(2)) are correspondingly cleared in the file's permission mask.

The "save text image after execution bit" of the mode is cleared (see chmod(2) for the values of mode).

Upon successful completion, a write-only file descriptor is returned and the file is open for writing, even if the mode does not permit writing. The file pointer is set to the beginning of the file. The file descriptor is set to remain open across exec functions (see fcntl(2)). A new file may be created with a mode that forbids writing.

The call creat(path, mode) is equivalent to:

open(path, O_WRONLY | O_CREAT | O_TRUNC, mode)

This function is a problem because it is possible to unintentionally delete a file or enter a potentially unstable race condition.

creat() is vulnerable to TOCTOU attacks. The existence of a call to this function should be flagged regardless of whether a "check" function precedes it.

cuserid

API Abuse

cuserid() generates a character-string representation of the username corresponding to the effective user ID of the process. If s is a NULL pointer, this representation is generated in an internal static area, the address of which is returned. Otherwise, s is assumed to point to an array of at least L_cuserid characters; the representation is left in this array. The constant L_cuserid is defined in the <stdio.h> header file.

cuserid() should be considered obsolete.

This function has been or will be deprecated in several systems (e.g., HPUnix, ISO POSIX-1).

Additionally this function has changed capability within a given OS (HP).

Therefore, in all cases, convert to getpwuid (getuid()), getpwuid (geteuid()), or getlogin(), depending on which username is desired.

db_ initialize

Time and State

Watch out when files are passed in as pathnames.

dbm_open

Time and State

Can be involved in a race condition if you open things after a poor check. For example, don't check to see if something is not a symbolic link before opening it. Open it, then check by querying the resulting object. Don't run tests on symbolic filenames.

dbminit

Time and State

TOCTOU problems when opening a file.

dirname

Time and State

Note: dirname, basename functions should be analyzed together.

The dirname() function takes a pointer to a character string that contains a pathname, and returns a pointer to a string that is a pathname of the parent directory of that file. Trailing '/' characters in the path are not counted as part of the path.

If path does not contain a '/', then dirname() returns a pointer to the string ".". If path is a null pointer or points to an empty string, dirname() returns a pointer to the "." string .

A call to dirname() should be flagged if the argument (the directory name) is used previously in a "check" category call.

dlopen

Time and State

Take care when accessing files from passed-in pathnames; they are vulnerable to symbolic linking.

drand48 erand48

Security Feature

The random function is a Linear Congruential Generator (LCG) used to create pseudorandom integers. That by itself is not a security issue. However, how the numbers are used can be a problem. The algorithm that generates the numbers is well known, the range of numbers generated is very small (in a cryptographic context), and the generated numbers can be guessed with reasonable ease. Hence, if the pseudorandom numbers are used as the basis for encryption computations, then it becomes a security problem. There is simply not enough randomness or entropy in the pseudorandom numbers generated by the LCGs for them to be used in high-security encryption.

execl execle execlp

API Abuse

The exec() class of functions is used for executing a file as a process image.

The exec() family of calls is vulnerable to TOCTOU attacks.

A call to an exec() family function should be flagged if the first argument (the directory or filename) is used earlier in a "check" category call.

Path-searching exec functions are susceptible to malicious programs inserted into the search path.

The APIs execlp, execvp, popen, and system are usually implemented through a shell or exhibit shell-like characteristics. If user input can affect the arguments to the function, a malicious user could change or add commands to be run.

These functions search the path if a full path to the program is not specified. When using these functions, always specify the full path to the program. The Windows _exec and system family of functions is also vulnerable in the same manner. Also be sure to include the file extension (.exe, .com, .bat) to prevent unwanted matches.

execv execve execvp

API Abuse

The exec() class of functions is used for executing a file as a process image.

The exec() family of calls is vulnerable to TOCTOU attacks.

A call to an exec() family function should be flagged if the first argument (the directory or filename) is used earlier in a "check" category call.

Path-searching exec functions are susceptible to malicious programs inserted into the search path.

The APIs execlp, execvp, popen, and system are usually implemented through a shell or exhibit shell-like characteristics. If user input can affect the arguments to the function, a malicious user could change or add commands to be run.

These functions search the path if a full path to the program is not specified. When using these functions, always specify the full path to the program. The Windows _exec and system family of functions is also vulnerable in the same manner. Also be sure to include the file extension (.exe, .com, .bat) to prevent unwanted matches.

fattach fchmod fchown fdetatch

Time and State

Care must be taken when accessing files passed in pathnames. ACL-based race conditions are possible.

fdopen

Time and State

Can be involved in a race condition if you open things after a poor check. For example, you don't check to see if something is not a symbolic link before opening it. Open it, then check by querying the resulting object. Don't run tests on symbolic filenames.

fgetc

Input Validation and Representation

Be careful not to introduce a buffer overflow when using a loop.

fgets

Input Validation and Representation

Low risk of buffer overflows.

fopen

Time and State

The fopen() function, used to open files, is vulnerable to several attacks.

First, if proper checks are not made, an attacker could replace an important file, such as a password file, causing the program to read and process incorrect data. The function is also vulnerable to TOCTOU attacks, where an attacker can modify a file between execution of a check function and a use function.

Note: On Windows platforms, the APIs _tfopen and _wfopen are synonymous with fopen.

fprintf

Input Validation and Representation

The printf family of functions is susceptible to a variety of format string and buffer overflow attacks. Flag any instance of the printf() family of functions in the code. Determine whether or not the format string is being provided through some input channel. If it is using a single argument, this is a definite vulnerability. Replace the code with the "fix" section.

If the first argument is a string literal constant, this rule does not apply.

If the first argument is a variable string, try to determine if it is user supplied. If so, it will be more difficult to determine whether it is vulnerable to the threat or not. If it is influenced by any data that comes into the current function, it should be flagged as a (potentially false positive) vulnerability.

All of these functions have potential format string problems. Some (as marked) also have potential BO problems when they write their output to strings.

fread

Input Validation and Representation

Check to make sure malicious input can have no ill effect.

freopen

Time and State

The freopen() function first attempts to flush the stream and close any file descriptor associated with stream. Failure to flush or close the file successfully is ignored. The error and end-of-file indicators for the stream are cleared.

The freopen() function opens the file whose pathname is the string pointed to by filename and associates the stream pointed to by stream with it. The mode argument is used just as in fopen().

freopen() is vulnerable to TOCTOU attacks. A call to freopen() should be flagged if the first argument (the directory or filename) is used earlier in a "check" category call.

On Windows platforms the APIs _freopen, _tfreopen, and _wfreopen are synonymous with freopen.

fscanf

Input Validation and Representation

The scanf family of functions scans input according to a format as described below. This format may contain conversion specifiers; the results from such conversions, if any, are stored through the pointer arguments. The scanf function reads input from the standard input stream stdin, fscanf reads input from the stream pointer stream, and sscanf reads its input from the character string pointed to by str.

The vulnerability of the scanf() function resides in the fact that it has no bounds-checking capability. If the string that is being accepted is longer than the buffer size, the characters will overflow into the adjoining memory space. This is a classic buffer overflow security vulnerability problem.

scanf() function is susceptible to buffer overflow.

fstat ftok ftw

Time and State

Verify file states before file operations; they are susceptible to races. (Also make sure that buffers are large enough.)

fwprintf

Input Validation and Representation

The printf family of functions is susceptible to a variety of format string and buffer overflow attacks. Flag any instance of the printf() family of functions in the code. Determine whether or not the format string is being provided through some input channel. If it is using a single argument, this is a definite vulnerability. Replace the code with the "fix" section.

If the first argument is a string literal constant, this rule does not apply.

If the first argument is a variable string, try to determine if it is user supplied. If so, it will be more difficult to determine whether it is vulnerable to the threat or not. If it is influenced by any data that comes into the current function, it should be flagged as a (potentially false positive) vulnerability.

All of these functions have potential format string problems. Some (as marked) also have potential BO problems when they write their output to strings.

getattr

Time and State

Subject to race on reference to device by name.

getc

Input Validation and Representation

The getc() function is used to get the next character from the standard input stream. (The function returns the character read as an unsigned char cast to an int or EOF on end of file or error.) Other similar functions get the next character from other input streams (e.g., from files).

The getc() function, in isolation, is not a security risk. However, the function is often misused when filling buffers. Often, programmers will repeatedly call getc() and copy the characters into a buffer until a certain character is encountered, without checking the current position in the buffer. This can easily cause a buffer overflow.

Also, it is easy to forget to include the null terminator at the end of the string in the buffer. Otherwise, the unterminated string can cause problems such as access violations.

getchar

Input Validation and Representation

The getc() function is used to get the next character from the standard input stream. (The function returns the character read as an unsigned char cast to an int or EOF on end of file or error.) Other similar functions get the next character from other input streams (e.g., from files).

The getc() function, in isolation, is not a security risk. However, the function is often misused when filling buffers. Often, programmers will repeatedly call getc() and copy the characters into a buffer until a certain character is encountered, without checking the current position in the buffer. This can easily cause a buffer overflow.

Also, it is easy to forget to include the null terminator at the end of the string in the buffer. Otherwise, the unterminated string can cause problems such as access violations.

getenv

Input Validation and Representation

Value of variables stored in character array, return value size unknown.

getlogin

The results of getlogin() should not be trusted.

The getlogin() function returns a pointer to a string that contains the name of the user associated with the calling process. The function is not reentrant, meaning that if it is called from another process, the contents are not locked out and the value of the string can be changed by another process. This makes it very risky to use because the username can be changed by other processes, so the results of the function cannot be trusted.

Also, according to the Linux man page: "Unfortunately, it is often rather easy to fool getlogin(). Sometimes it does not work at all, because some program messed up the utmp file. Often, it gives only the first 8 characters of the login name. The user currently logged in on the controlling tty of our program need not be the user who started it. Avoid getlogin() for security-related purposes."

Guidance: Using names for security purposes is not advised. Names are easy to forge and can have overlapping user IDs, potentially causing confusion or impersonation.

getopt getopt_long getopt_long_only

Input Validation and Representation

Some implementations of getopt() are vulnerable to internal buffer overflows.

The getopt(int argc, char *const argv[], const char *optstring) function is used to parse the command line parameters. The level of security risk is implementation dependent, in that for some C packages, it is possible for a buffer overflow to occur. The third argument of the function is a list of option characters. If the option character is followed by a colon, then the option requires an argument; two consecutive colons means the argument is optional. This is used to specify options, such as -w, in the command line.

Flag instances of getopt(), and getopt_long(). Look for nearby bounds checks.

There is a portability issue for old platforms. Check documentation for your particular platform.

getpass

Input Validation and Representation

Some versions of getpass() allow overflow of an internal buffer.

The getpass function is designed to accept a password from the console, which is a null-terminated string. The echo is off, so it will not appear on the screen. It can lead to a buffer overflow problem, but that is very implementation dependent. In some implementations of the function, there is a maximum length defined for the password, and in other implementations, the password can be of arbitrary length.

gets

Input Validation and Representation

The gets() function is intrinsically unsafe and should not be used.

The gets() function reads characters from stdin and stores them in a buffer until a newline or EOF character is encountered. There is no way to specify the size of the buffer, so this function is very vulnerable to buffer overflows.

jrand48

Security Feature

The random function is a Linear Congruential Generator (LCG) used to create pseudorandom integers. That by itself is not a security issue. However, how the numbers are used can be a problem. The algorithm that generates the numbers is well known, the range of numbers generated is very small (in a cryptographic context), and the generated numbers can be guessed with reasonable ease. Hence, if the pseudorandom numbers are used as the basis for encryption computations, then it becomes a security problem. There is simply not enough randomness or entropy in the pseudorandom numbers generated by the LCGs for them to be used in high-security encryption.

krb_recvauth krb_set_tkt_string

Time and State

Kerberos functions related to keys and all are susceptible to races.

kvm_open

Encapsulation

Susceptible to races.

lchown

Time and State

The chown() function sets the owner ID and group ID of the file specified by path or referenced by the open file descriptor fildes to owner and group, respectively. If owner or group is specified as -1, chown() does not change the corresponding ID of the file.

The lchown() function sets the owner ID and group ID of the named file in the same manner as chown(), unless the named file is a symbolic link. In this case, lchown() changes the ownership of the symbolic link file itself, while chown() changes the ownership of the file or directory to which the symbolic link refers.

The fchownat() function sets the owner ID and group ID of the named file in the same manner as chown(). If, however, the path argument is relative, the path is resolved relative to the fildes argument rather than the current working directory. If the fildes argument has the special value FDCWD, the path resolution reverts back to current working directory relative. If the flag argument is set to SYMLNK, the function behaves like lchown() with respect to symbolic links. If the path argument is absolute, the fildes argument is ignored. If the path argument is a null pointer, the function behaves like fchown().

If chown(), lchown(), fchown(), or fchownat() is invoked by a process other than super-user, the set-user-ID and set-group-ID bits of the file mode, S_ISUID and S_ISGID, respectively, are cleared.

chown() is vulnerable to TOCTOU attacks. The existence of a call to this function should be flagged regardless of whether a "check" function precedes it.

link

Time and State

Can lead to Process/File interaction race conditions (TOCTOU).

lrand48

Security Feature

The random function is a Linear Congruential Generator (LCG) used to create pseudorandom integers. That by itself is not a security issue. However, how the numbers are used can be a problem. The algorithm that generates the numbers is well known, the range of numbers generated is very small (in a cryptographic context), and the generated numbers can be guessed with reasonable ease. Hence, if the pseudorandom numbers are used as the basis for encryption computations, then it becomes a security problem. There is simply not enough randomness or entropy in the pseudorandom numbers generated by the LCGs for them to be used in high-security encryption.

lstat

Time and State

The stat() function obtains information about the file pointed to by path. Read, write, or execute permission of the named file is not required, but all directories listed in the pathname leading to the file must be searchable.

lstat() is like stat() except in the case where the named file is a symbolic link, in which case lstat() returns information about the link, while stat() returns information about the file the link references.

fstat() obtains the same information about an open file known by the file descriptor fd.

stat() is used in combination with other functions that manipulate the file being queried (e.g., mkdir is vulnerable to TOCTOU attacks).

A call to stat() should be flagged if the first argument (the directory name) is used later in a use category call.

mbstowcs

Input Validation and Representation

Internal stack allocated buffer can be overflowed on some versions. Also watch for the NULL terminator.

memcpy

Input Validation and Representation

Many functions are susceptible to off-by-one and bounds-checking errors.

There are many generic types of errors that can apply to usage of a wide variety of functions.

These include:

  • Using a function that does not permit one to specify the size of a buffer to prevent overflows.

  • Mis-specifying the size of a buffer or the amount of data to be written. Off-by-one errors are common.

  • Failing to plan for correct behavior when input is larger than expected.

  • Failing to allow space for a terminating null character.

  • Failing to ensure that a terminating null character is present; many standard functions consistently experience this failure.

  • Specifying the size of a buffer or the amount of data to be transferred using incorrect units. This is particularly a problem with multibyte strings. On the Windows platform, these functions tend to include a "W" in the name.

  • Assuming the wrong semantics for a parameter that controls data transfer and prevents buffer overflows. Because various functions use the buffer size, buffer size minus one, the remaining space in the buffer, etc., it is important to understand the bounding semantics for each function.

Note that while some functions, such as strcpy(), are intrinsically dangerous, even the "safe" functions like strncpy() are still susceptible to subtle errors if bounds checks are not done properly.

mkdir mkdirp

Time and State

The mkdir() function attempts to create a new empty directory. It is generally vulnerable to classic TOCTOU attacks.

A call to mkdir() should be flagged if the first argument (the directory) is used earlier in a "check" category call.

mknod

Time and State

The mknod function creates a new file (or directory or special file) called pathname with theMode as the mode. The file type and permissions of the new file are initialized from the mode. mknod() is often used to create device files.

mknod() is vulnerable to TOCTOU attacks.

A call to mknod() should be flagged if the first argument (the filename) is used previously in a "check" category call.

mkstemp

Time and State

Unique temporary filenames may not have correct file modes. Use with care.

mktemp

Time and State

The mktemp(char *template) creates a unique temporary file using the input template. The last six characters of the template must be XXXXXX, and these are replaced with a string that will make the filename unique. THIS FUNCTION SHOULD NOT BE USED.

Some implementations replace the XXXXXX combination with the current process ID followed by a single letter. With only 26 possible values, it is relatively easy for an attacker to guess the filename and access the contents. It is also possible for a race condition to exist between testing whether the name exists and opening the file.

mktemp() is vulnerable to TOCTOU attacks. A call to mktemp() should be unilaterally flagged.

If this call must be used and if a "check present" is done, then a race condition is possible. This function creates a file; as such there is a vulnerability (based on the above description) that the filename can be "guessed."

mount

Time and State

Can lead to Process/File interaction race conditions (and runs as root).

mrand48

Security Feature

The random function is a Linear Congruential Generator (LCG) used to create pseudorandom integers. That by itself is not a security issue. However, how the numbers are used can be a problem. The algorithm that generates the numbers is well known, the range of numbers generated is very small (in a cryptographic context), and the generated numbers can be guessed with reasonable ease. Hence, if the pseudorandom numbers are used as the basis for encryption computations, then it becomes a security problem. There is simply not enough randomness or entropy in the pseudorandom numbers generated by the LCGs for them to be used in high-security encryption.

nftw nis_getserv -list nis_mkdir nis_ping nis_rmdir nlist

Time and State

Susceptible to race conditions. Watch for file substitution.

nrand48

Security Feature

The random function is a Linear Congruential Generator (LCG) used to create pseudorandom integers. That by itself is not a security issue. However, how the numbers are used can be a problem. The algorithm that generates the numbers is well known, the range of numbers generated is very small (in a cryptographic context), and the generated numbers can be guessed with reasonable ease. Hence, if the pseudorandom numbers are used as the basis for encryption computations, then it becomes a security problem. There is simply not enough randomness or entropy in the pseudorandom numbers generated by the LCGs for them to be used in high-security encryption.

open

Time and State

The open function establishes a connection between a file and a file descriptor. Pathname is the name of the file to open, and fileFlags is the bitwise OR of a series of constants used to specify the file access modes. An optional additional input is used to specify the permissions, such as read-only.

open() is vulnerable to TOCTOU attacks.

A call to open() should be flagged if the first argument (the directory or filename) is used earlier in a "check" category call.

opendir

Time and State

The opendir() function opens a directory stream corresponding to the directory name and returns a pointer to the directory stream. The stream is positioned at the first entry in the directory.

opendir() is vulnerable to TOCTOU attacks.

A call to opendir() should be flagged if the argument (the directory name) is used previously in a "check" category call.

openlog

Time and State

Can lead to Process/File interaction race conditions (TOCTOU category B).

pathconf

Time and State

The pathconf function is used to provide methods for the application to determine the current value of a configurable limit or option that is associated with a file or directory. The first input is the name of a file or directory, and the second input is a constant that represents the configurable system limit or option to be returned.

pathconf() is vulnerable to TOCTOU attacks. The existence of a call to this function should unilaterally be flagged.

pathfind

Time and State

Can lead to Process/File interaction race conditions (TOCTOU problems).

popen

Encapsulation

Path-searching exec functions are susceptible to malicious programs inserted into the search path.

The APIs execlp, execvp, popen, and system are usually implemented through a shell or exhibit shell-like characteristics. If user input can affect the arguments to the function, a malicious user could change or add commands to be run.

These functions search the path if a full path to the program is not specified. When using these functions, always specify the full path to the program. The Windows _exec and system family of functions is also vulnerable in the same manner. Also be sure to include the file extension (.exe, .com, .bat) to prevent unwanted matches.

printf

Input Validation and Representation

The printf family of functions is susceptible to a variety of format string and buffer overflow attacks. Flag any instance of the printf() family of functions in the code. Determine whether or not the format string is being provided through some input channel. If it is using a single argument, this is a definite vulnerability. Replace the code with the "fix" section.

If the first argument is a string literal constant, this rule does not apply.

If the first argument is a variable string, try to determine if it is user supplied. If so, it will be more difficult to determine whether it is vulnerable to the threat or not. If it is influenced by any data that comes into the current function, it should be flagged as a (potentially false positive) vulnerability.

All of these functions have potential format string problems. Some (as marked) also have potential BO problems when they write their output to strings.

rand random

Security Feature

The random function is a Linear Congruential Generator (LCG) used to create pseudorandom integers. That by itself is not a security issue. However, how the numbers are used can be a problem. The algorithm that generates the numbers is well known, the range of numbers generated is very small (in a cryptographic context), and the generated numbers can be guessed with reasonable ease. Hence, if the pseudorandom numbers are used as the basis for encryption computations, then it becomes a security problem. There is simply not enough randomness or entropy in pseudorandom numbers generated by LCGs for them to be used in high-security encryption.

read

Input Validation and Representation

The read function attempts to read nbyte bytes from the file associated with the open file descriptor, fildes, into the buffer pointed to by buf.

If nbyte is 0, read will return 0 and have no other results.

On files that support seeking (e.g., a regular file), the read starts at a position in the file given by the file offset associated with fildes. The file offset is incremented by the number of bytes actually read.

Files that do not support seeking (e.g., terminals) always read from the current position. The value of a file offset associated with such a file is undefined.

If fildes refers to a socket, read is equivalent to recv (3SOCKET) with no flags set.

No data transfer will occur past the current end-of-file. If the starting position is at or after the end-of-file, 0 will be returned. If the file refers to a device special file, the result of subsequent read requests is implementation-dependent.

If the value of nbyte is greater than SSIZE_MAX, the result is implementation-dependent.

The developer must ensure that the buffer is large enough to hold the number of bytes read. This is most commonly a problem when an input file stream contains a "count" for number of bytes to follow. If the attacker can corrupt this and specify a number of bytes significantly larger than the amount of buffer space available, the attacker could overrun a buffer.

readlink

Time and State

Can lead to Process/File interaction race conditions (TOCTOU category A).

realpath

Input Validation and Representation plus Time and State

realpath expands all symbolic links and resolves references to '/./', '/../', and extra '/' characters in the null-terminated string named by path and stores the canonicalized absolute pathname in the buffer of size PATH_MAX named by resolved_path. The resulting path will have no symbolic link, '/./', or '/../' components.

Never use this function (or do so at very high potential risk). It is broken by design since it is impossible to determine a suitable size for the output buffer. According to POSIX a buffer of size PATH_MAX suffices, but PATH_MAX need not be a defined constant and may have to be obtained using pathconf(). And asking pathconf() does not really help, since on the one hand, POSIX warns that the result of pathconf() may be huge and unsuitable for mallocing memory. And on the other hand, pathconf() may return -1 to signify that PATH_MAX is not bounded.

The libc4 and libc5 implementation contains a buffer overflow (fixed in libc-5.4.13). Thus, suid programs like mount need a private version.

recv recvfrom recvmsg

Input Validation and Representation

May receive input from untrusted source. May cause buffer overflow.

remove

Time and State

The remove() function makes a file/directory inaccessible by that name. An attempt to open that file/directory using that name does not work unless you recreate it. If the file is open, the subroutine does not remove it.

If the file has multiple links, the link count of files linked to the removed file is reduced by 1.

For files, remove() is identical to unlink(). For directories, remove() is identical to rmdir().

remove() is vulnerable to TOCTOU attacks.

A call to remove() should be flagged if the first argument (the directory or filename) is used earlier in a "check" category call.

rename

Time and State

The rename() function changes the name of a file. The old argument points to the pathname of the file to be renamed. The new argument points to the new pathname of the file.

If old and new both refer to the same existing file, the rename() function returns successfully and performs no other action.

If old points to the pathname of a file that is not a directory, new must not point to the pathname of a directory. If the link named by new exists, it will be removed and old will be renamed to new. In this case, a link named new must remain visible to other processes throughout the renaming operation and will refer to either the file referred to by new or the file referred to as old before the operation began.

If old points to the pathname of a directory, new must not point to the pathname of a file that is not a directory. If the directory named by new exists, it will be removed and old will be renamed to new. In this case, a link named new will exist throughout the renaming operation and will refer to either the file referred to by new or the file referred to as old before the operation began. Thus, if new names an existing directory, it must be an empty directory.

The new pathname must not contain a path prefix that names old. Write access permission is required for both the directory containing old and the directory containing new. If old points to the pathname of a directory, write access permission is required for the directory named by old, and, if it exists, the directory named by new.

If the directory containing old has the sticky bit set, at least one of the following conditions must be true:

  • The user must own old.

  • The user must own the directory containing old.

  • Old must be writable by the user.

A call to rename() should be flagged if either argument is referenced earlier in a "check" category call.

rmdir rmdirp

Time and State

The rmdir function attempts to remove a directory. It is generally vulnerable to classic TOCTOU attacks.

A call to rmdir() should be flagged if the first argument (the directory) is used earlier in a "check" category call.

scandir

Time and State

The scandir() function scans the directory dir, calling filter() on each directory entry. Entries for which filter() returns non-zero are stored in strings allocated via malloc(); sorted using qsort() with the comparison function compar(); and collected in array namelist, which is allocated via malloc(). If filter is NULL, all entries are selected.

The alphasort() and versionsort() functions can be used as the comparison function compar(). The former sorts directory entries using strcoll(3); the latter using strverscmp(3) on the strings (*a)->d_name and (*b)->d_name.

This function is in essence a TOCTOU security vulnerability. It can be used to return information about the directory structure of a system. If an attacker can select the value of dirname (due to the classic "check"/"use" scenario), then it is possible for the attacker to determine what directories exist on a system.

A call to scandir() should be flagged if the argument (the directory name) is used previously in a "check" category call.

scanf

Input Validation and Representation

The scanf family of functions scans input according to a format as described below. This format may contain conversion specifiers; the results from such conversions, if any, are stored through the pointer arguments. The scanf function reads input from the standard input stream stdin, fscanf reads input from the stream pointer stream, and sscanf reads its input from the character string pointed to by str.

The vulnerability of the scanf() function resides in the fact that it has no bounds-checking capability. If the string that is being accepted is longer than the buffer size, the characters will overflow into the adjoining memory space. This is a classic buffer overflow security vulnerability problem.

The scanf() function is susceptible to buffer overflow.

select

Input Validation and Representation

Adding a +1 to MAX_FDS can cause a 1-bit heap overflow.

snprintf

Input Validation and Representation

Many functions are susceptible to off-by-one and bounds-checking errors.

There are many generic types of errors that can apply to usage of a wide variety of functions.

These include:

  • Using a function that does not permit one to specify the size of a buffer to prevent overflows.

  • Mis-specifying the size of a buffer or the amount of data to be written. Off-by-one errors are common.

  • Failing to plan for correct behavior when input is larger than expected.

  • Failing to allow space for a terminating null character.

  • Failing to ensure that a terminating null character is present; many standard functions consistently experience this failure.

  • Specifying the size of a buffer or the amount of data to be transferred using incorrect units. This is particularly a problem with multibyte strings. On the Windows platform, these functions tend to include a "W" in the name.

  • Assuming the wrong semantics for a parameter that controls data transfer and prevents buffer overflows. Because various functions use the buffer size, buffer size minus one, the remaining space in the buffer, etc., it is important to understand the bounding semantics for each function.

Note that while some functions, such as strcpy(), are intrinsically dangerous, even the "safe" functions like strncpy() are still susceptible to subtle errors if bounds checks are not done properly.

socket

API Abuse

Watch for cases when root process allows its children to inherit privilege. An inherited socket could enable privileged connections from untrusted machines.

sprintf

Input Validation and Representation

The sprintf function is used to build strings by embedding format field specifiers in a string and having the data converted into the equivalent string form and then substituted for the specifier.

{v} sprintf() is susceptible to buffer overflow if used improperly. Mark any instance of vsprintf() and sprintf() as vulnerabilities. Replace calls with {v} snprintf() or change the format string.

Check the format string to see if it includes "%.111s" formatting limit.

The return result of sprintf() tells how many characters were actually written. If the number of chars is larger than the original buffer, that means memory has been overwritten and the program state is invalid.

srand srand48

Security Feature

The random function is a Linear Congruential Generator (LCG) used to create pseudorandom integers. That by itself is not a security issue. However, how the numbers are used can be a problem. The algorithm that generates the numbers is well known, the range of numbers generated is very small (in a cryptographic context), and the generated numbers can be guessed with reasonable ease. Hence, if the pseudorandom numbers are used as the basis for encryption computations, then it becomes a security problem. There is simply not enough randomness or entropy in pseudorandom numbers generated by LCGs for them to be used in high-security encryption.

sscanf

Input Validation and Representation

The scanf family of functions scans input according to a format as described below. This format may contain conversion specifiers; the results from such conversions, if any, are stored through the pointer arguments. The scanf function reads input from the standard input stream stdin, fscanf reads input from the stream pointer stream, and sscanf reads its input from the character string pointed to by str.

The vulnerability of the scanf() function resides in the fact that it has no bounds-checking capability. If the string that is being accepted is longer than the buffer size, the characters will overflow into the adjoining memory space. This is a classic buffer overflow security vulnerability problem.

The scanf() function is susceptible to buffer overflow.

stat

Time and State

The stat() function obtains information about the file pointed to by path. Read, write, or execute permission of the named file is not required, but all of the directories listed in the pathname leading to the file must be searchable.

lstat() is like stat() except in the case where the named file is a symbolic link, in which case lstat() returns information about the link, while stat() returns information about the file the link references.

fstat() obtains the same information about an open file known by the file descriptor fd.

stat() is used in combination with other functions that manipulate the file being queried (e.g., mkdir is vulnerable to TOCTOU attacks).

A call to stat() should be flagged if the first argument (the directory name) is used later in a use category call.

statvfs

Time and State

Can lead to Process/File interaction race conditions (TOCTOU).

strcadd

Input Validation and Representation

Low risk of buffer overflows.

strcat

Input Validation and Representation

The strcat() function is unsafe and should not be used.

The strcat() function will concatenate two strings by placing the second input on the end of the first. If the space in the first buffer is not capable of storing both strings, the data of the second string will overflow into the adjacent memory space.

strccpy

Input Validation and Representation

Many functions are susceptible to off-by-one and bounds-checking errors.

There are many generic types of errors that can apply to usage of a wide variety of functions.

These include:

  • Using a function that does not permit one to specify the size of a buffer to prevent overflows.

  • Mis-specifying the size of a buffer or the amount of data to be written. Off-by-one errors are common.

  • Failing to plan for correct behavior when input is larger than expected.

  • Failing to allow space for a terminating null character.

  • Failing to ensure that a terminating null character is present; many standard functions consistently experience this failure.

  • Specifying the size of a buffer or the amount of data to be transferred using incorrect units. This is particularly a problem with multibyte strings. On the Windows platform, these functions tend to include a "W" in the name.

  • Assuming the wrong semantics for a parameter that controls data transfer and prevents buffer overflows. Because various functions use the buffer size, buffer size minus one, the remaining space in the buffer, etc., it is important to understand the bounding semantics for each function.

Note that while some functions, such as strcpy(), are intrinsically dangerous, even the "safe" functions like strncpy() are still susceptible to subtle errors if bounds checks are not done properly.

strcpy

Input Validation and Representation

The string copy library functions are vulnerable to buffer overflow attack.

strcpy() is the classic buffer overflow attack. Any variant of strcpy or any routine that behaves like it, copying a C-string from one buffer to another, is vulnerable to the same misuse and attack patterns.

The destination buffer must be big enough to hold the source string plus the null (\0) terminating character. Even if the destination buffer is large enough, there is a chance that the source buffer might not be null terminated and thus might overrun. Many of the string copy functions do not check buffer sizes and simply look for a null character to determine end of input. This gives an attacker an opportunity to send input larger than the buffer size, overflowing the buffer. The attacker can exploit this to implement a denial-of-service (DoS) or buffer overflow attack.

streadd strecpy

Input Validation and Representation

The strecpy() and streadd() functions are dangerous unless care is taken to allocate a large enough output buffer.

The strecpy(char *theTarget, const char *theSource, const char *exceptions) function is used to copy an input string into a target, expanding nongraphic characters to their escape sequence representations. The string is copied until a null byte is encountered. The third argument is a list of characters that are not to be expanded. A pointer to the first byte of the target buffer is returned.

This function is a security risk because there is the potential to overflow the target buffer. The risk for this function is greater than that for the functions that compress because a simple test of the size of the source string is not enough to guarantee that the target is large enough.

strncpy

Input Validation and Representation

Many functions are susceptible to off-by-one and bounds-checking errors.

There are many generic types of errors that can apply to usage of a wide variety of functions.

These include:

  • Using a function that does not permit one to specify the size of a buffer to prevent overflows.

  • Mis-specifying the size of a buffer or the amount of data to be written. Off-by-one errors are common.

  • Failing to plan for correct behavior when input is larger than expected.

  • Failing to allow space for a terminating null character.

  • Failing to ensure that a terminating null character is present; many standard functions consistently experience this failure.

  • Specifying the size of a buffer or the amount of data to be transferred using incorrect units. This is particularly a problem with multibyte strings. On the Windows platform, these functions tend to include a "W" in the name.

  • Assuming the wrong semantics for a parameter that controls data transfer and prevents buffer overflows. Because various functions use the buffer size, buffer size minus one, the remaining space in the buffer, etc., it is important to understand the bounding semantics for each function.

Note that while some functions, such as strcpy(), are intrinsically dangerous, even the "safe" functions like strncpy() are still susceptible to subtle errors if bounds checks are not done properly.

strtrns

Input Validation and Representation

The strtrns function will take currentString and replace every instance of oldsegment with newsegment. The constructed string will be placed in newString.

This function is a security risk because it is possible to overflow the newString buffer. If the currentString buffer is larger than the newString buffer, then an overflow will occur.

Flag all instances of strtrns() as a potential vulnerability.

Identify bounds checks for the function.

swprintf

Input Validation and Representation

The printf family of functions is susceptible to a variety of format string and buffer overflow attacks. Flag any instance of the printf() family of functions in the code. Determine whether or not the format string is being provided through some input channel. If it is using a single argument, this is a definite vulnerability. Replace the code with the "fix" section.

If the first argument is a string literal constant, this rule does not apply.

If the first argument is a variable string, try to determine if it is user supplied. If so, it will be more difficult to determine whether it is vulnerable to the threat or not. If it is influenced by any data that comes into the current function, it should be flagged as a (potentially false positive) vulnerability.

All of these functions have potential format string problems. Some (as marked) also have potential BO problems when they write their output to strings.

symlink

Time and State

Can lead to Process/File interaction race conditions (TOCTOU Category A).

syslog

Input Validation and Representation

syslog() has internal buffer limitations, so size of input should be bounded.

syslog() is used to log system messages. It has internal buffer limitations that are implementation dependent.

system

Encapsulation

Path-searching exec functions are susceptible to malicious programs inserted into the search path.

The APIs execlp, execvp, popen, and system are usually implemented through a shell or exhibit shell-like characteristics. If user input can affect the arguments to the function, a malicious user could change or add commands to be run.

These functions search the path if a full path to the program is not specified. When using these functions, always specify the full path to the program. The Windows _exec and system family of functions is also vulnerable in the same manner. Also be sure to include the file extension (.exe, .com, .bat) to prevent unwanted matches.

t_open

Time and State

The first step in initializing a transport endpoint. Watch for sensitive data going to untrusted parties.

tempnam

Time and State

Incorrect temporary file usage can lead to TOCTOU and accessibility vulnerabilities. A call to tmpfile should be flagged.

Temporary filenames created by the tmpnam family of functions can be easily guessed by an attacker.

tmpfile

Time and State

Incorrect temporary file usage can lead to TOCTOU and accessibility vulnerabilities. A call to tmpfile should be flagged.

tmpnam

Time and State

Incorrect temporary file usage can lead to TOCTOU and accessibility vulnerabilities. A call to tmpfile should be flagged.

Temporary filenames created by the tmpnam family of functions can be easily guessed by an attacker.

tmpnam_r

Time and State

Temporary filenames created by the tmpnam family of functions can be easily guessed by an attacker.

TRuncate

Time and State

Can lead to Process/File interaction race conditions (TOCTOU problems).

ttyname

API Abuse

It is possible to return a nonterminated string.

umask

Encapsulation

Setting a liberal umask can be bad when you exec an untrusted process.

umount

Time and State

Can lead to Process/File interaction race conditions (TOCTOU CATEGORY A).

unlink

Time and State

The unlink() function removes a link to a file. If path names a symbolic link, unlink() removes the symbolic link named by path and does not affect any file or directory named by the contents of the symbolic link. Otherwise, unlink() removes the link named by the pathname pointed to by path and decrements the link count of the file referenced by the link.

The unlinkat() function also removes a link to a file. See fsattr(5). If the flag argument is 0, the behavior of unlinkat() is the same as unlink() except in the processing of its path argument. If path is absolute, unlinkat() behaves the same as unlink() and the dirfd argument is unused. If path is relative and dirfd has the value AT_FDCWD, defined in <fcntl.h>, unlinkat() also behaves the same as unlink(). Otherwise, path is resolved relative to the directory referenced by the dirfd argument.

If the flag argument is set to the value AT_REMOVEDIR, defined in <fcntl.h>, unlinkat() behaves the same as rmdir(2) except in the processing of the path argument as described above.

When the file's link count becomes 0 and no process has the file open, the space occupied by the file will be freed and the file is no longer accessible. If one or more processes have the file open when the last link is removed, the link is removed before unlink() or unlinkat() returns, but the removal of the file contents is postponed until all references to the file are closed.

The path argument must not name a directory unless the process has appropriate privileges and the implementation supports using unlink() and unlinkat() on directories.

Upon successful completion, unlink() and unlinkat() will mark for update the st_ctime and st_mtime fields of the parent directory. If the file's link count is not 0, the st_ctime field of the file will be marked for update.

utime utimes

Time and State

Changes timestamps. Watch use by setuid or setgid programs.

utmpname utmpxname

Time and State

Any setuid program that runs as root or other authorized user can modify location of the files.

vfscanf

Input Validation and Representation

The scanf family of functions scans input according to a format as described below. This format may contain conversion specifiers; the results from such conversions, if any, are stored through the pointer arguments. The scanf function reads input from the standard input stream stdin, fscanf reads input from the stream pointer stream, and sscanf reads its input from the character string pointed to by str.

The vulnerability of the scanf() function resides in the fact that it has no bounds-checking capability.

If the string that is being accepted is longer than the buffer size, the characters will overflow into the adjoining memory space. This is a classic buffer overflow security vulnerability problem.

The scanf() function is susceptible to buffer overflow.

vfwprintf

Input Validation and Representation

The printf family of functions is susceptible to a variety of format string and buffer overflow attacks. Flag any instance of the printf() family of functions in the code. Determine whether or not the format string is being provided through some input channel. If it is using a single argument, this is a definite vulnerability. Replace the code with the "fix" section.

If the first argument is a string literal constant, this rule does not apply.

If the first argument is a variable string, try to determine if it is user supplied. If so, it will be more difficult to determine whether it is vulnerable to the threat or not. If it is influenced by any data that comes into the current function, it should be flagged as a (potentially false positive) vulnerability.

All of these functions have potential format string problems. Some (as marked) also have potential BO problems when they write their output to strings.

vscanf

Input Validation and Representation

The scanf family of functions scans input according to a format as described below. This format may contain conversion specifiers; the results from such conversions, if any, are stored through the pointer arguments. The scanf function reads input from the standard input stream stdin, fscanf reads input from the stream pointer stream, and sscanf reads its input from the character string pointed to by str.

The vulnerability of the scanf() function resides in the fact that it has no bounds-checking capability. If the string that is being accepted is longer than the buffer size, the characters will overflow into the adjoining memory space. This is a classic buffer overflow security vulnerability problem.

The scanf() function is susceptible to buffer overflow.

vsnprintf

Input Validation and Representation

Many functions are susceptible to off-by-one and bounds-checking errors.

There are many generic types of errors that can apply to usage of a wide variety of functions.

These include:

  • Using a function that does not permit one to specify the size of a buffer to prevent overflows.

  • Mis-specifying the size of a buffer or the amount of data to be written. Off-by-one errors are common.

  • Failing to plan for correct behavior when input is larger than expected.

  • Failing to allow space for a terminating null character.

  • Failing to ensure that a terminating null character is present; many standard functions consistently experience this failure.

  • Specifying the size of a buffer or the amount of data to be transferred using incorrect units. This is particularly a problem with multibyte strings. On the Windows platform, these functions tend to include a "W" in the name.

  • Assuming the wrong semantics for a parameter that controls data transfer and prevents buffer overflows. Because various functions use the buffer size, buffer size minus one, the remaining space in the buffer, etc., it is important to understand the bounding semantics for each function.

Note that while some functions, such as strcpy(), are intrinsically dangerous, even the "safe" functions like strncpy() are still susceptible to subtle errors if bounds checks are not done properly.

vsprintf

Input Validation and Representation

The sprintf function is used to build strings by embedding format field specifiers in a string and having the data converted into the equivalent string form and then substituted for the specifier.

{v}sprintf() is susceptible to buffer overflow if used improperly. Mark any instance of vsprintf() and sprintf() as vulnerabilities. Replace calls with{v}snprintf() or change the format string.

Check the format string to see if it includes "%.111s" formatting limit.

vsscanf

Input Validation and Representation

The return result of sprintf() tells how many characters were actually written. If the number of chars is larger than the original buffer, that means memory has been overwritten and the program state is invalid.

The scanf family of functions scans input according to a format as described below. This format may contain conversion specifiers; the results from such conversions, if any, are stored through the pointer arguments. The scanf function reads input from the standard input stream stdin, fscanf reads input from the stream pointer stream, and sscanf reads its input from the character string pointed to by str.

The vulnerability of the scanf() function resides in the fact that it has no bounds-checking capability. If the string that is being accepted is longer than the buffer size, the characters will overflow into the adjoining memory space. This is a classic buffer overflow security vulnerability problem.

The scanf() function is susceptible to buffer overflow.

vswprintf

Input Validation and Representation

The printf family of functions is susceptible to a variety of format string and buffer overflow attacks. Flag any instance of the printf() family of functions in the code. Determine whether or not the format string is being provided through some input channel. If it is using a single argument, this is a definite vulnerability. Replace the code with the "fix" section.

If the first argument is a string literal constant, this rule does not apply.

If the first argument is a variable string, try to determine if it is user supplied. If so, it will be more difficult to determine whether it is vulnerable to the threat or not. If it is influenced by any data that comes into the current function, it should be flagged as a (potentially false positive) vulnerability.

All of these functions have potential format string problems. Some (as marked) also have potential BO problems when they write their output to strings.

vwprintf

Input Validation and Representation

NON-CONSTANT FORMAT STRINGS can often be attacked.

wprintf

Input Validation and Representation

The printf family of functions is susceptible to a variety of format string and buffer overflow attacks. Flag any instance of the printf() family of functions in the code. Determine whether or not the format string is being provided through some input channel. If it is using a single argument, this is a definite vulnerability. Replace the code with the "fix" section.

If the first argument is a string literal constant, this rule does not apply.

If the first argument is a variable string, try to determine if it is user supplied. If so, it will be more difficult to determine whether it is vulnerable to the threat or not. If it is influenced by any data that comes into the current function, it should be flagged as a (potentially false positive) vulnerability.

All of these functions have potential format string problems. Some (as marked) also have potential BO problems when they write their output to strings.


As you can see by perusing this list, the kind of information that a simple tool gives back is valuable but not very useful as a large list. Using a tool to look for the myriad possible problems is really the only way to go.

Modern static analysis tools use much better techniques and much more thorough analyses than yesteryear's grep-based scanners like ITS4 and RATS. Nevertheless, the ruleset that was included in ITS4 is still applicable. The knowledge itself ages well. All static analysis tools should provide coverage on this basic ruleset. If your static analysis tool doesn't, you should get a new one.

Many more static analysis rules are available on the Building Security In portal from the U.S. Department of Homeland Security <http://buildsecurityin.us-cert.gov/portal/>.




Software Security. Building Security In
Software Security: Building Security In
ISBN: 0321356705
EAN: 2147483647
Year: 2004
Pages: 154
Authors: Gary McGraw

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net