-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Python: Use new dataflow API #14068
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
Python: Use new dataflow API #14068
Conversation
QHelp previews: python/ql/src/experimental/Security/CWE-522/LdapInsecureAuth.qhelpPython Insecure LDAP AuthenticationFailing to ensure the utilization of SSL in an LDAP connection can cause the entire communication to be sent in cleartext making it easier for an attacker to intercept it. RecommendationAlways set ExampleThis example shows both good and bad ways to deal with this issue under Python 3. The first one sets from ldap3 import Server, Connection, ALL
from flask import request, Flask
app = Flask(__name__)
@app.route("/good")
def good():
srv = Server(host, port, use_ssl=True)
conn = Connection(srv, dn, password)
conn.search(dn, search_filter)
return conn.response
@app.route("/bad")
def bad():
srv = Server(host, port)
conn = Connection(srv, dn, password)
conn.search(dn, search_filter)
return conn.response |
...src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql
Fixed
Show fixed
Hide fixed
python/ql/src/experimental/semmle/python/security/InsecureRandomness.qll
Fixed
Show fixed
Hide fixed
66be4f4
to
18d16b4
Compare
We could have switched to a stateful config, but I tried to keep changes as straight forward as possible.
I adopted helper predicates to do the "heavy" lifting of .asPathNode1(), maybe I like this approach better... let me know what you think 😊
…uestForgery` to new dataflow API
…use` a bit To use consistent naming
Since we want to know the _sinks_ and not just the flow, we need to expose the config as well :|
Split it into multiple commits to make it easier to review.
(and any higher number as well)
18d16b4
to
dadefa0
Compare
dadefa0
to
ce63358
Compare
} | ||
|
||
/** Global taint-tracking for detecting "random values that are not cryptographically secure" vulnerabilities. */ | ||
module Flow = TaintTracking::Global<Config>; |
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.
Is there a good reason why this uses the alternative naming convention (option 1)?
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 to keep changes to a minimal. Since it was already inside a properly named module, I let things stay that way.
So no better reason than I tried to get things done 😅
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.
LGTM, just minor comments.
Also, the QL4QL-alerts are interesting, we should probably follow up on those.
|
||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink } | ||
|
||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } |
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.
What was previously covered by super.isSanitizer(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.
Nothing 😂 I found that in a few cases I had copied this pattern from JS
/** Holds if data can flow from `source` to `sink` with `NormalHashFunction::Flow`. */ | ||
predicate normalHashFunctionFlowPath( | ||
WeakSensitiveDataHashingFlow::PathNode source, WeakSensitiveDataHashingFlow::PathNode sink | ||
) { | ||
NormalHashFunction::Flow::flowPath(source.asPathNode1(), sink.asPathNode1()) | ||
} | ||
|
||
/** Holds if data can flow from `source` to `sink` with `ComputationallyExpensiveHashFunction::Flow`. */ | ||
predicate computationallyExpensiveHashFunctionFlowPath( | ||
WeakSensitiveDataHashingFlow::PathNode source, WeakSensitiveDataHashingFlow::PathNode sink | ||
) { | ||
ComputationallyExpensiveHashFunction::Flow::flowPath(source.asPathNode2(), sink.asPathNode2()) | ||
} |
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.
Nice
exists(UserInputInComparisonConfig config | | ||
config.hasFlowTo(DataFlow2::exprNode(anotherParameter)) | ||
) | ||
UserInputInComparisonFlow::flowTo(DataFlow2::exprNode(anotherParameter)) |
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 think we should not need DataFlow2
any more?
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 see you solved this in a later commit 👍
If you're talking about the annotations on https://github.com/github/codeql/pull/14068/checks?check_run_id=16274578369, I don't think I want to do anything about those right now 😊 |
Highly recommend reviewing commit by commit 😅
The
.expected
file will have changes if:isAdditionalFlowStep
, since such steps will now always be part of the path-graph (lines added to .expected file)(no change-note like in Go: #13820)
This PR covers all usage I could find in
src/
andlib/
. I did not focus ontest/
yet. We should fix those too, but I don't think it's strictly required right now 😊