You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/language/ql-training-rst/cpp/data-flow-cpp.rst
+4-155Lines changed: 4 additions & 155 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -112,164 +112,13 @@ We need something better.
112
112
113
113
Here, ``DMLOut`` and ``ExtOut`` are macros that expand to formatting calls. The format specifier is not constant, in the sense that the format argument is not a string literal. However, it is clearly one of two possible constants, both with the same number of format specifiers.
114
114
115
-
What we need is a way to determine whether the format argument is ever set to something that is not constant.
115
+
What we need is a way to determine whether the format argument is ever set to something that is, not constant.
116
116
117
-
Data flow analysis
118
-
==================
117
+
.. include general data flow slides
119
118
120
-
- Models flow of data through the program.
121
-
- Implemented in the module ``semmle.code.cpp.dataflow.DataFlow``.
122
-
- Class ``DataFlow::Node`` represents program elements that have a value, such as expressions and function parameters.
- Various predicated represent flow between these nodes.
127
-
128
-
- Edges of the data flow graph.
129
-
130
-
.. note::
131
-
132
-
The solution here is to use *data flow*. Data flow is, as the name suggests, about tracking the flow of data through the program. It helps answers questions like: *does this expression ever hold a value that originates from a particular other place in the program*?
133
-
134
-
We can visualize the data flow problem as one of finding paths through a directed graph, where the nodes of the graph are elements in the program, and the edges represent the flow of data between those elements. If a path exists, then the data flows between those two edges.
a [label=<tainted<BR /><FONT POINT-SIZE="10">ParameterNode</FONT>>]
166
-
b [label=<tainted<BR /><FONT POINT-SIZE="10">ExprNode</FONT>>]
167
-
c [label=<x<BR /><FONT POINT-SIZE="10">ExprNode</FONT>>]
168
-
d [label=<x<BR /><FONT POINT-SIZE="10">ExprNode</FONT>>]
169
-
e [label=<y<BR /><FONT POINT-SIZE="10">ExprNode</FONT>>]
170
-
171
-
a -> b
172
-
b -> {c, d}
173
-
c -> e
174
-
175
-
}
176
-
177
-
Local vs global data flow
178
-
=========================
179
-
180
-
- Local (“intra-procedural”) data flow models flow within one function; feasible to compute for all functions in a snapshot
181
-
- Global (“inter-procedural”) data flow models flow across function calls; not feasible to compute for all functions in a snapshot
182
-
- Different APIs, so discussed separately
183
-
- This slide deck focuses on the former.
184
-
185
-
.. note::
186
-
187
-
For further information, see:
188
-
189
-
- `Introduction to data flow analysis in QL <https://help.semmle.com/QL/learn-ql/ql/intro-to-data-flow.html>`__
190
-
- `Analyzing data flow in C/C++ <https://help.semmle.com/QL/learn-ql/ql/cpp/dataflow.html>`__
191
-
192
-
.. rst-class:: background2
193
-
194
-
Local data flow
195
-
===============
196
-
197
-
Importing data flow
198
-
===================
199
-
200
-
To use the data flow library, add the following import:
201
-
202
-
.. code-block:: ql
203
-
204
-
import semmle.code.cpp.dataflow.DataFlow
205
-
206
-
**Note**: this library contains an explicit “module” declaration:
207
-
208
-
.. code-block:: ql
209
-
210
-
module DataFlow {
211
-
class Node extends ... { ... }
212
-
predicate localFlow(Node source, Node sink) {
213
-
localFlowStep*(source, sink)
214
-
}
215
-
...
216
-
}
217
-
218
-
So all references will need to be qualified (that is, ``DataFlow::Node``)
219
-
220
-
.. note::
221
-
222
-
A **query library** is file with the extension ``.qll``. Query libraries do not contain a query clause, but may contain modules, classes, and predicates. For example, the `C/C++ data flow library <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/dataflow/DataFlow.qll/module.DataFlow.html>`__ is contained in the ``semmle/code/cpp/dataflow/DataFlow.qll`` QLL file, and can be imported as shown above.
223
-
224
-
A **module** is a way of organizing QL code by grouping together related predicates, classes, and (sub-)modules. They can be either explicitly declared or implicit. A query library implicitly declares a module with the same name as the QLL file.
225
-
226
-
For further information on libraries and modules in QL, see the chapter on `Modules <https://help.semmle.com/QL/ql-handbook/modules.html>`__ in the QL language handbook.
227
-
228
-
For further information on importing QL libraries and modules, see the chapter on `Name resolution <https://help.semmle.com/QL/ql-handbook/name-resolution.html>`__ in the QL language handbook.
229
-
230
-
Data flow graph
231
-
===============
232
-
233
-
- Class ``DataFlow::Node`` represents data flow graph nodes
234
-
- Predicate ``DataFlow::localFlowStep`` represents local data flow graph edges, ``DataFlow::localFlow`` is its transitive closure
235
-
- Data flow graph nodes are *not* AST nodes, but they correspond to AST nodes, and there are predicates for mapping between them:
The ``DataFlow::Node`` class is shared between both the local and global data flow graphs–the primary difference is the edges, which in the “global” case can link different functions.
246
-
247
-
``localFlowStep`` is the “single step” flow relation–that is, it describes single edges in the local data flow graph. ``localFlow`` represents the `transitive <https://help.semmle.com/QL/ql-handbook/recursion.html#transitive-closures>`__ closure of this relation–in other words, it contains every pair of nodes where the second node is reachable from the first in the data flow graph.
248
-
249
-
The data flow graph is separate from the `AST <https://en.wikipedia.org/wiki/Abstract_syntax_tree>`__, to allow for flexibility in how data flow is modeled. There are a small number of data flow node types–expression nodes, parameter nodes, uninitialized variable nodes, and definition by reference nodes. Each node provides mapping functions to and from the relevant AST (for example ``Expr``, ``Parameter`` etc.) or symbol table (for example ``Variable``) classes.
250
-
251
-
Taint tracking
252
-
==============
253
-
254
-
- Usually, we want to generalise slightly by not only considering plain data flow, but also “taint” propagation, that is, whether a value is influenced by or derived from another.
255
-
256
-
- Examples:
257
-
258
-
.. code-block:: cpp
259
-
260
-
sink = source; // source -> sink: data and taint
261
-
strcat(sink, source); // source -> sink: taint, not data
262
-
263
-
- Library ``semmle.code.cpp.dataflow.TaintTracking`` provides predicates for tracking taint:
264
-
265
-
- ``TaintTracking::localTaintStep`` represents one (local) taint step
266
-
- ``TaintTracking::localTaint`` is its transitive closure.
267
-
268
-
.. note::
269
-
270
-
Taint tracking can be thought of as another type of data flow graph. It usually extends the standard data flow graph for a problem by adding edges between nodes where one one node influences or *taints* another.
271
-
272
-
The `API <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/dataflow/TaintTracking.qll/module.TaintTracking.html>`__ is almost identical to that of the local data flow. All we need to do to switch to taint tracking is ``import semmle.code.cpp.dataflow.TaintTracking`` instead of ``semmle.code.cpp.dataflow.DataFlow``, and instead of using ``localFlow``, we use ``localTaint``.
Copy file name to clipboardExpand all lines: docs/language/ql-training-rst/cpp/global-data-flow-cpp.rst
+6-70Lines changed: 6 additions & 70 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,57 +36,12 @@ Agenda
36
36
- Path queries
37
37
- Data flow models
38
38
39
-
Information flow
40
-
================
41
-
42
-
- Many security problems can be phrased as an information flow problem:
43
-
44
-
Given a (problem-specific) set of sources and sinks, is there a path in the data flow graph from some source to some sink?
45
-
46
-
- Some examples:
47
-
48
-
- SQL injection: sources are user-input, sinks are SQL queries
49
-
- Reflected XSS: sources are HTTP requests, sinks are HTTP responses
50
-
51
-
- We can solve such problems using the data flow and taint tracking libraries.
52
-
53
-
Global data flow and taint tracking
54
-
===================================
55
-
56
-
- Recap:
57
-
58
-
- Local (“intra-procedural”) data flow models flow within one function; feasible to compute for all functions in a snapshot
59
-
- Global (“inter-procedural”) data flow models flow across function calls; not feasible to compute for all functions in a snapshot
60
-
61
-
- For global data flow (and taint tracking), we must therefore provide restrictions to ensure the problem is tractable.
62
-
- Typically, this involves specifying the *source* and *sink*.
63
-
64
-
.. note::
65
-
66
-
As we mentioned in the previous slide deck, while local data flow is feasible to compute for all functions in a snapshot, global data flow is not. This is because the number of paths becomes exponentially larger for global data flow.
67
-
68
-
The global data flow (and taint tracking) avoids this problem by requiring that the query author specifies which ``sources`` and ``sinks`` are applicable. This allows the implementation to compute paths between the restricted set of nodes, rather than the full graph.
#. Use ``Config.hasFlow(source, sink)`` to find inter-procedural paths.
86
-
87
-
.. note::
88
-
89
-
In addition to the taint tracking configuration described here, there is also an equivalent *data flow* configuration in ``semmle.code.cpp.dataflow.DataFlow``, ``DataFlow::Configuration``. Data flow configurations are used to track whether the exact value produced by a source is used by a sink, whereas taint tracking configurations are used to determine whether the source may influence the value used at the sink. Whether you use taint tracking or data flow depends on the analysis problem you are trying to solve.
90
45
91
46
Finding tainted format strings (outline)
92
47
========================================
@@ -164,30 +119,11 @@ Use the ``FormattingFunction`` class, we can write the sink as:
164
119
165
120
When we run this query, we should find a single result. However, it is tricky to determine whether this result is a true positive (a “real” result) because our query only reports the source and the sink, and not the path through the graph between the two.
166
121
167
-
Path queries
168
-
============
169
-
170
-
Path queries provide information about the identified paths from sources to sinks. Paths can be examined in Path Explorer view.
122
+
.. insert path queries slides
171
123
172
-
Use this template:
173
-
174
-
.. code-block:: ql
175
-
176
-
/**
177
-
* ...
178
-
* @kind path-problem
179
-
*/
180
-
181
-
import semmle.code.cpp.dataflow.TaintTracking
182
-
import DataFlow::PathGraph
183
-
...
184
-
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
185
-
where cfg.hasFlowPath(source, sink)
186
-
select sink, source, sink, "<message>"
187
-
188
-
.. note::
124
+
.. include:: ../slide-snippets/path-queries.rst
189
125
190
-
To see the paths between the source and the sinks, we can convert the query to a path problem query. There are a few minor changes that need to be made for this to work–we need an additional import, to specify ``PathNode`` rather than ``Node``, and to add the source/sink to the query output (so that we can automatically determine the paths).
126
+
.. resume language-specific global data flow slides
Copy file name to clipboardExpand all lines: docs/language/ql-training-rst/java/global-data-flow-java.rst
+7-72Lines changed: 7 additions & 72 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,59 +36,13 @@ Agenda
36
36
- Path queries
37
37
- Data flow models
38
38
39
-
Information flow
40
-
================
41
-
42
-
- Many security problems can be phrased as an information flow problem:
43
-
44
-
Given a (problem-specific) set of sources and sinks, is there a path in the data flow graph from some source to some sink?
45
-
46
-
- Some examples:
47
-
48
-
- SQL injection: sources are user-input, sinks are SQL queries
49
-
- Reflected XSS: sources are HTTP requests, sinks are HTTP responses
50
-
51
-
- We can solve such problems using the data flow and taint tracking libraries.
52
-
53
-
Global data flow and taint tracking
54
-
===================================
55
-
56
-
- Recap:
57
-
58
-
- Local (“intra-procedural”) data flow models flow within one function; feasible to compute for all functions in a snapshot
59
-
- Global (“inter-procedural”) data flow models flow across function calls; not feasible to compute for all functions in a snapshot
60
-
61
-
- For global data flow (and taint tracking), we must therefore provided restrictions to ensure the problem is tractable.
62
-
- Typically, this involves specifying the *source* and *sink*.
63
-
64
-
.. note::
65
-
66
-
As we mentioned in the previous slide deck, while local data flow is feasible to compute for all functions in a snapshot, global data flow is not. This is because the number of paths becomes exponentially larger for global data flow.
67
-
68
-
The global data flow (and taint tracking) avoids this problem by requiring that the query author specifies which ``sources`` and ``sinks`` are applicable. This allows the implementation to compute paths between the restricted set of nodes, rather than the full graph.
#. Use ``Config.hasFlow(source, sink)`` to find inter-procedural paths.
86
-
87
-
.. note::
88
-
89
-
In addition to the taint tracking configuration described here, there is also an equivalent *data flow* configuration in ``semmle.code.java.dataflow.DataFlow``, ``DataFlow::Configuration``. Data flow configurations are used to track whether the exact value produced by a source is used by a sink, whereas taint tracking configurations are used to determine whether the source may influence the value used at the sink. Whether you use taint tracking or data flow depends on the analysis problem you are trying to solve.
90
-
91
-
Code injection in Apache Struts
45
+
Code injection in Apache struts
92
46
===============================
93
47
94
48
- In April 2018, Man Yue Mo, a security researcher at Semmle, reported 5 remote code execution (RCE) vulnerabilities (CVE-2018-11776) in Apache Struts.
@@ -181,30 +135,11 @@ Find a method access to ``compileAndExecute``, and mark the first argument.
181
135
...
182
136
}
183
137
184
-
Path queries
185
-
============
138
+
.. insert path queries slides
186
139
187
-
Path queries provide information about the identified paths from sources to sinks. Paths can be examined in Path Explorer view.
188
-
189
-
Use this template:
190
-
191
-
.. code-block:: ql
192
-
193
-
/**
194
-
* ...
195
-
* @kind path-problem
196
-
*/
197
-
198
-
import semmle.code.java.dataflow.TaintTracking
199
-
import DataFlow::PathGraph
200
-
...
201
-
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
202
-
where cfg.hasFlowPath(source, sink)
203
-
select sink, source, sink, "<message>"
204
-
205
-
.. note::
140
+
.. include:: ../slide-snippets/path-queries.rst
206
141
207
-
To see the paths between the source and the sinks, we can convert the query to a path problem query. There are a few minor changes that need to be made for this to work - we need an additional import, to specify ``PathNode`` rather than ``Node``, and to add the source/sink to the query output (so that we can automatically determine the paths).
142
+
.. resume language-specific global data flow slides
0 commit comments