Input/Output is a broad topic and includes all the functions defined in C99 Section 7.19, Input/output <stdio.h>" and related functions.
The security of I/O operations is dependent on the versions of the C library, the operating system, and the file system. Older libraries are generally more susceptible to security flaws than newer library versions. Different operating systems have different capabilities and mechanisms for managing file privileges. There are numerous different file systems, including: File Allocation Table (FAT), FAT32, New Technology File System (NTFS), NetWare File System (NWFS), and the Unix File System (UFS). There are also many distributed file systems including: Andrew File System (AFS), Distributed File System (DFS), Microsoft DFS, and Network File System (NFS). These file systems vary in their capabilities and privilege mechanisms.
As a starting point, the I/O topic area describes the use of C99 standard functions. However, because these functions have been generalized to support multiple disparate operating and file systems, they cannot generally be used in a secure fashion. As a result, most of the rules and recommendations in this topic area recommend approaches that are specific to the operating system and file systems in use. Because of the inherent complexity, there may not exist compliant solutions for all operating system and file system combinations. Therefore, the applicability of the rules for the target operating system/file system combinations should be considered.
Recommendations
FIO00-A. Take care when creating format strings
FIO01-A. Prefer functions that do not rely on file names for identification
FIO02-A. Canonicalize file names originating from untrusted sources
FIO03-A. Do not make assumptions about fopen() and file creation
FIO04-A. Detect and handle input and output errors
FIO05-A. Identify files using multiple file attributes
FIO06-A. Create files with appropriate access permissions
FIO07-A. Prefer fseek() to rewind()
FIO08-A. Take care when calling remove() on an open file
FIO09-A. fflush() should be called after writing to an output stream if data integrity is important
FIO10-A. Take care when using the rename() function
FIO11-A. Take care when specifying the mode parameter of fopen()
FIO12-A. Prefer setvbuf() to setbuf()
FIO13-A. Take care when using ungetc()
FIO14-A. Understand the difference between text mode and binary mode with file streams
FIO15-A. Avoid taking conditional actions based on path or file names
Rules
FIO30-C. Exclude user input from format strings
FIO31-C. Do not simultaneously open the same file multiple times
FIO32-C. Detect and handle file operation errors
FIO33-C. Detect and handle input output errors resulting in undefined behavior
FIO34-C. Use int to capture the return value of character IO functions
FIO35-C. Use feof() and ferror() to detect end-of-file and file errors
FIO36-C. Do not assume a newline character is read when using fgets()
FIO37-C. Don't assume character data has been read
FIO38-C. Do not use a copy of a FILE object for input and output
FIO39-C. Do not read in from a stream directly following output to that stream
FIO40-C. Reset strings on fgets() failure
FIO41-C. Do not call getc() or putc() with arguments that have side effects
FIO42-C. Ensure files are properly closed when they are no longer needed
FIO43-C. Do not copy data from an unbounded source to a fixed-length array
FIO44-C. Only use values for fsetpos() that are returned from fgetpos()
FIO45-C. Do not reopen a file stream
FIO46-C. Do not perform operations on devices that are only appropriate for files
Risk Assessment Summary
Recommendations
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
FIO00-A |
1 (low) |
1 (unlikely) |
2 (medium) |
P2 |
L3 |
FIO01-A |
2 (medium) |
2 (probable) |
1 (high) |
P4 |
L3 |
FIO02-A |
2 (medium) |
1 (unlikely) |
1 (high) |
P2 |
L3 |
FIO03-A |
2 (medium) |
2 (probable) |
1 (high) |
P4 |
L3 |
FIO04-A |
2 (medium) |
2 (probable) |
1 (high) |
P4 |
L3 |
FIO05-A |
2 (medium) |
2 (probable) |
2 (medium) |
P8 |
L2 |
FIO06-A |
2 (medium) |
1 (unlikely) |
2 (medium) |
P4 |
L3 |
FIO07-A |
1 (low) |
1 (unlikely) |
2 (medium) |
P2 |
L3 |
FIO08-A |
2 (medium) |
1 (unlikely) |
2 (medium) |
P4 |
L3 |
FIO09-A |
2 (medium) |
1 (unlikely) |
2 (medium) |
P4 |
L3 |
FIO10-A |
2 (medium) |
2 (probable) |
2 (medium) |
P8 |
L2 |
FIO11-A |
1 (low) |
2 (probable) |
3 (low) |
P6 |
L2 |
FIO12-A |
1 (low) |
1 (unlikely) |
2 (medium) |
P2 |
L3 |
FIO13-A |
2 (medium) |
2 (probable) |
1 (high) |
P4 |
L3 |
FIO14-A |
1 (low) |
2 (probable) |
2 (medium) |
P4 |
L3 |
Rules
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
FIO30-C |
3 (high) |
3 (likely) |
3 (low) |
P27 |
L1 |
FIO31-C |
2 (medium) |
2 (probable) |
2 (medium) |
P8 |
L2 |
FIO32-C |
2 (medium) |
1 (unlikely) |
2 (medium) |
P4 |
L3 |
FIO33-C |
1 (low) |
1 (unlikely) |
3 (low) |
P3 |
L3 |
FIO34-C |
3 (high) |
2 (probable) |
2 (medium) |
P12 |
L1 |
FIO35-C |
1 (low) |
1 (unlikely) |
2 (medium) |
P2 |
L3 |
FIO33-C |
3 (high) |
1 (unlikely) |
2 (medium) |
P6 |
L2 |
FIO37-C |
3 (high) |
1 (unlikely) |
2 (medium) |
P6 |
L2 |
FIO36-C |
2 (medium) |
1 (unlikely) |
3 (low) |
P6 |
L2 |
FIO38-C |
1 (low) |
2 (probable) |
2 (medium) |
P4 |
L3 |
FIO39-C |
2 (medium) |
2 (probable) |
2 (medium) |
P8 |
L2 |
FIO40-C |
1 (low) |
1 (unlikely) |
2 (medium) |
P2 |
L3 |
FIO41-C |
1 (low) |
1 (unlikely) |
2 (medium) |
P2 |
L3 |
FIO42-C |
2 (medium) |
1 (unlikely) |
2 (medium) |
P4 |
L3 |
FIO43-C |
3 (high) |
3 (likely) |
2 (medium) |
P18 |
L1 |
FIO44-C |
2 (medium) |
1 (unlikely) |
2 (medium) |
P4 |
L3 |
FIO45-C |
2 (medium) |
1 (unlikely) |
2 (medium) |
P4 |
L3 |