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
C++: New query for SSL certificates not checked #7243
base: main
Are you sure you want to change the base?
Conversation
I haven't looked at any of the LGTM results yet. But I have a couple of code comments.
| * `SSL_get_verify_result` at `node`. Note that this is only computed at the call to | ||
| * `SSL_get_peer_certificate` and at the start and end of `BasicBlock`s. | ||
| */ | ||
| predicate certNotChecked(SSLGetPeerCertificateCall getCertCall, ControlFlowNode node) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intead of rolling our own control-flow analysis here, could we instead use StackVariableReachability? Then isSource could be the call to SSL_get_peer_certificate, isSink could be the exit of the function, and isBarrier could be a call to SSL_get_verify_result.
Would that work?
It may be difficult to fit the certIsZero barrier into SSL_get_peer_certificate, but I think it's doable by having one StackVariableReachability for each call to SSL_get_peer_certificate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried a couple of libraries that didn't quite fit the problem, I may have overlooked StackVariableReachability.. Trying it now...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be difficult to fit the
certIsZerobarrier intoSSL_get_peer_certificate, but I think it's doable by having oneStackVariableReachabilityfor each call toSSL_get_peer_certificate.
This turns out not to be a major issue, the existing GVN logic finds appropriate guards on certificates returned by SSL_get_peer_certificate, and I've never seen more than one certificate being used at once (in which case we'd have to worry about which certificate it is).
What is an issue is that the certIsZero barrier needs to be a barrier edge, not a barrier node. StackVariableReachability does not appear to support barrier edges and I haven't found a sufficient workaround for this yet. I suppose I could add it as a new feature, but that will then require a lot of testing.
| // if (cert) { } | ||
| guard = cert and | ||
| node1 = guard and | ||
| node2 = guard.getAFalseSuccessor() | ||
| or | ||
| // if (!cert) { | ||
| node1 = guard.getParent() and | ||
| node2 = guard.getParent().(NotExpr).getATrueSuccessor() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could these cases not be covered by using guard.controls? That might be able to solve the FP in test2_11 (and in principle the one in test2_9 as well, but IIRC the GuardConditions class specifically doesn't handle this case very well).
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
This is the second of two new queries for CWE-295: Improper Certificate Validation.
Results:
SSL_get_peer_certificate.Precision:
@medium, for review after looking at the LGTM results in more depth.Performance:
kamailio_kamailioandchakra-core(performance is great with a warmed up cache).The text was updated successfully, but these errors were encountered: