Merge pull request #5878 from RasmusWL/fix-concept-tests-pretty-print

Python: Fix concept tests pretty print
This commit is contained in:
yoff
2021-06-10 11:21:08 +02:00
committed by GitHub
17 changed files with 149 additions and 150 deletions

View File

@@ -1,7 +1,7 @@
import python
import semmle.python.dataflow.new.DataFlow
string prettyExp(Expr e) {
string prettyExpr(Expr e) {
not e instanceof Num and
not e instanceof StrConst and
not e instanceof Subscript and
@@ -15,17 +15,41 @@ string prettyExp(Expr e) {
e.(StrConst).getPrefix() + e.(StrConst).getText() +
e.(StrConst).getPrefix().regexpReplaceAll("[a-zA-Z]+", "")
or
result = prettyExp(e.(Subscript).getObject()) + "[" + prettyExp(e.(Subscript).getIndex()) + "]"
result = prettyExpr(e.(Subscript).getObject()) + "[" + prettyExpr(e.(Subscript).getIndex()) + "]"
or
(
if exists(e.(Call).getAnArg()) or exists(e.(Call).getANamedArg())
then result = prettyExp(e.(Call).getFunc()) + "(..)"
else result = prettyExp(e.(Call).getFunc()) + "()"
then result = prettyExpr(e.(Call).getFunc()) + "(..)"
else result = prettyExpr(e.(Call).getFunc()) + "()"
)
or
result = prettyExp(e.(Attribute).getObject()) + "." + e.(Attribute).getName()
result = prettyExpr(e.(Attribute).getObject()) + "." + e.(Attribute).getName()
}
/**
* Gets pretty-printed version of the DataFlow::Node `node`
*/
bindingset[node]
string prettyNode(DataFlow::Node node) {
if exists(node.asExpr()) then result = prettyExp(node.asExpr()) else result = node.toString()
if exists(node.asExpr()) then result = prettyExpr(node.asExpr()) else result = node.toString()
}
/**
* Gets pretty-printed version of the DataFlow::Node `node`, that is suitable for use
* with `TestUtilities.InlineExpectationsTest` (that is, no spaces unless required).
*/
bindingset[node]
string prettyNodeForInlineTest(DataFlow::Node node) {
exists(node.asExpr()) and
result = prettyExpr(node.asExpr())
or
exists(Expr e | e = node.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() |
// since PostUpdateNode both has space in the `[post <thing>]` annotation, and does
// not pretty print the pre-update node, we do custom handling of this.
result = "[post]" + prettyExpr(e)
)
or
not exists(node.asExpr()) and
not exists(Expr e | e = node.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr()) and
result = node.toString()
}

View File

@@ -46,6 +46,6 @@ query predicate test_taint(string arg_location, string test_res, string scope_na
arg_location = arg.getLocation().toString() and
test_res = test_res and
scope_name = call.getScope().getName() and
repr = prettyExp(arg)
repr = prettyExpr(arg)
)
}

View File

@@ -1,53 +0,0 @@
# Add taintlib to PATH so it can be imported during runtime without any hassle
import sys; import os; sys.path.append(os.path.dirname(os.path.dirname((__file__))))
from taintlib import *
# This has no runtime impact, but allows autocomplete to work
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from ..taintlib import *
# Actual tests
from io import StringIO
import json
def test():
print("\n# test")
ts = TAINTED_STRING
encoded = json.dumps(ts)
ensure_tainted(
encoded, # $ tainted
json.dumps(ts), # $ tainted
json.dumps(obj=ts), # $ tainted
json.loads(encoded), # $ tainted
json.loads(s=encoded), # $ tainted
)
# load/dump with file-like
tainted_filelike = StringIO()
json.dump(ts, tainted_filelike)
tainted_filelike.seek(0)
ensure_tainted(
tainted_filelike, # $ tainted
json.load(tainted_filelike), # $ tainted
)
# load/dump with file-like using keyword-args
tainted_filelike = StringIO()
json.dump(obj=ts, fp=tainted_filelike)
tainted_filelike.seek(0)
ensure_tainted(
tainted_filelike, # $ tainted
json.load(fp=tainted_filelike), # $ tainted
)
# Make tests runable
test()

View File

@@ -2,19 +2,7 @@ import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.Concepts
import TestUtilities.InlineExpectationsTest
string value_from_expr(Expr e) {
// TODO: This one is starting to look like `repr` predicate from TestTaintLib
result =
e.(StrConst).getPrefix() + e.(StrConst).getText() +
e.(StrConst).getPrefix().regexpReplaceAll("[a-zA-Z]+", "")
or
result = e.(Name).getId()
or
not e instanceof StrConst and
not e instanceof Name and
result = e.toString()
}
import experimental.dataflow.TestUtil.PrintNode
class SystemCommandExecutionTest extends InlineExpectationsTest {
SystemCommandExecutionTest() { this = "SystemCommandExecutionTest" }
@@ -27,7 +15,7 @@ class SystemCommandExecutionTest extends InlineExpectationsTest {
command = sce.getCommand() and
location = command.getLocation() and
element = command.toString() and
value = value_from_expr(command.asExpr()) and
value = prettyNodeForInlineTest(command) and
tag = "getCommand"
)
}
@@ -46,7 +34,7 @@ class DecodingTest extends InlineExpectationsTest {
exists(DataFlow::Node data |
location = data.getLocation() and
element = data.toString() and
value = value_from_expr(data.asExpr()) and
value = prettyNodeForInlineTest(data) and
(
data = d.getAnInput() and
tag = "decodeInput"
@@ -84,7 +72,7 @@ class EncodingTest extends InlineExpectationsTest {
exists(DataFlow::Node data |
location = data.getLocation() and
element = data.toString() and
value = value_from_expr(data.asExpr()) and
value = prettyNodeForInlineTest(data) and
(
data = e.getAnInput() and
tag = "encodeInput"
@@ -117,7 +105,7 @@ class CodeExecutionTest extends InlineExpectationsTest {
code = ce.getCode() and
location = code.getLocation() and
element = code.toString() and
value = value_from_expr(code.asExpr()) and
value = prettyNodeForInlineTest(code) and
tag = "getCode"
)
}
@@ -135,7 +123,7 @@ class SqlExecutionTest extends InlineExpectationsTest {
sql = e.getSql() and
location = e.getLocation() and
element = sql.toString() and
value = value_from_expr(sql.asExpr()) and
value = prettyNodeForInlineTest(sql) and
tag = "getSql"
)
}
@@ -218,7 +206,7 @@ class HttpServerHttpResponseTest extends InlineExpectationsTest {
exists(HTTP::Server::HttpResponse response |
location = response.getLocation() and
element = response.toString() and
value = value_from_expr(response.getBody().asExpr()) and
value = prettyNodeForInlineTest(response.getBody()) and
tag = "responseBody"
)
or
@@ -257,7 +245,7 @@ class HttpServerHttpRedirectResponseTest extends InlineExpectationsTest {
exists(HTTP::Server::HttpRedirectResponse redirect |
location = redirect.getLocation() and
element = redirect.toString() and
value = value_from_expr(redirect.getRedirectLocation().asExpr()) and
value = prettyNodeForInlineTest(redirect.getRedirectLocation()) and
tag = "redirectLocation"
)
)
@@ -275,7 +263,7 @@ class FileSystemAccessTest extends InlineExpectationsTest {
path = a.getAPathArgument() and
location = a.getLocation() and
element = path.toString() and
value = value_from_expr(path.asExpr()) and
value = prettyNodeForInlineTest(path) and
tag = "getAPathArgument"
)
}
@@ -309,7 +297,7 @@ class SafeAccessCheckTest extends InlineExpectationsTest {
location = c.getLocation() and
(
element = checks.toString() and
value = value_from_expr(checks.asExpr()) and
value = prettyNodeForInlineTest(checks) and
tag = "checks"
or
element = branch.toString() and

View File

@@ -58,7 +58,7 @@ class InlineTaintTest extends InlineExpectationsTest {
exists(DataFlow::Node sink |
any(TestTaintTrackingConfiguration config).hasFlow(_, sink) and
location = sink.getLocation() and
element = prettyExp(sink.asExpr()) and
element = prettyExpr(sink.asExpr()) and
value = "" and
tag = "tainted"
)
@@ -84,7 +84,7 @@ query predicate untaintedArgumentToEnsureTaintedNotMarkedAsMissing(
error = "ERROR, you should add `# $ MISSING: tainted` annotation" and
exists(DataFlow::Node sink |
sink = shouldBeTainted() and
element = prettyExp(sink.asExpr()) and
element = prettyExpr(sink.asExpr()) and
not any(TestTaintTrackingConfiguration config).hasFlow(_, sink) and
location = sink.getLocation() and
not exists(FalseNegativeExpectation missingResult |

View File

@@ -1,3 +1,3 @@
import dill
dill.loads(payload) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=dill decodeMayExecuteInput
dill.loads(payload) # $decodeInput=payload decodeOutput=dill.loads(..) decodeFormat=dill decodeMayExecuteInput

View File

@@ -74,20 +74,20 @@ class CustomRedirectView(RedirectView):
# Ensure that simple subclasses are still vuln to XSS
def xss__not_found(request):
return HttpResponseNotFound(request.GET.get("name")) # $HttpResponse mimetype=text/html responseBody=Attribute()
return HttpResponseNotFound(request.GET.get("name")) # $HttpResponse mimetype=text/html responseBody=request.GET.get(..)
# Ensure we still have an XSS sink when manually setting the content_type to HTML
def xss__manual_response_type(request):
return HttpResponse(request.GET.get("name"), content_type="text/html; charset=utf-8") # $HttpResponse mimetype=text/html responseBody=Attribute()
return HttpResponse(request.GET.get("name"), content_type="text/html; charset=utf-8") # $HttpResponse mimetype=text/html responseBody=request.GET.get(..)
def xss__write(request):
response = HttpResponse() # $HttpResponse mimetype=text/html
response.write(request.GET.get("name")) # $HttpResponse mimetype=text/html responseBody=Attribute()
response.write(request.GET.get("name")) # $HttpResponse mimetype=text/html responseBody=request.GET.get(..)
# This is safe but probably a bug if the argument to `write` is not a result of `json.dumps` or similar.
def safe__write_json(request):
response = JsonResponse() # $HttpResponse mimetype=application/json
response.write(request.GET.get("name")) # $HttpResponse mimetype=application/json responseBody=Attribute()
response.write(request.GET.get("name")) # $HttpResponse mimetype=application/json responseBody=request.GET.get(..)
# Ensure manual subclasses are vulnerable
class CustomResponse(HttpResponse):
@@ -95,7 +95,7 @@ class CustomResponse(HttpResponse):
super().__init__(content, *args, content_type="text/html", **kwargs)
def xss__custom_response(request):
return CustomResponse("ACME Responses", request.GET("name")) # $HttpResponse MISSING: mimetype=text/html responseBody=Attribute() SPURIOUS: responseBody="ACME Responses"
return CustomResponse("ACME Responses", request.GET("name")) # $HttpResponse MISSING: mimetype=text/html responseBody=request.GET.get(..) SPURIOUS: responseBody="ACME Responses"
class CustomJsonResponse(JsonResponse):
def __init__(self, banner, content, *args, **kwargs):

View File

@@ -13,7 +13,7 @@ https://docs.djangoproject.com/en/3.1/ref/settings/
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent #$ getAPathArgument=Path()
BASE_DIR = Path(__file__).resolve().parent.parent #$ getAPathArgument=Path(..)
# Quick-start development settings - unsuitable for production

View File

@@ -5,9 +5,9 @@ def test_idna():
tb = TAINTED_BYTES
ensure_tainted(
idna.encode(ts), # $ tainted encodeInput=ts encodeOutput=Attribute() encodeFormat=IDNA
idna.encode(s=ts), # $ tainted encodeInput=ts encodeOutput=Attribute() encodeFormat=IDNA
idna.encode(ts), # $ tainted encodeInput=ts encodeOutput=idna.encode(..) encodeFormat=IDNA
idna.encode(s=ts), # $ tainted encodeInput=ts encodeOutput=idna.encode(..) encodeFormat=IDNA
idna.decode(tb), # $ tainted decodeInput=tb decodeOutput=Attribute() decodeFormat=IDNA
idna.decode(s=tb), # $ tainted decodeInput=tb decodeOutput=Attribute() decodeFormat=IDNA
idna.decode(tb), # $ tainted decodeInput=tb decodeOutput=idna.decode(..) decodeFormat=IDNA
idna.decode(s=tb), # $ tainted decodeInput=tb decodeOutput=idna.decode(..) decodeFormat=IDNA
)

View File

@@ -5,14 +5,14 @@ def test():
ts = TAINTED_STRING
tainted_obj = {"foo": ts}
encoded = simplejson.dumps(tainted_obj) # $ encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj
encoded = simplejson.dumps(tainted_obj) # $ encodeOutput=simplejson.dumps(..) encodeFormat=JSON encodeInput=tainted_obj
ensure_tainted(
encoded, # $ tainted
simplejson.dumps(tainted_obj), # $ tainted encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj
simplejson.dumps(obj=tainted_obj), # $ tainted encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj
simplejson.loads(encoded), # $ tainted decodeOutput=Attribute() decodeFormat=JSON decodeInput=encoded
simplejson.loads(s=encoded), # $ tainted decodeOutput=Attribute() decodeFormat=JSON decodeInput=encoded
simplejson.dumps(tainted_obj), # $ tainted encodeOutput=simplejson.dumps(..) encodeFormat=JSON encodeInput=tainted_obj
simplejson.dumps(obj=tainted_obj), # $ tainted encodeOutput=simplejson.dumps(..) encodeFormat=JSON encodeInput=tainted_obj
simplejson.loads(encoded), # $ tainted decodeOutput=simplejson.loads(..) decodeFormat=JSON decodeInput=encoded
simplejson.loads(s=encoded), # $ tainted decodeOutput=simplejson.loads(..) decodeFormat=JSON decodeInput=encoded
)
# load/dump with file-like
@@ -22,7 +22,7 @@ def test():
tainted_filelike.seek(0)
ensure_tainted(
tainted_filelike, # $ MISSING: tainted
simplejson.load(tainted_filelike), # $ decodeOutput=Attribute() decodeFormat=JSON decodeInput=tainted_filelike MISSING: tainted
simplejson.load(tainted_filelike), # $ decodeOutput=simplejson.load(..) decodeFormat=JSON decodeInput=tainted_filelike MISSING: tainted
)
# load/dump with file-like using keyword-args
@@ -32,7 +32,7 @@ def test():
tainted_filelike.seek(0)
ensure_tainted(
tainted_filelike, # $ MISSING: tainted
simplejson.load(fp=tainted_filelike), # $ decodeOutput=Attribute() decodeFormat=JSON decodeInput=tainted_filelike MISSING: tainted
simplejson.load(fp=tainted_filelike), # $ decodeOutput=simplejson.load(..) decodeFormat=JSON decodeInput=tainted_filelike MISSING: tainted
)
# To make things runable

View File

@@ -1,6 +1,6 @@
import base64
# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py
base64.a85decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Ascii85
base64.b85decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base85
base64.decodebytes(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64
base64.a85decode(payload) # $ decodeInput=payload decodeOutput=base64.a85decode(..) decodeFormat=Ascii85
base64.b85decode(payload) # $ decodeInput=payload decodeOutput=base64.b85decode(..) decodeFormat=Base85
base64.decodebytes(payload) # $ decodeInput=payload decodeOutput=base64.decodebytes(..) decodeFormat=Base64

View File

@@ -1,6 +1,6 @@
import base64
# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py
base64.a85encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Ascii85
base64.b85encode(bs)# $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base85
base64.encodebytes(bs)# $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64
base64.a85encode(bs) # $ encodeInput=bs encodeOutput=base64.a85encode(..) encodeFormat=Ascii85
base64.b85encode(bs)# $ encodeInput=bs encodeOutput=base64.b85encode(..) encodeFormat=Base85
base64.encodebytes(bs)# $ encodeInput=bs encodeOutput=base64.encodebytes(..) encodeFormat=Base64

View File

@@ -2,14 +2,14 @@ import pickle
import marshal
import base64
pickle.loads(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=pickle decodeMayExecuteInput
marshal.loads(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=marshal decodeMayExecuteInput
pickle.loads(payload) # $ decodeInput=payload decodeOutput=pickle.loads(..) decodeFormat=pickle decodeMayExecuteInput
marshal.loads(payload) # $ decodeInput=payload decodeOutput=marshal.loads(..) decodeFormat=marshal decodeMayExecuteInput
# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py
base64.b64decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64
base64.standard_b64decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64
base64.urlsafe_b64decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64
base64.b32decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base32
base64.b16decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base16
base64.b64decode(payload) # $ decodeInput=payload decodeOutput=base64.b64decode(..) decodeFormat=Base64
base64.standard_b64decode(payload) # $ decodeInput=payload decodeOutput=base64.standard_b64decode(..) decodeFormat=Base64
base64.urlsafe_b64decode(payload) # $ decodeInput=payload decodeOutput=base64.urlsafe_b64decode(..) decodeFormat=Base64
base64.b32decode(payload) # $ decodeInput=payload decodeOutput=base64.b32decode(..) decodeFormat=Base32
base64.b16decode(payload) # $ decodeInput=payload decodeOutput=base64.b16decode(..) decodeFormat=Base16
# deprecated since Python 3.1, but still works
base64.decodestring(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64
base64.decodestring(payload) # $ decodeInput=payload decodeOutput=base64.decodestring(..) decodeFormat=Base64

View File

@@ -2,14 +2,14 @@ import pickle
import marshal
import base64
pickle.dumps(obj) # $ MISSING: f-:encodeInput=obj f-:encodeOutput=Attribute() f-:encodeFormat=pickle f-:encodeMayExecuteInput
marshal.dumps(obj) # $ MISSING: f-:encodeInput=obj f-:encodeOutput=Attribute() f-:encodeFormat=marshal f-:encodeMayExecuteInput
pickle.dumps(obj) # $ MISSING: encodeInput=obj encodeOutput=pickle.dumps(..) encodeFormat=pickle encodeMayExecuteInput
marshal.dumps(obj) # $ MISSING: encodeInput=obj encodeOutput=marshal.dumps(..) encodeFormat=marshal encodeMayExecuteInput
# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py
base64.b64encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64
base64.standard_b64encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64
base64.urlsafe_b64encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64
base64.b32encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base32
base64.b16encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base16
base64.b64encode(bs) # $ encodeInput=bs encodeOutput=base64.b64encode(..) encodeFormat=Base64
base64.standard_b64encode(bs) # $ encodeInput=bs encodeOutput=base64.standard_b64encode(..) encodeFormat=Base64
base64.urlsafe_b64encode(bs) # $ encodeInput=bs encodeOutput=base64.urlsafe_b64encode(..) encodeFormat=Base64
base64.b32encode(bs) # $ encodeInput=bs encodeOutput=base64.b32encode(..) encodeFormat=Base32
base64.b16encode(bs) # $ encodeInput=bs encodeOutput=base64.b16encode(..) encodeFormat=Base16
# deprecated since Python 3.1, but still works
base64.encodestring(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64
base64.encodestring(bs) # $ encodeInput=bs encodeOutput=base64.encodestring(..) encodeFormat=Base64

View File

@@ -0,0 +1,40 @@
from io import StringIO
import json
def test():
print("\n# test")
ts = TAINTED_STRING
encoded = json.dumps(ts) # $ encodeOutput=json.dumps(..) encodeFormat=JSON encodeInput=ts
ensure_tainted(
encoded, # $ tainted
json.dumps(ts), # $ tainted encodeOutput=json.dumps(..) encodeFormat=JSON encodeInput=ts
json.dumps(obj=ts), # $ tainted encodeOutput=json.dumps(..) encodeFormat=JSON encodeInput=ts
json.loads(encoded), # $ tainted decodeOutput=json.loads(..) decodeFormat=JSON decodeInput=encoded
json.loads(s=encoded), # $ tainted decodeOutput=json.loads(..) decodeFormat=JSON decodeInput=encoded
)
# load/dump with file-like
tainted_filelike = StringIO()
json.dump(ts, tainted_filelike) # $ encodeOutput=[post]tainted_filelike encodeFormat=JSON encodeInput=ts
tainted_filelike.seek(0)
ensure_tainted(
tainted_filelike, # $ tainted
json.load(tainted_filelike), # $ tainted decodeOutput=json.load(..) decodeFormat=JSON decodeInput=tainted_filelike
)
# load/dump with file-like using keyword-args
tainted_filelike = StringIO()
json.dump(obj=ts, fp=tainted_filelike) # $ encodeOutput=[post]tainted_filelike encodeFormat=JSON encodeInput=ts
tainted_filelike.seek(0)
ensure_tainted(
tainted_filelike, # $ tainted
json.load(fp=tainted_filelike), # $ tainted decodeOutput=json.load(..) decodeFormat=JSON decodeInput=tainted_filelike
)
# Make tests runable
test()

View File

@@ -5,19 +5,19 @@ def test():
ts = TAINTED_STRING
tainted_obj = {"foo": ts}
encoded = ujson.dumps(tainted_obj) # $ encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj
encoded = ujson.dumps(tainted_obj) # $ encodeOutput=ujson.dumps(..) encodeFormat=JSON encodeInput=tainted_obj
ensure_tainted(
encoded, # $ tainted
ujson.dumps(tainted_obj), # $ tainted encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj
ujson.dumps(obj=tainted_obj), # $ tainted encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj
ujson.loads(encoded), # $ tainted decodeOutput=Attribute() decodeFormat=JSON decodeInput=encoded
ujson.loads(obj=encoded), # $ tainted decodeOutput=Attribute() decodeFormat=JSON decodeInput=encoded
ujson.dumps(tainted_obj), # $ tainted encodeOutput=ujson.dumps(..) encodeFormat=JSON encodeInput=tainted_obj
ujson.dumps(obj=tainted_obj), # $ tainted encodeOutput=ujson.dumps(..) encodeFormat=JSON encodeInput=tainted_obj
ujson.loads(encoded), # $ tainted decodeOutput=ujson.loads(..) decodeFormat=JSON decodeInput=encoded
ujson.loads(obj=encoded), # $ tainted decodeOutput=ujson.loads(..) decodeFormat=JSON decodeInput=encoded
ujson.encode(tainted_obj), # $ tainted encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj
ujson.encode(obj=tainted_obj), # $ tainted encodeOutput=Attribute() encodeFormat=JSON encodeInput=tainted_obj
ujson.decode(encoded), # $ tainted decodeOutput=Attribute() decodeFormat=JSON decodeInput=encoded
ujson.decode(obj=encoded), # $ tainted decodeOutput=Attribute() decodeFormat=JSON decodeInput=encoded
ujson.encode(tainted_obj), # $ tainted encodeOutput=ujson.encode(..) encodeFormat=JSON encodeInput=tainted_obj
ujson.encode(obj=tainted_obj), # $ tainted encodeOutput=ujson.encode(..) encodeFormat=JSON encodeInput=tainted_obj
ujson.decode(encoded), # $ tainted decodeOutput=ujson.decode(..) decodeFormat=JSON decodeInput=encoded
ujson.decode(obj=encoded), # $ tainted decodeOutput=ujson.decode(..) decodeFormat=JSON decodeInput=encoded
)
# load/dump with file-like
@@ -27,7 +27,7 @@ def test():
tainted_filelike.seek(0)
ensure_tainted(
tainted_filelike, # $ MISSING: tainted
ujson.load(tainted_filelike), # $ decodeOutput=Attribute() decodeFormat=JSON decodeInput=tainted_filelike MISSING: tainted
ujson.load(tainted_filelike), # $ decodeOutput=ujson.load(..) decodeFormat=JSON decodeInput=tainted_filelike MISSING: tainted
)
# load/dump with file-like using keyword-args does not work in `ujson`

View File

@@ -1,37 +1,37 @@
import yaml
# Unsafe:
yaml.load(payload) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput
yaml.load(payload, yaml.Loader) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput
yaml.unsafe_load(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput
yaml.full_load(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput
yaml.load(payload) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
yaml.load(payload, yaml.Loader) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
yaml.unsafe_load(payload) # $ decodeInput=payload decodeOutput=yaml.unsafe_load(..) decodeFormat=YAML decodeMayExecuteInput
yaml.full_load(payload) # $ decodeInput=payload decodeOutput=yaml.full_load(..) decodeFormat=YAML decodeMayExecuteInput
# Safe:
yaml.load(payload, yaml.SafeLoader) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML
yaml.load(payload, Loader=yaml.SafeLoader) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML
yaml.load(payload, yaml.BaseLoader) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML
yaml.safe_load(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML
yaml.load(payload, yaml.SafeLoader) # $ decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML
yaml.load(payload, Loader=yaml.SafeLoader) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML
yaml.load(payload, yaml.BaseLoader) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML
yaml.safe_load(payload) # $ decodeInput=payload decodeOutput=yaml.safe_load(..) decodeFormat=YAML
################################################################################
# load_all variants
################################################################################
# Unsafe:
yaml.load_all(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput
yaml.unsafe_load_all(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput
yaml.full_load_all(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput
yaml.load_all(payload) # $ decodeInput=payload decodeOutput=yaml.load_all(..) decodeFormat=YAML decodeMayExecuteInput
yaml.unsafe_load_all(payload) # $ decodeInput=payload decodeOutput=yaml.unsafe_load_all(..) decodeFormat=YAML decodeMayExecuteInput
yaml.full_load_all(payload) # $ decodeInput=payload decodeOutput=yaml.full_load_all(..) decodeFormat=YAML decodeMayExecuteInput
# Safe:
yaml.safe_load_all(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML
yaml.safe_load_all(payload) # $ decodeInput=payload decodeOutput=yaml.safe_load_all(..) decodeFormat=YAML
################################################################################
# C-based loaders with `libyaml`
################################################################################
# Unsafe:
yaml.load(payload, yaml.CLoader) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput
yaml.load(payload, yaml.CFullLoader) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML decodeMayExecuteInput
yaml.load(payload, yaml.CLoader) # $ decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
yaml.load(payload, yaml.CFullLoader) # $ decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
# Safe:
yaml.load(payload, yaml.CSafeLoader) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML
yaml.load(payload, yaml.CBaseLoader) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=YAML
yaml.load(payload, yaml.CSafeLoader) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML
yaml.load(payload, yaml.CBaseLoader) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML