|
11 | 11 | */
|
12 | 12 |
|
13 | 13 | import python
|
14 |
| -import semmle.python.web.Http |
| 14 | +private import semmle.python.dataflow.new.DataFlow |
| 15 | +private import semmle.python.Concepts |
| 16 | +private import semmle.python.ApiGraphs |
15 | 17 |
|
16 |
| -FunctionValue requestFunction() { result = Module::named("requests").attr(httpVerbLower()) } |
| 18 | +/** |
| 19 | + * Gets a call to a method that makes an outgoing request using the `requests` module, |
| 20 | + * such as `requests.get` or `requests.put`, with the specified HTTP verb `verb` |
| 21 | + */ |
| 22 | +DataFlow::CallCfgNode outgoingRequestCall(string verb) { |
| 23 | + verb = HTTP::httpVerbLower() and |
| 24 | + result = API::moduleImport("requests").getMember(verb).getACall() |
| 25 | +} |
| 26 | + |
| 27 | +/** Gets the "verfiy" argument to a outgoingRequestCall. */ |
| 28 | +DataFlow::Node verifyArg(DataFlow::CallCfgNode call) { |
| 29 | + call = outgoingRequestCall(_) and |
| 30 | + result = call.getArgByName("verify") |
| 31 | +} |
| 32 | + |
| 33 | +/** Gets a back-reference to the verify argument `arg`. */ |
| 34 | +private DataFlow::TypeTrackingNode verifyArgBacktracker( |
| 35 | + DataFlow::TypeBackTracker t, DataFlow::Node arg |
| 36 | +) { |
| 37 | + t.start() and |
| 38 | + arg = verifyArg(_) and |
| 39 | + result = arg.getALocalSource() |
| 40 | + or |
| 41 | + exists(DataFlow::TypeBackTracker t2 | result = verifyArgBacktracker(t2, arg).backtrack(t2, t)) |
| 42 | +} |
17 | 43 |
|
18 |
| -/** requests treats None as the default and all other "falsey" values as False */ |
19 |
| -predicate falseNotNone(Value v) { v.getDefiniteBooleanValue() = false and not v = Value::none_() } |
| 44 | +/** Gets a back-reference to the verify argument `arg`. */ |
| 45 | +DataFlow::LocalSourceNode verifyArgBacktracker(DataFlow::Node arg) { |
| 46 | + result = verifyArgBacktracker(DataFlow::TypeBackTracker::end(), arg) |
| 47 | +} |
20 | 48 |
|
21 |
| -from CallNode call, FunctionValue func, Value falsey, ControlFlowNode origin |
| 49 | +from DataFlow::CallCfgNode call, DataFlow::Node falseyOrigin, string verb |
22 | 50 | where
|
23 |
| - func = requestFunction() and |
24 |
| - func.getACall() = call and |
25 |
| - falseNotNone(falsey) and |
26 |
| - call.getArgByName("verify").pointsTo(falsey, origin) |
27 |
| -select call, "Call to $@ with verify=$@", func, "requests." + func.getName(), origin, "False" |
| 51 | + call = outgoingRequestCall(verb) and |
| 52 | + falseyOrigin = verifyArgBacktracker(verifyArg(call)) and |
| 53 | + // requests treats `None` as the default and all other "falsey" values as `False`. |
| 54 | + falseyOrigin.asExpr().(ImmutableLiteral).booleanValue() = false and |
| 55 | + not falseyOrigin.asExpr() instanceof None |
| 56 | +select call, "Call to requests." + verb + " with verify=$@", falseyOrigin, "False" |
0 commit comments