Skip to content

Commit 72d08f4

Browse files
committed
Python: Model json load/dump
1 parent 63f28d7 commit 72d08f4

File tree

2 files changed

+38
-4
lines changed
  • python/ql
    • src/semmle/python/frameworks
    • test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep

2 files changed

+38
-4
lines changed

python/ql/src/semmle/python/frameworks/Stdlib.qll

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,22 @@ private module Stdlib {
518518
override string getFormat() { result = "JSON" }
519519
}
520520

521+
/**
522+
* A call to `json.load`
523+
* See https://docs.python.org/3/library/json.html#json.load
524+
*/
525+
private class JsonLoadCall extends Decoding::Range, DataFlow::CallCfgNode {
526+
JsonLoadCall() { this = json().getMember("load").getACall() }
527+
528+
override predicate mayExecuteInput() { none() }
529+
530+
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("fp")] }
531+
532+
override DataFlow::Node getOutput() { result = this }
533+
534+
override string getFormat() { result = "JSON" }
535+
}
536+
521537
/**
522538
* A call to `json.dumps`
523539
* See https://docs.python.org/3/library/json.html#json.dumps
@@ -532,6 +548,24 @@ private module Stdlib {
532548
override string getFormat() { result = "JSON" }
533549
}
534550

551+
/**
552+
* A call to `json.dump`
553+
* See https://docs.python.org/3/library/json.html#json.dump
554+
*/
555+
private class JsonDumpCall extends Encoding::Range, DataFlow::CallCfgNode {
556+
JsonDumpCall() { this = json().getMember("dump").getACall() }
557+
558+
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("obj")] }
559+
560+
override DataFlow::Node getOutput() {
561+
result.(DataFlow::PostUpdateNode).getPreUpdateNode() in [
562+
this.getArg(1), this.getArgByName("fp")
563+
]
564+
}
565+
566+
override string getFormat() { result = "JSON" }
567+
}
568+
535569
// ---------------------------------------------------------------------------
536570
// cgi
537571
// ---------------------------------------------------------------------------

python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_json.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ def test():
3333

3434
tainted_filelike.seek(0)
3535
ensure_tainted(
36-
tainted_filelike, # $ MISSING: tainted
37-
json.load(tainted_filelike), # $ MISSING: tainted
36+
tainted_filelike, # $ tainted
37+
json.load(tainted_filelike), # $ tainted
3838
)
3939

4040
# load/dump with file-like using keyword-args
@@ -43,8 +43,8 @@ def test():
4343

4444
tainted_filelike.seek(0)
4545
ensure_tainted(
46-
tainted_filelike, # $ MISSING: tainted
47-
json.load(fp=tainted_filelike), # $ MISSING: tainted
46+
tainted_filelike, # $ tainted
47+
json.load(fp=tainted_filelike), # $ tainted
4848
)
4949

5050

0 commit comments

Comments
 (0)