-
Notifications
You must be signed in to change notification settings - Fork 1.8k
CPP: Add query for CWE-670: Always-Incorrect Control Flow Implementation when use SSL_shutdown #9087
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CPP: Add query for CWE-670: Always-Incorrect Control Flow Implementation when use SSL_shutdown #9087
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
... | ||
SSL_shutdown(ssl); | ||
SSL_shutdown(ssl); // BAD | ||
... | ||
switch ((ret = SSL_shutdown(ssl))) { | ||
case 1: | ||
break; | ||
case 0: | ||
ERR_clear_error(); | ||
if (-1 != (ret = SSL_shutdown(ssl))) break; // GOOD | ||
... |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<!DOCTYPE qhelp PUBLIC | ||
"-//Semmle//qhelp//EN" | ||
"qhelp.dtd"> | ||
<qhelp> | ||
<overview> | ||
<p>Incorrect closing of the connection leads to the creation of different states for the server and client, which can be exploited by an attacker.</p> | ||
|
||
</overview> | ||
|
||
<example> | ||
<p>The following example shows the incorrect and correct usage of function SSL_shutdown.</p> | ||
<sample src="DangerousUseSSL_shutdown.cpp" /> | ||
|
||
</example> | ||
<references> | ||
|
||
<li> | ||
CERT Coding Standard: | ||
<a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP12-C.+Do+not+ignore+values+returned+by+functions">EXP12-C. Do not ignore values returned by functions - SEI CERT C Coding Standard - Confluence</a>. | ||
geoffw0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</li> | ||
<li> | ||
Openssl.org: | ||
<a href="https://www.openssl.org/docs/man3.0/man3/SSL_shutdown.html">SSL_shutdown - shut down a TLS/SSL connection</a>. | ||
</li> | ||
|
||
</references> | ||
</qhelp> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/** | ||
* @name Dangerous use SSL_shutdown. | ||
* @description Incorrect closing of the connection leads to the creation of different states for the server and client, which can be exploited by an attacker. | ||
* @kind problem | ||
* @id cpp/dangerous-use-of-ssl-shutdown | ||
* @problem.severity warning | ||
* @precision medium | ||
* @tags correctness | ||
* security | ||
* external/cwe/cwe-670 | ||
*/ | ||
|
||
import cpp | ||
import semmle.code.cpp.commons.Exclusions | ||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering | ||
|
||
from FunctionCall fc, FunctionCall fc1 | ||
where | ||
fc != fc1 and | ||
fc.getASuccessor+() = fc1 and | ||
fc.getTarget().hasName("SSL_shutdown") and | ||
fc1.getTarget().hasName("SSL_shutdown") and | ||
fc1 instanceof ExprInVoidContext and | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand that we're looking for two calls to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are absolutely right, the first check also needs to be checked.
but if you find grain in it, I will add this detector. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Are they problematic? Is it sometimes OK for the developer to ignore the return value of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am sure that you should always check the return value of this function. however, we are talking about the problem of ambiguous understanding of states on the part of the server and the client, in this case, the presence of one call indicates that the developer does not consider this a problem. the addition of this detection, in my opinion, will lead to an increase in hits and will correlate with the situation in these PRs 6950 6947. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, checking for an error on the first call to |
||
( | ||
globalValueNumber(fc.getArgument(0)) = globalValueNumber(fc1.getArgument(0)) or | ||
fc.getArgument(0).(VariableAccess).getTarget() = fc1.getArgument(0).(VariableAccess).getTarget() | ||
) and | ||
not exists(FunctionCall fctmp | | ||
fctmp.getTarget().hasName("SSL_free") and | ||
fc.getASuccessor+() = fctmp and | ||
fctmp.getASuccessor+() = fc1 | ||
) | ||
select fc, "You need to handle the return value SSL_shutdown" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
| test.cpp:45:20:45:31 | call to SSL_shutdown | You need to handle the return value SSL_shutdown | | ||
| test.cpp:61:11:61:22 | call to SSL_shutdown | You need to handle the return value SSL_shutdown | |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
experimental/Security/CWE/CWE-670/DangerousUseSSL_shutdown.ql |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// it's not exact, but it's enough for an example | ||
typedef int SSL; | ||
|
||
|
||
int SSL_shutdown(SSL *ssl); | ||
int SSL_get_error(const SSL *ssl, int ret); | ||
void ERR_clear_error(void); | ||
void print_error(char *buff,int code); | ||
|
||
int gootTest1(SSL *ssl) | ||
{ | ||
int ret; | ||
switch ((ret = SSL_shutdown(ssl))) { | ||
case 1: | ||
break; | ||
case 0: | ||
ERR_clear_error(); | ||
if ((ret = SSL_shutdown(ssl)) == 1) break; // GOOD | ||
default: | ||
print_error("error shutdown", | ||
SSL_get_error(ssl, ret)); | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
int gootTest2(SSL *ssl) | ||
{ | ||
int ret; | ||
switch ((ret = SSL_shutdown(ssl))) { | ||
case 1: | ||
break; | ||
case 0: | ||
ERR_clear_error(); | ||
if (-1 != (ret = SSL_shutdown(ssl))) break; // GOOD | ||
default: | ||
print_error("error shutdown", | ||
SSL_get_error(ssl, ret)); | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
int badTest1(SSL *ssl) | ||
{ | ||
int ret; | ||
switch ((ret = SSL_shutdown(ssl))) { | ||
case 1: | ||
break; | ||
case 0: | ||
SSL_shutdown(ssl); // BAD | ||
break; | ||
default: | ||
print_error("error shutdown", | ||
SSL_get_error(ssl, ret)); | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
int badTest2(SSL *ssl) | ||
{ | ||
int ret; | ||
ret = SSL_shutdown(ssl); | ||
switch (ret) { | ||
case 1: | ||
break; | ||
case 0: | ||
SSL_shutdown(ssl); // BAD | ||
break; | ||
default: | ||
print_error("error shutdown", | ||
SSL_get_error(ssl, ret)); | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.