Skip to content

Commit dfd30e4

Browse files
authored
Merge pull request #8227 from geoffw0/319improve
C++: Promote cpp/non-https-url
2 parents ab3cad7 + 899ae90 commit dfd30e4

File tree

4 files changed

+80
-2
lines changed

4 files changed

+80
-2
lines changed

cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @description Non-HTTPS connections can be intercepted by third parties.
44
* @kind path-problem
55
* @problem.severity warning
6-
* @precision medium
6+
* @precision high
77
* @id cpp/non-https-url
88
* @tags security
99
* external/cwe/cwe-319
@@ -12,6 +12,7 @@
1212

1313
import cpp
1414
import semmle.code.cpp.dataflow.TaintTracking
15+
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
1516
import DataFlow::PathGraph
1617

1718
/**
@@ -57,7 +58,12 @@ class HttpStringToUrlOpenConfig extends TaintTracking::Configuration {
5758

5859
override predicate isSource(DataFlow::Node src) {
5960
// Sources are strings containing an HTTP URL not in a private domain.
60-
src.asExpr() instanceof HttpStringLiteral
61+
src.asExpr() instanceof HttpStringLiteral and
62+
// block taint starting at `strstr`, which is likely testing an existing URL, rather than constructing an HTTP URL.
63+
not exists(FunctionCall fc |
64+
fc.getTarget().getName() = ["strstr", "strcasestr"] and
65+
fc.getArgument(1) = globalValueNumber(src.asExpr()).getAnExpr()
66+
)
6167
}
6268

6369
override predicate isSink(DataFlow::Node sink) {
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 "Failure to use HTTPS URLs" (`cpp/non-https-url`) has been improved reducing false positive results, and its precision has been increased to 'high'.

cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ edges
77
| test.cpp:40:11:40:17 | access to array | test.cpp:11:26:11:28 | url |
88
| test.cpp:46:18:46:26 | http:// | test.cpp:49:11:49:16 | buffer |
99
| test.cpp:49:11:49:16 | buffer | test.cpp:11:26:11:28 | url |
10+
| test.cpp:110:21:110:40 | http://example.com | test.cpp:121:11:121:13 | ptr |
11+
| test.cpp:121:11:121:13 | ptr | test.cpp:11:26:11:28 | url |
1012
nodes
1113
| test.cpp:11:26:11:28 | url | semmle.label | url |
1214
| test.cpp:15:30:15:32 | url | semmle.label | url |
@@ -17,9 +19,12 @@ nodes
1719
| test.cpp:40:11:40:17 | access to array | semmle.label | access to array |
1820
| test.cpp:46:18:46:26 | http:// | semmle.label | http:// |
1921
| test.cpp:49:11:49:16 | buffer | semmle.label | buffer |
22+
| test.cpp:110:21:110:40 | http://example.com | semmle.label | http://example.com |
23+
| test.cpp:121:11:121:13 | ptr | semmle.label | ptr |
2024
subpaths
2125
#select
2226
| test.cpp:28:10:28:29 | http://example.com | test.cpp:28:10:28:29 | http://example.com | test.cpp:15:30:15:32 | url | A URL may be constructed with the HTTP protocol. |
2327
| test.cpp:35:23:35:42 | http://example.com | test.cpp:35:23:35:42 | http://example.com | test.cpp:15:30:15:32 | url | A URL may be constructed with the HTTP protocol. |
2428
| test.cpp:36:26:36:45 | http://example.com | test.cpp:36:26:36:45 | http://example.com | test.cpp:15:30:15:32 | url | A URL may be constructed with the HTTP protocol. |
2529
| test.cpp:46:18:46:26 | http:// | test.cpp:46:18:46:26 | http:// | test.cpp:15:30:15:32 | url | A URL may be constructed with the HTTP protocol. |
30+
| test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com | test.cpp:15:30:15:32 | url | A URL may be constructed with the HTTP protocol. |

cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/test.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,66 @@ void test()
5858
openUrl(buffer);
5959
}
6060
}
61+
62+
typedef unsigned long size_t;
63+
int strncmp(const char *s1, const char *s2, size_t n);
64+
char* strstr(char* s1, const char* s2);
65+
66+
void test2(const char *url)
67+
{
68+
if (strncmp(url, "http://", 7)) // GOOD (or at least dubious; we are not constructing the URL)
69+
{
70+
openUrl(url);
71+
}
72+
}
73+
74+
void test3(char *url)
75+
{
76+
char *ptr;
77+
78+
ptr = strstr(url, "https://"); // GOOD (https)
79+
if (!ptr)
80+
{
81+
ptr = strstr(url, "http://"); // GOOD (we are not constructing the URL)
82+
}
83+
84+
if (ptr)
85+
{
86+
openUrl(ptr);
87+
}
88+
}
89+
90+
void test4(char *url)
91+
{
92+
const char *https_string = "https://"; // GOOD (https)
93+
const char *http_string = "http://"; // GOOD (we are not constructing the URL)
94+
char *ptr;
95+
96+
ptr = strstr(url, https_string);
97+
if (!ptr)
98+
{
99+
ptr = strstr(url, http_string);
100+
}
101+
102+
if (ptr)
103+
{
104+
openUrl(ptr);
105+
}
106+
}
107+
108+
void test5()
109+
{
110+
char *url_string = "http://example.com"; // BAD
111+
char *ptr;
112+
113+
ptr = strstr(url_string, "https://"); // GOOD (https)
114+
if (!ptr)
115+
{
116+
ptr = strstr(url_string, "http://"); // GOOD (we are not constructing the URL here)
117+
}
118+
119+
if (ptr)
120+
{
121+
openUrl(ptr);
122+
}
123+
}

0 commit comments

Comments
 (0)