Skip to content

Commit a7cdf0e

Browse files
author
Porcupiney Hairs
committed
CPP: Disabled SSL certificate verification
Disable SSL certificate verification can expose the communication to MITM attacks. This PR adds a query to detect the same. This also include the tests and qhelp for the same.
1 parent db76896 commit a7cdf0e

File tree

7 files changed

+120
-0
lines changed

7 files changed

+120
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
2+
<qhelp>
3+
<overview>
4+
Disabling verification of the SSL certificate allows man-in-the-middle attacks. Disabling the
5+
peer or the host's certificate verification makes the SSL communication insecure. Just having
6+
encryption on a transfer is not enough as you cannot be sure that you are communicating with the
7+
correct end-point.
8+
</overview>
9+
<recommendation>
10+
It is recommended that all communications be done post verification of the host as well as the
11+
peer.
12+
</recommendation>
13+
<example>
14+
<p>The following snippet disables certification verification by setting the value of <code>
15+
CURLOPT_SSL_VERIFYHOST</code> and <code>CURLOPT_SSL_VERIFYHOST</code> to <code>0</code>:</p>
16+
<sample src="CurlSSLBad.cpp" />
17+
<p>This is bad as the certificates are not verified any more. This can be easily fixed by
18+
setting the values of the options to <code>2</code>. </p>
19+
<sample src="CurlSSLGood.cpp" />
20+
</example>
21+
<references>
22+
<li> Curl Documentation:<a href="https://curl.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html">
23+
CURLOPT_SSL_VERIFYHOST</a></li>
24+
<li> Curl Documentation:<a href="https://curl.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html">
25+
CURLOPT_SSL_VERIFYHOST</a></li>
26+
<li> Related CVE: <a href="https://nvd.nist.gov/vuln/detail/CVE-2022-33684"> CVE-2022-33684</a></li>
27+
<li> Related CVE: <a href="https://huntr.com/bounties/42325662-6329-4e04-875a-49e2f5d69f78">
28+
`openframeworks/openframeworks`</a></li>
29+
</references>
30+
</qhelp>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @name Disabled certifcate verification
3+
* @description Disabling SSL certificate verification of host or peer could expose the communication to man-in-the-middle(MITM) attacks.
4+
* @kind problem
5+
* @problem.severity warning
6+
* @id cpp/curl-disabled-ssl
7+
* @tags security
8+
* external/cwe/cwe-295
9+
*/
10+
11+
import cpp
12+
import semmle.code.cpp.dataflow.new.TaintTracking
13+
14+
/** Models the `curl_easy_setopt` function call */
15+
private class CurlSetOptCall extends FunctionCall {
16+
CurlSetOptCall() {
17+
exists(FunctionCall fc, Function f |
18+
f.hasGlobalName("curl_easy_setopt") and
19+
fc.getTarget() = f
20+
|
21+
this = fc
22+
)
23+
}
24+
}
25+
26+
/** Models an access to any enum constant which could affect SSL verification */
27+
private class CurlVerificationConstant extends EnumConstantAccess {
28+
CurlVerificationConstant() {
29+
exists(EnumConstant e | e.getName() = ["CURLOPT_SSL_VERIFYHOST", "CURLOPT_SSL_VERIFYPEER"] |
30+
e.getAnAccess() = this
31+
)
32+
}
33+
}
34+
35+
from CurlSetOptCall c
36+
where
37+
c.getArgument(1) = any(CurlVerificationConstant v) and
38+
c.getArgument(2).getValue() = "0"
39+
select c, "This call disables Secure Socket Layer and could potentially lead to MITM attacks"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
string host = "codeql.com"
2+
void bad(void) {
3+
std::unique_ptr<CURL, void(*)(CURL*)> curl =
4+
std::unique_ptr<CURL, void(*)(CURL*)>(curl_easy_init(), curl_easy_cleanup);
5+
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 0);
6+
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 0);
7+
curl_easy_setopt(curl.get(), CURLOPT_URL, host.c_str());
8+
curl_easy_perform(curl.get());
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
string host = "codeql.com"
2+
void good(void) {
3+
std::unique_ptr<CURL, void(*)(CURL*)> curl =
4+
std::unique_ptr<CURL, void(*)(CURL*)>(curl_easy_init(), curl_easy_cleanup);
5+
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 2);
6+
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 2);
7+
curl_easy_setopt(curl.get(), CURLOPT_URL, host.c_str());
8+
curl_easy_perform(curl.get());
9+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include<iostream>
2+
#include<memory>
3+
4+
#include<curl/curl.h>
5+
6+
using namespace std;
7+
8+
string host = "codeql.com"
9+
10+
void bad(void) {
11+
std::unique_ptr<CURL, void(*)(CURL*)> curl =
12+
std::unique_ptr<CURL, void(*)(CURL*)>(curl_easy_init(), curl_easy_cleanup);
13+
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 0);
14+
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 0);
15+
curl_easy_setopt(curl.get(), CURLOPT_URL, host.c_str());
16+
curl_easy_perform(curl.get());
17+
}
18+
19+
void good(void) {
20+
std::unique_ptr<CURL, void(*)(CURL*)> curl =
21+
std::unique_ptr<CURL, void(*)(CURL*)>(curl_easy_init(), curl_easy_cleanup);
22+
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 2);
23+
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 2);
24+
curl_easy_setopt(curl.get(), CURLOPT_URL, host.c_str());
25+
curl_easy_perform(curl.get());
26+
}
27+
28+
int main(int c, char** argv){
29+
bad();
30+
good();
31+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
experimental/Security/CWE/CWE-295/CurlSSL.ql
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
semmle-extractor-options: command='g++ -lcurl'

0 commit comments

Comments
 (0)