Skip to content

Commit f462156

Browse files
author
dilanbhalla
committed
private data file/buffer write
1 parent a2677f8 commit f462156

11 files changed

+247
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<include src="PrivateCleartextStorage.qhelp" /></qhelp>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* @name Cleartext storage of private data in buffer
3+
* @description Storing private data in cleartext can expose it
4+
* to an attacker.
5+
* @kind path-problem
6+
* @problem.severity warning
7+
* @precision medium
8+
* @id cpp/private-cleartext-storage-buffer
9+
* @tags security
10+
* external/cwe/cwe-312
11+
*/
12+
13+
import cpp
14+
import semmle.code.cpp.security.BufferWrite
15+
import semmle.code.cpp.security.TaintTracking
16+
import semmle.code.cpp.security.PrivateData
17+
import TaintedWithPath
18+
19+
class Configuration extends TaintTrackingConfiguration {
20+
override predicate isSink(Element tainted) { exists(BufferWrite w | w.getASource() = tainted) }
21+
}
22+
23+
from
24+
BufferWrite w, Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode,
25+
string taintCause, PrivateDataExpr dest
26+
where
27+
taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and
28+
isUserInput(taintSource, taintCause) and
29+
w.getASource() = taintedArg and
30+
dest = w.getDest()
31+
select w, sourceNode, sinkNode,
32+
"This write into buffer '" + dest.toString() + "' may contain unencrypted data from $@",
33+
taintSource, "user input (" + taintCause + ")"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<include src="PrivateCleartextStorage.qhelp" /></qhelp>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @name Cleartext storage of sensitive information in file
3+
* @description Storing sensitive information in cleartext can expose it
4+
* to an attacker.
5+
* @kind problem
6+
* @problem.severity warning
7+
* @precision medium
8+
* @id cpp/private-cleartext-storage-file
9+
* @tags security
10+
* external/cwe/cwe-313
11+
*/
12+
13+
import cpp
14+
import semmle.code.cpp.security.PrivateData
15+
import semmle.code.cpp.security.FileWrite
16+
17+
from FileWrite w, PrivateDataExpr source, Expr dest
18+
where
19+
source = w.getASource() and
20+
dest = w.getDest()
21+
select w, "This write into file '" + dest.toString() + "' may contain unencrypted data from $@",
22+
source, "this source."
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Private data that is stored unencrypted is accessible to an attacker who gains access to the
7+
storage.</p>
8+
9+
</overview>
10+
<recommendation>
11+
12+
<p>Ensure that private data is always encrypted before being stored, especially before writing to a file.
13+
It may be wise to encrypt information before it is put into a buffer that may be readable in memory.</p>
14+
15+
<p>In general, decrypt private data only at the point where it is necessary for it to be used in
16+
cleartext.</p>
17+
18+
</recommendation>
19+
20+
<references>
21+
22+
<li>M. Dowd, J. McDonald and J. Schuhm, <i>The Art of Software Security Assessment</i>, 1st Edition, Chapter 2 - 'Common Vulnerabilities of Encryption', p. 43. Addison Wesley, 2006.</li>
23+
<li>M. Howard and D. LeBlanc, <i>Writing Secure Code</i>, 2nd Edition, Chapter 9 - 'Protecting Secret Data', p. 299. Microsoft, 2002.</li>
24+
25+
26+
27+
<!-- LocalWords: CWE
28+
-->
29+
30+
</references>
31+
</qhelp>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Provides classes and predicates for identifying private data and functions for security.
3+
*
4+
* 'Private' data in general is anything that would compromise user privacy if exposed. This
5+
* library tries to guess where private data may either be stored in a variable or produced by a
6+
* function.
7+
*
8+
* This library is not concerned with credentials. See `SensitiveActions` for expressions related
9+
* to credentials.
10+
*/
11+
12+
import cpp
13+
14+
/** A string for `match` that identifies strings that look like they represent private data. */
15+
private string privateNames() {
16+
// Inspired by the list on https://cwe.mitre.org/data/definitions/359.html
17+
// Government identifiers, such as Social Security Numbers
18+
result = "%social%security%number%" or
19+
// Contact information, such as home addresses and telephone numbers
20+
result = "%postcode%" or
21+
result = "%zipcode%" or
22+
result = "%telephone%" or
23+
// Geographic location - where the user is (or was)
24+
result = "%latitude%" or
25+
result = "%longitude%" or
26+
// Financial data - such as credit card numbers, salary, bank accounts, and debts
27+
result = "%creditcard%" or
28+
result = "%salary%" or
29+
result = "%bankaccount%" or
30+
// Communications - e-mail addresses, private e-mail messages, SMS text messages, chat logs, etc.
31+
result = "%email%" or
32+
result = "%mobile%" or
33+
result = "%employer%" or
34+
// Health - medical conditions, insurance status, prescription records
35+
result = "%medical%"
36+
}
37+
38+
/** An expression that might contain private data. */
39+
abstract class PrivateDataExpr extends Expr { }
40+
41+
/** A functiond call that might produce private data. */
42+
class PrivateFunctionCall extends PrivateDataExpr, FunctionCall {
43+
PrivateFunctionCall() {
44+
exists(string s | this.getTarget().getName().toLowerCase() = s | s.matches(privateNames()))
45+
}
46+
}
47+
48+
/** An access to a variable that might contain private data. */
49+
class PrivateVariableAccess extends PrivateDataExpr, VariableAccess {
50+
PrivateVariableAccess() {
51+
exists(string s | this.getTarget().getName().toLowerCase() = s | s.matches(privateNames()))
52+
}
53+
}
54+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
edges
2+
| test.cpp:54:17:54:20 | argv | test.cpp:58:26:58:30 | input |
3+
| test.cpp:54:17:54:20 | argv | test.cpp:58:26:58:30 | input |
4+
| test.cpp:54:17:54:20 | argv | test.cpp:58:26:58:30 | input |
5+
| test.cpp:54:17:54:20 | argv | test.cpp:58:26:58:30 | input |
6+
nodes
7+
| test.cpp:54:17:54:20 | argv | semmle.label | argv |
8+
| test.cpp:54:17:54:20 | argv | semmle.label | argv |
9+
| test.cpp:58:26:58:30 | input | semmle.label | input |
10+
| test.cpp:58:26:58:30 | input | semmle.label | input |
11+
| test.cpp:58:26:58:30 | input | semmle.label | input |
12+
#select
13+
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:54:17:54:20 | argv | test.cpp:58:26:58:30 | input | This write into buffer 'medical' may contain unencrypted data from $@ | test.cpp:54:17:54:20 | argv | user input (argv) |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Security/CWE/CWE-359/PrivateCleartextBufferWrite.ql
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| test.cpp:45:3:45:7 | call to fputs | This write into file 'file' may contain unencrypted data from $@ | test.cpp:45:9:45:16 | theEmail | this source. |
2+
| test.cpp:70:32:70:32 | call to operator<< | This write into file 'mystream' may contain unencrypted data from $@ | test.cpp:70:35:70:42 | theEmail | this source. |
3+
| test.cpp:73:34:73:38 | call to write | This write into file 'mystream' may contain unencrypted data from $@ | test.cpp:73:40:73:47 | theEmail | this source. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Security/CWE/CWE-359/PrivateCleartextFileWrite.ql

0 commit comments

Comments
 (0)