Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eff244d

Browse files
committed
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.
1 parent b78234f commit eff244d

2 files changed

Lines changed: 83 additions & 1 deletion

File tree

python/ql/src/experimental/semmle/python/Concepts.qll

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66

77
import python
88
private import experimental.dataflow.DataFlow
9-
private import experimental.semmle.python.Frameworks
109
private import experimental.dataflow.RemoteFlowSources
10+
private import experimental.dataflow.TaintTracking
11+
private import experimental.semmle.python.Frameworks
1112

1213
/**
1314
* A data-flow node that executes an operating system command,
@@ -165,6 +166,55 @@ module Decoding {
165166
}
166167
}
167168

169+
/**
170+
* A data-flow node that encodes data to a binary or textual format. This
171+
* is intended to include serialization, marshalling, encoding, pickling,
172+
* compressing, encrypting, etc.
173+
*
174+
* Doing so should normally preserve taint.
175+
*
176+
* Extend this class to refine existing API models. If you want to model new APIs,
177+
* extend `Encoding::Range` instead.
178+
*/
179+
class Encoding extends DataFlow::Node {
180+
Encoding::Range range;
181+
182+
Encoding() { this = range }
183+
184+
/** Gets an input that is encoded by this function. */
185+
DataFlow::Node getAnInput() { result = range.getAnInput() }
186+
187+
/** Gets the output that contains the encoded data produced by this function. */
188+
DataFlow::Node getOutput() { result = range.getOutput() }
189+
190+
/** Gets an identifier for the format this function decodes from, such as "JSON". */
191+
string getFormat() { result = range.getFormat() }
192+
}
193+
194+
/** Provides a class for modeling new encoding mechanisms. */
195+
module Encoding {
196+
/**
197+
* A data-flow node that encodes data to a binary or textual format. This
198+
* is intended to include serialization, marshalling, encoding, pickling,
199+
* compressing, encrypting, etc.
200+
*
201+
* Doing so should normally preserve taint.
202+
*
203+
* Extend this class to model new APIs. If you want to refine existing API models,
204+
* extend `Encoding` instead.
205+
*/
206+
abstract class Range extends DataFlow::Node {
207+
/** Gets an input that is encoded by this function. */
208+
abstract DataFlow::Node getAnInput();
209+
210+
/** Gets the output that contains the encoded data produced by this function. */
211+
abstract DataFlow::Node getOutput();
212+
213+
/** Gets an identifier for the format this function decodes from, such as "JSON". */
214+
abstract string getFormat();
215+
}
216+
}
217+
168218
/**
169219
* A data-flow node that dynamically executes Python code.
170220
*

python/ql/test/experimental/meta/ConceptsTest.qll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,38 @@ class DecodingTest extends InlineExpectationsTest {
7373
}
7474
}
7575

76+
class EncodingTest extends InlineExpectationsTest {
77+
EncodingTest() { this = "EncodingTest" }
78+
79+
override string getARelevantTag() { result in ["encodeInput", "encodeOutput", "encodeFormat"] }
80+
81+
override predicate hasActualResult(Location location, string element, string tag, string value) {
82+
exists(location.getFile().getRelativePath()) and
83+
exists(Encoding e |
84+
exists(DataFlow::Node data |
85+
location = data.getLocation() and
86+
element = data.toString() and
87+
value = value_from_expr(data.asExpr()) and
88+
(
89+
data = e.getAnInput() and
90+
tag = "encodeInput"
91+
or
92+
data = e.getOutput() and
93+
tag = "encodeOutput"
94+
)
95+
)
96+
or
97+
exists(string format |
98+
location = e.getLocation() and
99+
element = format and
100+
value = format and
101+
format = e.getFormat() and
102+
tag = "encodeFormat"
103+
)
104+
)
105+
}
106+
}
107+
76108
class CodeExecutionTest extends InlineExpectationsTest {
77109
CodeExecutionTest() { this = "CodeExecutionTest" }
78110

0 commit comments

Comments
 (0)