mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Merge remote-tracking branch 'origin/main' into jorgectf/python/insecure-cookie
This commit is contained in:
@@ -1,6 +1,17 @@
|
||||
from flask import Flask, request
|
||||
from flask import Flask, request, send_from_directory, send_file
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/save-uploaded-file") # $routeSetup="/save-uploaded-file"
|
||||
def test_taint(): # $requestHandler
|
||||
request.files['key'].save("path") # $ getAPathArgument="path"
|
||||
|
||||
|
||||
@app.route("/path-injection") # $routeSetup="/path-injection"
|
||||
def test_path(): # $requestHandler
|
||||
|
||||
send_from_directory("filepath","file") # $ getAPathArgument="filepath" getAPathArgument="file"
|
||||
send_file("file") # $ getAPathArgument="file"
|
||||
|
||||
send_from_directory(directory="filepath","file") # $ getAPathArgument="filepath" getAPathArgument="file"
|
||||
send_from_directory(filename="filepath","file") # $ getAPathArgument="filepath" getAPathArgument="file"
|
||||
send_file(filename_or_fp="file") # $ getAPathArgument="file"
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.meta.ConceptsTest
|
||||
@@ -0,0 +1,33 @@
|
||||
import ruamel.yaml
|
||||
|
||||
# Unsafe:
|
||||
ruamel.yaml.load(payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
ruamel.yaml.load(stream=payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
ruamel.yaml.load(payload, ruamel.yaml.Loader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
|
||||
# Safe:
|
||||
ruamel.yaml.load(payload, ruamel.yaml.SafeLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
|
||||
ruamel.yaml.load(payload, Loader=ruamel.yaml.SafeLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
|
||||
ruamel.yaml.load(payload, ruamel.yaml.BaseLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
|
||||
ruamel.yaml.safe_load(payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.safe_load(..) decodeFormat=YAML
|
||||
|
||||
################################################################################
|
||||
# load_all variants
|
||||
################################################################################
|
||||
|
||||
# Unsafe:
|
||||
ruamel.yaml.load_all(payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.load_all(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
|
||||
# Safe:
|
||||
ruamel.yaml.safe_load_all(payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.safe_load_all(..) decodeFormat=YAML
|
||||
|
||||
################################################################################
|
||||
# C-based loaders with `libyaml`
|
||||
################################################################################
|
||||
|
||||
# Unsafe:
|
||||
ruamel.yaml.load(payload, ruamel.yaml.CLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
|
||||
# Safe:
|
||||
ruamel.yaml.load(payload, ruamel.yaml.CSafeLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
|
||||
ruamel.yaml.load(payload, ruamel.yaml.CBaseLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
|
||||
63
python/ql/test/library-tests/frameworks/ruamel.yaml/PoC
Normal file
63
python/ql/test/library-tests/frameworks/ruamel.yaml/PoC
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# this file doesn't have a .py extension so the extractor doesn't pick it up, so it
|
||||
# doesn't have to be annotated
|
||||
|
||||
# This file is just a Proof of Concept for how code execution can be triggered.
|
||||
|
||||
import os
|
||||
import ruamel.yaml
|
||||
|
||||
class Exploit(object):
|
||||
def __reduce__(self):
|
||||
return (os.system, ('ls',))
|
||||
|
||||
data = Exploit()
|
||||
serialized_data = ruamel.yaml.dump(data)
|
||||
|
||||
# All these will execute `ls`
|
||||
print("!!! ruamel.yaml.load")
|
||||
ruamel.yaml.load(serialized_data)
|
||||
|
||||
print("!!! ruamel.yaml.load kwarg")
|
||||
ruamel.yaml.load(stream=serialized_data)
|
||||
|
||||
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.Loader")
|
||||
ruamel.yaml.load(serialized_data, ruamel.yaml.Loader)
|
||||
|
||||
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.UnsafeLoader")
|
||||
ruamel.yaml.load(serialized_data, ruamel.yaml.UnsafeLoader)
|
||||
|
||||
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.CLoader")
|
||||
ruamel.yaml.load(serialized_data, ruamel.yaml.CLoader)
|
||||
|
||||
# you need to iterate through the result for it to execute... but it still works
|
||||
print("!!! ruamel.yaml.load_all")
|
||||
for _ in ruamel.yaml.load_all(serialized_data):
|
||||
pass
|
||||
|
||||
# check that the safe version is actually safe
|
||||
print("\n" + "-"*80)
|
||||
print("safe versions")
|
||||
print("-" * 80)
|
||||
|
||||
print("!!! ruamel.yaml.safe_load")
|
||||
try:
|
||||
ruamel.yaml.safe_load(serialized_data)
|
||||
raise Exception("should not happen")
|
||||
except ruamel.yaml.constructor.ConstructorError:
|
||||
pass
|
||||
|
||||
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.SafeLoader")
|
||||
try:
|
||||
ruamel.yaml.load(serialized_data, ruamel.yaml.SafeLoader)
|
||||
raise Exception("should not happen")
|
||||
except ruamel.yaml.constructor.ConstructorError:
|
||||
pass
|
||||
|
||||
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.CSafeLoader")
|
||||
try:
|
||||
ruamel.yaml.load(serialized_data, ruamel.yaml.CSafeLoader)
|
||||
raise Exception("should not happen")
|
||||
except ruamel.yaml.constructor.ConstructorError:
|
||||
pass
|
||||
@@ -2,6 +2,7 @@ import yaml
|
||||
|
||||
# Unsafe:
|
||||
yaml.load(payload) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
yaml.load(stream=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
|
||||
|
||||
58
python/ql/test/library-tests/frameworks/yaml/PoC
Normal file
58
python/ql/test/library-tests/frameworks/yaml/PoC
Normal file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# this file doesn't have a .py extension so the extractor doesn't pick it up, so it
|
||||
# doesn't have to be annotated
|
||||
|
||||
# This file is just a Proof of Concept for how code execution can be triggered.
|
||||
|
||||
|
||||
import os
|
||||
import yaml
|
||||
|
||||
class Exploit(object):
|
||||
def __reduce__(self):
|
||||
return (os.system, ('ls',))
|
||||
|
||||
data = Exploit()
|
||||
serialized_data = yaml.dump(data)
|
||||
|
||||
# All these will execute `ls`
|
||||
print("!!! yaml.unsafe_load")
|
||||
yaml.unsafe_load(serialized_data)
|
||||
|
||||
print("!!! yaml.unsafe_load kwarg")
|
||||
yaml.unsafe_load(stream=serialized_data)
|
||||
|
||||
print("!!! yaml.load with Loader=yaml.UnsafeLoader")
|
||||
yaml.load(serialized_data, yaml.UnsafeLoader)
|
||||
|
||||
# you need to iterate through the result for it to execute... but it still works
|
||||
print("!!! yaml.unsafe_load_all")
|
||||
for _ in yaml.unsafe_load_all(serialized_data):
|
||||
pass
|
||||
|
||||
# check that the safe version is actually safe
|
||||
print("\n" + "-"*80)
|
||||
print("safe versions")
|
||||
print("-" * 80)
|
||||
|
||||
print("!!! yaml.load")
|
||||
try:
|
||||
yaml.load(serialized_data)
|
||||
raise Exception("should not happen")
|
||||
except yaml.constructor.ConstructorError:
|
||||
pass
|
||||
|
||||
print("!!! yaml.safe_load")
|
||||
try:
|
||||
yaml.safe_load(serialized_data)
|
||||
raise Exception("should not happen")
|
||||
except yaml.constructor.ConstructorError:
|
||||
pass
|
||||
|
||||
print("!!! yaml.load with Loader=yaml.SafeLoader")
|
||||
try:
|
||||
yaml.load(serialized_data, yaml.SafeLoader)
|
||||
raise Exception("should not happen")
|
||||
except yaml.constructor.ConstructorError:
|
||||
pass
|
||||
Reference in New Issue
Block a user