mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Python: Add Encoding concept
I wasn't able to find a good opposite of "parsing", so left that out of the list of intended purposes.
This commit is contained in:
@@ -6,8 +6,9 @@
|
||||
|
||||
import python
|
||||
private import experimental.dataflow.DataFlow
|
||||
private import experimental.semmle.python.Frameworks
|
||||
private import experimental.dataflow.RemoteFlowSources
|
||||
private import experimental.dataflow.TaintTracking
|
||||
private import experimental.semmle.python.Frameworks
|
||||
|
||||
/**
|
||||
* A data-flow node that executes an operating system command,
|
||||
@@ -165,6 +166,55 @@ module Decoding {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that encodes data to a binary or textual format. This
|
||||
* is intended to include serialization, marshalling, encoding, pickling,
|
||||
* compressing, encrypting, etc.
|
||||
*
|
||||
* Doing so should normally preserve taint.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `Encoding::Range` instead.
|
||||
*/
|
||||
class Encoding extends DataFlow::Node {
|
||||
Encoding::Range range;
|
||||
|
||||
Encoding() { this = range }
|
||||
|
||||
/** Gets an input that is encoded by this function. */
|
||||
DataFlow::Node getAnInput() { result = range.getAnInput() }
|
||||
|
||||
/** Gets the output that contains the encoded data produced by this function. */
|
||||
DataFlow::Node getOutput() { result = range.getOutput() }
|
||||
|
||||
/** Gets an identifier for the format this function decodes from, such as "JSON". */
|
||||
string getFormat() { result = range.getFormat() }
|
||||
}
|
||||
|
||||
/** Provides a class for modeling new encoding mechanisms. */
|
||||
module Encoding {
|
||||
/**
|
||||
* A data-flow node that encodes data to a binary or textual format. This
|
||||
* is intended to include serialization, marshalling, encoding, pickling,
|
||||
* compressing, encrypting, etc.
|
||||
*
|
||||
* Doing so should normally preserve taint.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `Encoding` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets an input that is encoded by this function. */
|
||||
abstract DataFlow::Node getAnInput();
|
||||
|
||||
/** Gets the output that contains the encoded data produced by this function. */
|
||||
abstract DataFlow::Node getOutput();
|
||||
|
||||
/** Gets an identifier for the format this function decodes from, such as "JSON". */
|
||||
abstract string getFormat();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that dynamically executes Python code.
|
||||
*
|
||||
|
||||
@@ -73,6 +73,38 @@ class DecodingTest extends InlineExpectationsTest {
|
||||
}
|
||||
}
|
||||
|
||||
class EncodingTest extends InlineExpectationsTest {
|
||||
EncodingTest() { this = "EncodingTest" }
|
||||
|
||||
override string getARelevantTag() { result in ["encodeInput", "encodeOutput", "encodeFormat"] }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
exists(Encoding e |
|
||||
exists(DataFlow::Node data |
|
||||
location = data.getLocation() and
|
||||
element = data.toString() and
|
||||
value = value_from_expr(data.asExpr()) and
|
||||
(
|
||||
data = e.getAnInput() and
|
||||
tag = "encodeInput"
|
||||
or
|
||||
data = e.getOutput() and
|
||||
tag = "encodeOutput"
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(string format |
|
||||
location = e.getLocation() and
|
||||
element = format and
|
||||
value = format and
|
||||
format = e.getFormat() and
|
||||
tag = "encodeFormat"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class CodeExecutionTest extends InlineExpectationsTest {
|
||||
CodeExecutionTest() { this = "CodeExecutionTest" }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user