Skip to content

Commit 146318d

Browse files
authored
Merge pull request #8580 from geoffw0/privdata
C++: Port PrivateData.qll from C# and use it in cpp/cleartext-transmission
2 parents 15c54f6 + e04298d commit 146318d

File tree

9 files changed

+233
-69
lines changed

9 files changed

+233
-69
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: feature
3+
---
4+
* A new library `semmle.code.cpp.security.PrivateData` has been added. The new library heuristically detects variables and functions dealing with sensitive private data, such as e-mail addresses and credit card numbers.

cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateCleartextWrite.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import cpp
66
import semmle.code.cpp.dataflow.TaintTracking
7-
import experimental.semmle.code.cpp.security.PrivateData
7+
import semmle.code.cpp.security.PrivateData
88
import semmle.code.cpp.security.FileWrite
99
import semmle.code.cpp.security.BufferWrite
1010

cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateData.qll

Lines changed: 0 additions & 52 deletions
This file was deleted.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* Provides classes for heuristically identifying variables and functions that
3+
* might contain or return sensitive private data.
4+
*
5+
* 'Private' data in general is anything that would compromise user privacy if
6+
* exposed. This library tries to guess where private data may either be stored
7+
* in a variable or returned by a function call.
8+
*
9+
* This library is not concerned with credentials. See `SensitiveExprs.qll` for
10+
* expressions related to credentials.
11+
*/
12+
13+
import cpp
14+
15+
/**
16+
* A string for `regexpMatch` that identifies strings that look like they
17+
* represent private data.
18+
*/
19+
private string privateNames() {
20+
result =
21+
".*(" +
22+
// Inspired by the list on https://cwe.mitre.org/data/definitions/359.html
23+
// Government identifiers, such as Social Security Numbers
24+
"social.?security|" +
25+
// Contact information, such as home addresses and telephone numbers
26+
"post.?code|zip.?code|telephone|" +
27+
// Geographic location - where the user is (or was)
28+
"latitude|longitude|" +
29+
// Financial data - such as credit card numbers, salary, bank accounts, and debts
30+
"credit.?card|salary|bank.?account|" +
31+
// Communications - e-mail addresses, private e-mail messages, SMS text messages, chat logs, etc.
32+
"email|mobile|employer|" +
33+
// Health - medical conditions, insurance status, prescription records
34+
"medical" +
35+
// ---
36+
").*"
37+
}
38+
39+
/**
40+
* A variable that might contain sensitive private information.
41+
*/
42+
class PrivateDataVariable extends Variable {
43+
PrivateDataVariable() {
44+
this.getName().toLowerCase().regexpMatch(privateNames()) and
45+
not this.getUnspecifiedType() instanceof IntegralType
46+
}
47+
}
48+
49+
/**
50+
* A function that might return sensitive private information.
51+
*/
52+
class PrivateDataFunction extends Function {
53+
PrivateDataFunction() {
54+
this.getName().toLowerCase().regexpMatch(privateNames()) and
55+
not this.getUnspecifiedType() instanceof IntegralType
56+
}
57+
}
58+
59+
/**
60+
* An expression whose value might be sensitive private information.
61+
*/
62+
class PrivateDataExpr extends Expr {
63+
PrivateDataExpr() {
64+
this.(VariableAccess).getTarget() instanceof PrivateDataVariable or
65+
this.(FunctionCall).getTarget() instanceof PrivateDataFunction
66+
}
67+
}

cpp/ql/lib/semmle/code/cpp/security/SensitiveExprs.qll

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
/**
22
* Provides classes for heuristically identifying variables and functions that
3-
* might contain or return a password or other sensitive information.
3+
* might contain or return a password or other credential.
4+
*
5+
* This library is not concerned with other kinds of sensitive private
6+
* information. See `PrivateData.qll` for expressions related to that.
47
*/
58

69
import cpp
710

811
/**
912
* Holds if the name `s` suggests something might contain or return a password
10-
* or other sensitive information.
13+
* or other credential.
1114
*/
1215
bindingset[s]
1316
private predicate suspicious(string s) {
@@ -16,7 +19,7 @@ private predicate suspicious(string s) {
1619
}
1720

1821
/**
19-
* A variable that might contain a password or other sensitive information.
22+
* A variable that might contain a password or other credential.
2023
*/
2124
class SensitiveVariable extends Variable {
2225
SensitiveVariable() {
@@ -26,7 +29,7 @@ class SensitiveVariable extends Variable {
2629
}
2730

2831
/**
29-
* A function that might return a password or other sensitive information.
32+
* A function that might return a password or other credential.
3033
*/
3134
class SensitiveFunction extends Function {
3235
SensitiveFunction() {
@@ -36,7 +39,7 @@ class SensitiveFunction extends Function {
3639
}
3740

3841
/**
39-
* An expression whose value might be a password or other sensitive information.
42+
* An expression whose value might be a password or other credential.
4043
*/
4144
class SensitiveExpr extends Expr {
4245
SensitiveExpr() {

cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,43 @@
99
* @id cpp/cleartext-transmission
1010
* @tags security
1111
* external/cwe/cwe-319
12+
* external/cwe/cwe-359
1213
*/
1314

1415
import cpp
1516
import semmle.code.cpp.security.SensitiveExprs
17+
import semmle.code.cpp.security.PrivateData
1618
import semmle.code.cpp.dataflow.TaintTracking
1719
import semmle.code.cpp.models.interfaces.FlowSource
1820
import semmle.code.cpp.commons.File
1921
import DataFlow::PathGraph
2022

23+
class SourceVariable extends Variable {
24+
SourceVariable() {
25+
this instanceof SensitiveVariable or
26+
this instanceof PrivateDataVariable
27+
}
28+
}
29+
30+
class SourceFunction extends Function {
31+
SourceFunction() {
32+
this instanceof SensitiveFunction or
33+
this instanceof PrivateDataFunction
34+
}
35+
}
36+
2137
/**
2238
* A DataFlow node corresponding to a variable or function call that
2339
* might contain or return a password or other sensitive information.
2440
*/
25-
class SensitiveNode extends DataFlow::Node {
26-
SensitiveNode() {
27-
this.asExpr() = any(SensitiveVariable sv).getInitializer().getExpr() or
28-
this.asExpr().(VariableAccess).getTarget() =
29-
any(SensitiveVariable sv).(GlobalOrNamespaceVariable) or
30-
this.asExpr().(VariableAccess).getTarget() = any(SensitiveVariable v | v instanceof Field) or
31-
this.asUninitialized() instanceof SensitiveVariable or
32-
this.asParameter() instanceof SensitiveVariable or
33-
this.asExpr().(FunctionCall).getTarget() instanceof SensitiveFunction
41+
class SourceNode extends DataFlow::Node {
42+
SourceNode() {
43+
this.asExpr() = any(SourceVariable sv).getInitializer().getExpr() or
44+
this.asExpr().(VariableAccess).getTarget() = any(SourceVariable sv).(GlobalOrNamespaceVariable) or
45+
this.asExpr().(VariableAccess).getTarget() = any(SourceVariable v | v instanceof Field) or
46+
this.asUninitialized() instanceof SourceVariable or
47+
this.asParameter() instanceof SourceVariable or
48+
this.asExpr().(FunctionCall).getTarget() instanceof SourceFunction
3449
}
3550
}
3651

@@ -207,7 +222,7 @@ class Encrypted extends Expr {
207222
class FromSensitiveConfiguration extends TaintTracking::Configuration {
208223
FromSensitiveConfiguration() { this = "FromSensitiveConfiguration" }
209224

210-
override predicate isSource(DataFlow::Node source) { source instanceof SensitiveNode }
225+
override predicate isSource(DataFlow::Node source) { source instanceof SourceNode }
211226

212227
override predicate isSink(DataFlow::Node sink) {
213228
sink.asExpr() = any(NetworkSendRecv nsr).getDataExpr()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The `cpp/cleartext-transmission` query now recognizes additional sources, for sensitive private data such as e-mail addresses and credit card numbers.

cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ edges
9292
| test3.cpp:398:18:398:25 | password | test3.cpp:400:33:400:40 | password |
9393
| test3.cpp:421:21:421:28 | password | test3.cpp:421:3:421:17 | call to decrypt_inplace |
9494
| test3.cpp:429:7:429:14 | password | test3.cpp:431:8:431:15 | password |
95+
| test3.cpp:526:44:526:54 | my_latitude | test3.cpp:527:15:527:20 | buffer |
96+
| test3.cpp:532:45:532:58 | home_longitude | test3.cpp:533:15:533:20 | buffer |
97+
| test3.cpp:551:47:551:58 | salaryString | test3.cpp:552:15:552:20 | buffer |
98+
| test3.cpp:556:19:556:30 | salaryString | test3.cpp:559:15:559:20 | buffer |
9599
| test.cpp:41:23:41:43 | cleartext password! | test.cpp:48:21:48:27 | call to encrypt |
96100
| test.cpp:41:23:41:43 | cleartext password! | test.cpp:48:29:48:39 | thePassword |
97101
| test.cpp:66:23:66:43 | cleartext password! | test.cpp:76:21:76:27 | call to encrypt |
@@ -221,6 +225,25 @@ nodes
221225
| test3.cpp:421:21:421:28 | password | semmle.label | password |
222226
| test3.cpp:429:7:429:14 | password | semmle.label | password |
223227
| test3.cpp:431:8:431:15 | password | semmle.label | password |
228+
| test3.cpp:507:18:507:39 | social_security_number | semmle.label | social_security_number |
229+
| test3.cpp:508:18:508:33 | socialSecurityNo | semmle.label | socialSecurityNo |
230+
| test3.cpp:509:18:509:29 | homePostCode | semmle.label | homePostCode |
231+
| test3.cpp:510:18:510:28 | my_zip_code | semmle.label | my_zip_code |
232+
| test3.cpp:511:18:511:26 | telephone | semmle.label | telephone |
233+
| test3.cpp:512:18:512:36 | mobile_phone_number | semmle.label | mobile_phone_number |
234+
| test3.cpp:513:18:513:22 | email | semmle.label | email |
235+
| test3.cpp:514:18:514:38 | my_credit_card_number | semmle.label | my_credit_card_number |
236+
| test3.cpp:515:18:515:35 | my_bank_account_no | semmle.label | my_bank_account_no |
237+
| test3.cpp:516:18:516:29 | employerName | semmle.label | employerName |
238+
| test3.cpp:517:18:517:29 | medical_info | semmle.label | medical_info |
239+
| test3.cpp:526:44:526:54 | my_latitude | semmle.label | my_latitude |
240+
| test3.cpp:527:15:527:20 | buffer | semmle.label | buffer |
241+
| test3.cpp:532:45:532:58 | home_longitude | semmle.label | home_longitude |
242+
| test3.cpp:533:15:533:20 | buffer | semmle.label | buffer |
243+
| test3.cpp:551:47:551:58 | salaryString | semmle.label | salaryString |
244+
| test3.cpp:552:15:552:20 | buffer | semmle.label | buffer |
245+
| test3.cpp:556:19:556:30 | salaryString | semmle.label | salaryString |
246+
| test3.cpp:559:15:559:20 | buffer | semmle.label | buffer |
224247
| test.cpp:41:23:41:43 | cleartext password! | semmle.label | cleartext password! |
225248
| test.cpp:48:21:48:27 | call to encrypt | semmle.label | call to encrypt |
226249
| test.cpp:48:29:48:39 | thePassword | semmle.label | thePassword |
@@ -254,3 +277,18 @@ subpaths
254277
| test3.cpp:414:3:414:6 | call to recv | test3.cpp:414:17:414:24 | password | test3.cpp:414:17:414:24 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:414:17:414:24 | password | password |
255278
| test3.cpp:420:3:420:6 | call to recv | test3.cpp:420:17:420:24 | password | test3.cpp:420:17:420:24 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:420:17:420:24 | password | password |
256279
| test3.cpp:431:2:431:6 | call to fgets | test3.cpp:429:7:429:14 | password | test3.cpp:431:8:431:15 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:429:7:429:14 | password | password |
280+
| test3.cpp:507:2:507:5 | call to send | test3.cpp:507:18:507:39 | social_security_number | test3.cpp:507:18:507:39 | social_security_number | This operation transmits 'social_security_number', which may contain unencrypted sensitive data from $@ | test3.cpp:507:18:507:39 | social_security_number | social_security_number |
281+
| test3.cpp:508:2:508:5 | call to send | test3.cpp:508:18:508:33 | socialSecurityNo | test3.cpp:508:18:508:33 | socialSecurityNo | This operation transmits 'socialSecurityNo', which may contain unencrypted sensitive data from $@ | test3.cpp:508:18:508:33 | socialSecurityNo | socialSecurityNo |
282+
| test3.cpp:509:2:509:5 | call to send | test3.cpp:509:18:509:29 | homePostCode | test3.cpp:509:18:509:29 | homePostCode | This operation transmits 'homePostCode', which may contain unencrypted sensitive data from $@ | test3.cpp:509:18:509:29 | homePostCode | homePostCode |
283+
| test3.cpp:510:2:510:5 | call to send | test3.cpp:510:18:510:28 | my_zip_code | test3.cpp:510:18:510:28 | my_zip_code | This operation transmits 'my_zip_code', which may contain unencrypted sensitive data from $@ | test3.cpp:510:18:510:28 | my_zip_code | my_zip_code |
284+
| test3.cpp:511:2:511:5 | call to send | test3.cpp:511:18:511:26 | telephone | test3.cpp:511:18:511:26 | telephone | This operation transmits 'telephone', which may contain unencrypted sensitive data from $@ | test3.cpp:511:18:511:26 | telephone | telephone |
285+
| test3.cpp:512:2:512:5 | call to send | test3.cpp:512:18:512:36 | mobile_phone_number | test3.cpp:512:18:512:36 | mobile_phone_number | This operation transmits 'mobile_phone_number', which may contain unencrypted sensitive data from $@ | test3.cpp:512:18:512:36 | mobile_phone_number | mobile_phone_number |
286+
| test3.cpp:513:2:513:5 | call to send | test3.cpp:513:18:513:22 | email | test3.cpp:513:18:513:22 | email | This operation transmits 'email', which may contain unencrypted sensitive data from $@ | test3.cpp:513:18:513:22 | email | email |
287+
| test3.cpp:514:2:514:5 | call to send | test3.cpp:514:18:514:38 | my_credit_card_number | test3.cpp:514:18:514:38 | my_credit_card_number | This operation transmits 'my_credit_card_number', which may contain unencrypted sensitive data from $@ | test3.cpp:514:18:514:38 | my_credit_card_number | my_credit_card_number |
288+
| test3.cpp:515:2:515:5 | call to send | test3.cpp:515:18:515:35 | my_bank_account_no | test3.cpp:515:18:515:35 | my_bank_account_no | This operation transmits 'my_bank_account_no', which may contain unencrypted sensitive data from $@ | test3.cpp:515:18:515:35 | my_bank_account_no | my_bank_account_no |
289+
| test3.cpp:516:2:516:5 | call to send | test3.cpp:516:18:516:29 | employerName | test3.cpp:516:18:516:29 | employerName | This operation transmits 'employerName', which may contain unencrypted sensitive data from $@ | test3.cpp:516:18:516:29 | employerName | employerName |
290+
| test3.cpp:517:2:517:5 | call to send | test3.cpp:517:18:517:29 | medical_info | test3.cpp:517:18:517:29 | medical_info | This operation transmits 'medical_info', which may contain unencrypted sensitive data from $@ | test3.cpp:517:18:517:29 | medical_info | medical_info |
291+
| test3.cpp:527:3:527:6 | call to send | test3.cpp:526:44:526:54 | my_latitude | test3.cpp:527:15:527:20 | buffer | This operation transmits 'buffer', which may contain unencrypted sensitive data from $@ | test3.cpp:526:44:526:54 | my_latitude | my_latitude |
292+
| test3.cpp:533:3:533:6 | call to send | test3.cpp:532:45:532:58 | home_longitude | test3.cpp:533:15:533:20 | buffer | This operation transmits 'buffer', which may contain unencrypted sensitive data from $@ | test3.cpp:532:45:532:58 | home_longitude | home_longitude |
293+
| test3.cpp:552:3:552:6 | call to send | test3.cpp:551:47:551:58 | salaryString | test3.cpp:552:15:552:20 | buffer | This operation transmits 'buffer', which may contain unencrypted sensitive data from $@ | test3.cpp:551:47:551:58 | salaryString | salaryString |
294+
| test3.cpp:559:3:559:6 | call to send | test3.cpp:556:19:556:30 | salaryString | test3.cpp:559:15:559:20 | buffer | This operation transmits 'buffer', which may contain unencrypted sensitive data from $@ | test3.cpp:556:19:556:30 | salaryString | salaryString |

0 commit comments

Comments
 (0)