diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-295/CurlSSL.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-295/CurlSSL.qhelp new file mode 100644 index 000000000000..2e17f99f45d7 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-295/CurlSSL.qhelp @@ -0,0 +1,34 @@ + + + +

+ Disabling verification of the SSL certificate allows man-in-the-middle attacks. A SSL + connection is vulnerable to man-in-the-middle attacks if the certification is not checked + properly. If the peer or the host's certificate verification is not verified, the underlying + SSL communication is insecure.

+
+ +

It is recommended that all communications be done post verification of the host as well as + the + peer.

+
+ +

The following snippet disables certification verification by setting the value of + CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYHOST to 0:

+ +

This is bad as the certificates are not verified any more. This can be easily fixed by + setting the values of the options to 2.

+ +
+ +
  • Curl Documentation: + CURLOPT_SSL_VERIFYHOST
  • +
  • Curl Documentation: + CURLOPT_SSL_VERIFYPEER
  • +
  • Related CVE: CVE-2022-33684
  • +
  • Related security advisory: + openframeworks/openframeworks +
  • +
    +
    \ No newline at end of file diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-295/CurlSSL.ql b/cpp/ql/src/experimental/Security/CWE/CWE-295/CurlSSL.ql new file mode 100644 index 000000000000..f6cdaf3e9fca --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-295/CurlSSL.ql @@ -0,0 +1,39 @@ +/** + * @name Disabled certifcate verification + * @description Disabling SSL certificate verification of host or peer could expose the communication to man-in-the-middle(MITM) attacks. + * @kind problem + * @problem.severity warning + * @id cpp/curl-disabled-ssl + * @tags security + * external/cwe/cwe-295 + */ + +import cpp +import semmle.code.cpp.dataflow.new.TaintTracking + +/** Models the `curl_easy_setopt` function call */ +private class CurlSetOptCall extends FunctionCall { + CurlSetOptCall() { + exists(FunctionCall fc, Function f | + f.hasGlobalOrStdName("curl_easy_setopt") and + fc.getTarget() = f + | + this = fc + ) + } +} + +/** Models an access to any enum constant which could affect SSL verification */ +private class CurlVerificationConstant extends EnumConstantAccess { + CurlVerificationConstant() { + exists(EnumConstant e | e.getName() = ["CURLOPT_SSL_VERIFYHOST", "CURLOPT_SSL_VERIFYPEER"] | + e.getAnAccess() = this + ) + } +} + +from CurlSetOptCall c +where + c.getArgument(1) = any(CurlVerificationConstant v) and + c.getArgument(2).getValue() = "0" +select c, "This call disables Secure Socket Layer and could potentially lead to MITM attacks" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-295/CurlSSLBad.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-295/CurlSSLBad.cpp new file mode 100644 index 000000000000..a09e490d73b3 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-295/CurlSSLBad.cpp @@ -0,0 +1,9 @@ +string host = "codeql.com" +void bad(void) { + std::unique_ptr curl = + std::unique_ptr(curl_easy_init(), curl_easy_cleanup); + curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(curl.get(), CURLOPT_URL, host.c_str()); + curl_easy_perform(curl.get()); +} \ No newline at end of file diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-295/CurlSSLGood.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-295/CurlSSLGood.cpp new file mode 100644 index 000000000000..bafead50d5e7 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-295/CurlSSLGood.cpp @@ -0,0 +1,9 @@ +string host = "codeql.com" +void good(void) { + std::unique_ptr curl = + std::unique_ptr(curl_easy_init(), curl_easy_cleanup); + curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 2); + curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 2); + curl_easy_setopt(curl.get(), CURLOPT_URL, host.c_str()); + curl_easy_perform(curl.get()); +} \ No newline at end of file diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-295/CurlSSL.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-295/CurlSSL.cpp new file mode 100644 index 000000000000..60a34889e05b --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-295/CurlSSL.cpp @@ -0,0 +1,43 @@ +#include "../../../../../library-tests/string_concat/stl.h" + +namespace std{ + struct CURL {}; + typedef CURL curl; + enum curl_constant{ + CURLOPT_URL, + CURLOPT_SSL_VERIFYHOST, + CURLOPT_SSL_VERIFYPEER + }; + + CURL *curl_easy_init(); + void curl_easy_cleanup(CURL *handle); + void curl_easy_perform(CURL *handle); + void curl_easy_setopt(CURL *handle, curl_constant param, int p); + void curl_easy_setopt(CURL *handle, curl_constant param, char* p); +} + + +using namespace std; +char host[] = "codeql.com"; + +void bad(void) { + std::unique_ptr curl = std::unique_ptr(curl_easy_init()); + curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(curl.get(), CURLOPT_URL, host); + curl_easy_perform(curl.get()); +} + +void good(void) { + std::unique_ptr curl = std::unique_ptr(curl_easy_init()); + curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 2); + curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 2); + curl_easy_setopt(curl.get(), CURLOPT_URL, host); + curl_easy_perform(curl.get()); +} + +int main(int c, char** argv){ + bad(); + good(); +} + diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-295/CurlSSL.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-295/CurlSSL.expected new file mode 100644 index 000000000000..343da6da6077 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-295/CurlSSL.expected @@ -0,0 +1,2 @@ +| CurlSSL.cpp:25:2:25:17 | call to curl_easy_setopt | This call disables Secure Socket Layer and could potentially lead to MITM attacks | +| CurlSSL.cpp:26:2:26:17 | call to curl_easy_setopt | This call disables Secure Socket Layer and could potentially lead to MITM attacks | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-295/CurlSSL.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-295/CurlSSL.qlref new file mode 100644 index 000000000000..6b09ac53c9b7 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-295/CurlSSL.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-295/CurlSSL.ql