Skip to content

Commit e7dca43

Browse files
authored
Merge pull request github#6950 from ihsinme/ihsinme-patch-078
CPP: Add query for CWE-200 Exposure of Sensitive Information to an Unauthorized Actor
2 parents 64b458b + 5c80139 commit e7dca43

12 files changed

+155
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
...
2+
FILE *fp = fopen(filename,"w"); // BAD
3+
...
4+
umask(S_IXUSR|S_IRWXG|S_IRWXO);
5+
FILE *fp;
6+
fp = fopen(filename,"w"); // GOOD
7+
chmod(filename,S_IRUSR|S_IWUSR);
8+
fprintf(fp,"%s\n","data to file");
9+
fclose(fp);
10+
...
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>When creating a file using a library function such as <code>fopen</code>, the access rights for the newly created file are not specified as part of the call. Instead these rights are determined by the system unless the programmer takes specific measures, such as calling the Posix <code>umask</code> function at some point before the call to <code>fopen</code>. For some applications, the default access rights assigned by the system are not sufficient to protect a file against access by an attacker.</p>
7+
8+
9+
</overview>
10+
11+
<example>
12+
<p>The following example demonstrates erroneous and fixed methods for working with files.</p>
13+
<sample src="ExposureSensitiveInformationUnauthorizedActor.cpp" />
14+
15+
</example>
16+
<references>
17+
18+
<li>
19+
CERT C Coding Standard:
20+
<a href="https://wiki.sei.cmu.edu/confluence/display/c/FIO06-C.+Create+files+with+appropriate+access+permissions">FIO06-C. Create files with appropriate access permissions</a>.
21+
</li>
22+
23+
</references>
24+
</qhelp>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* @name Writing to a file without setting permissions.
3+
* @description Lack of restriction on file access rights can be unsafe.
4+
* @kind problem
5+
* @id cpp/work-with-file-without-permissions-rights
6+
* @problem.severity warning
7+
* @precision medium
8+
* @tags correctness
9+
* maintainability
10+
* security
11+
* external/cwe/cwe-200
12+
* external/cwe/cwe-264
13+
*/
14+
15+
import cpp
16+
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
17+
18+
/** Holds for a function `f` that has an argument at index `apos` used to read the file. */
19+
predicate numberArgumentRead(Function f, int apos) {
20+
f.hasGlobalOrStdName("fgets") and apos = 2
21+
or
22+
f.hasGlobalOrStdName("fread") and apos = 3
23+
or
24+
f.hasGlobalOrStdName("read") and apos = 0
25+
or
26+
f.hasGlobalOrStdName("fscanf") and apos = 0
27+
}
28+
29+
/** Holds for a function `f` that has an argument at index `apos` used to write to file */
30+
predicate numberArgumentWrite(Function f, int apos) {
31+
f.hasGlobalOrStdName("fprintf") and apos = 0
32+
or
33+
f.hasGlobalOrStdName("fputs") and apos = 1
34+
or
35+
f.hasGlobalOrStdName("write") and apos = 0
36+
or
37+
f.hasGlobalOrStdName("fwrite") and apos = 3
38+
or
39+
f.hasGlobalOrStdName("fflush") and apos = 0
40+
}
41+
42+
from FunctionCall fc
43+
where
44+
// a file is opened
45+
(
46+
fc.getTarget().hasGlobalOrStdName("fopen") or
47+
fc.getTarget().hasGlobalOrStdName("open")
48+
) and
49+
fc.getNumberOfArguments() = 2 and
50+
// the file is used for writing (but not reading)
51+
exists(FunctionCall fctmp, int i |
52+
numberArgumentWrite(fctmp.getTarget(), i) and
53+
globalValueNumber(fc) = globalValueNumber(fctmp.getArgument(i))
54+
) and
55+
not exists(FunctionCall fctmp, int i |
56+
numberArgumentRead(fctmp.getTarget(), i) and
57+
globalValueNumber(fc) = globalValueNumber(fctmp.getArgument(i))
58+
) and
59+
// a file creation mode is not set globally by `umask` anywhere in the program
60+
not exists(FunctionCall fctmp |
61+
fctmp.getTarget().hasGlobalOrStdName("umask") or
62+
fctmp.getTarget().hasGlobalOrStdName("fchmod") or
63+
fctmp.getTarget().hasGlobalOrStdName("chmod")
64+
)
65+
select fc, "You may have forgotten to restrict access rights when working with a file."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.cpp:12:8:12:12 | call to fopen | You may have forgotten to restrict access rights when working with a file. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.ql
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
typedef int FILE;
2+
FILE *fopen(const char *filename, const char *mode);
3+
int umask(int pmode);
4+
int chmod(char * filename,int pmode);
5+
int fprintf(FILE *fp,const char *fmt, ...);
6+
int fclose(FILE *stream);
7+
8+
int main(int argc, char *argv[])
9+
{
10+
//umask(0022);
11+
FILE *fp;
12+
fp = fopen("myFile.txt","w"); // BAD
13+
//chmod("myFile.txt",0644);
14+
fprintf(fp,"%s\n","data to file");
15+
fclose(fp);
16+
return 0;
17+
}

cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test2/ExposureSensitiveInformationUnauthorizedActor.expected

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
experimental/Security/CWE/CWE-200/ExposureSensitiveInformationUnauthorizedActor.ql
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
typedef int FILE;
2+
FILE *fopen(const char *filename, const char *mode);
3+
int umask(int pmode);
4+
int chmod(char * filename,int pmode);
5+
int fprintf(FILE *fp,const char *fmt, ...);
6+
int fclose(FILE *stream);
7+
8+
int main(int argc, char *argv[])
9+
{
10+
umask(0022);
11+
FILE *fp;
12+
fp = fopen("myFile.txt","w"); // GOOD
13+
chmod("myFile.txt",0644);
14+
fprintf(fp,"%s\n","data to file");
15+
fclose(fp);
16+
return 0;
17+
}

cpp/ql/test/experimental/query-tests/Security/CWE/CWE-200/test3/ExposureSensitiveInformationUnauthorizedActor.expected

Whitespace-only changes.

0 commit comments

Comments
 (0)