mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
Bring headings more into line with content models
This commit is contained in:
@@ -31,7 +31,8 @@ An annotated flow graph:
|
||||
|
||||
The simplest use of the ``ControlFlowNode`` and ``AstNode`` classes is to find unreachable code. There is one ``ControlFlowNode`` per path through any ``AstNode`` and any ``AstNode`` that is unreachable has no paths flowing through it. Therefore, any ``AstNode`` without a corresponding ``ControlFlowNode`` is unreachable.
|
||||
|
||||
**Unreachable AST nodes**
|
||||
Example finding unreachable AST nodes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
@@ -43,7 +44,8 @@ The simplest use of the ``ControlFlowNode`` and ``AstNode`` classes is to find u
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/669220024/>`__. The demo projects on LGTM.com all have some code that has no control flow node, and is therefore unreachable. However, since the ``Module`` class is also a subclass of the ``AstNode`` class, the query also finds any modules implemented in C or with no source code. Therefore, it is better to find all unreachable statements:
|
||||
|
||||
**Unreachable statements**
|
||||
Example finding unreachable statements
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
@@ -60,8 +62,8 @@ The ``BasicBlock`` class
|
||||
|
||||
The ``BasicBlock`` class represents a `basic block <http://en.wikipedia.org/wiki/Basic_block>`__ of control flow nodes. The ``BasicBlock`` class is not that useful for writing queries directly, but is very useful for building complex analyses, such as data flow. The reason it is useful is that it shares many of the interesting properties of control flow nodes, such as what can reach what and what `dominates <http://en.wikipedia.org/wiki/Dominator_%28graph_theory%29>`__ what, but there are fewer basic blocks than control flow nodes - resulting in queries that are faster and use less memory.
|
||||
|
||||
Example: Finding mutually exclusive basic blocks
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Example finding mutually exclusive basic blocks
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Suppose we have the following Python code:
|
||||
|
||||
@@ -92,7 +94,8 @@ However, by that definition, two basic blocks are mutually exclusive if they are
|
||||
|
||||
Combining these conditions we get:
|
||||
|
||||
**Mutually exclusive blocks within the same function**
|
||||
Example finding mutually exclusive blocks within the same function
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ Functions in Python
|
||||
|
||||
Functions are key building blocks of Python code bases. You can find functions and identify calls to them using syntactic classes from the standard CodeQL library.
|
||||
|
||||
This example uses the standard CodeQL class ``Function`` (see :doc:`Introducing the Python libraries <introduce-libraries-python>`).
|
||||
These examples use the standard CodeQL class `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__. For more information, see :doc:`Introducing the Python libraries <introduce-libraries-python>`.
|
||||
|
||||
Finding all functions called "get..."
|
||||
-------------------------------------
|
||||
|
||||
@@ -3,15 +3,15 @@ CodeQL library for Python
|
||||
|
||||
Overview of the extensive library you use to analyze databases generated from Python code bases. This library uses classes with abstractions and predicates to present the data in an object-oriented form. This abstraction makes it easier for you to write queries.
|
||||
|
||||
About the CodeQL library for Python
|
||||
-----------------------------------
|
||||
|
||||
The CodeQL library for each programming language is implemented as a set of QL modules, that is, files with the extension ``.qll``. The module ``python.qll`` imports all the core Python library modules, so you can include the complete library by beginning your query with:
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
import python
|
||||
|
||||
The rest of this tutorial summarizes the contents of the standard libraries for Python. We recommend that you read this and then work through the practical examples in the tutorials shown at the end of the page.
|
||||
|
||||
Overview of the library
|
||||
-----------------------
|
||||
|
||||
The CodeQL library for Python incorporates a large number of classes. Each class corresponds either to one kind of entity in Python source code or to an entity that can be derived from the source code using static analysis. These classes can be divided into four categories:
|
||||
|
||||
- **Syntactic** - classes that represent entities in the Python source code.
|
||||
@@ -20,16 +20,16 @@ The CodeQL library for Python incorporates a large number of classes. Each class
|
||||
- **Taint tracking** - classes that represent the source, sinks and kinds of taint used to implement taint-tracking queries.
|
||||
|
||||
Syntactic classes
|
||||
~~~~~~~~~~~~~~~~~
|
||||
-----------------
|
||||
|
||||
This part of the library represents the Python source code. The ``Module``, ``Class``, and ``Function`` classes correspond to Python modules, classes, and functions respectively, collectively these are known as ``Scope`` classes. Each ``Scope`` contains a list of statements each of which is represented by a subclass of the class ``Stmt``. Statements themselves can contain other statements or expressions which are represented by subclasses of ``Expr``. Finally, there are a few additional classes for the parts of more complex expressions such as list comprehensions. Collectively these classes are subclasses of ``AstNode`` and form an `Abstract syntax tree <http://en.wikipedia.org/wiki/Abstract_syntax_tree>`__ (AST). The root of each AST is a ``Module``.
|
||||
This part of the library represents the Python source code. The ``Module``, ``Class``, and ``Function`` classes correspond to Python modules, classes, and functions respectively, collectively these are known as ``Scope`` classes. Each ``Scope`` contains a list of statements each of which is represented by a subclass of the class ``Stmt``. Statements themselves can contain other statements or expressions which are represented by subclasses of ``Expr``. Finally, there are a few additional classes for the parts of more complex expressions such as list comprehensions. Collectively these classes are subclasses of ``AstNode`` and form an Abstract syntax tree (AST). The root of each AST is a ``Module``. For more information, see `Abstract syntax tree <http://en.wikipedia.org/wiki/Abstract_syntax_tree>`__.
|
||||
|
||||
`Symbolic information <http://en.wikipedia.org/wiki/Symbol_table>`__ is attached to the AST in the form of variables (represented by the class ``Variable``).
|
||||
Symbolic information is attached to the AST in the form of variables (represented by the class ``Variable``). For more information, see `Symbolic information <http://en.wikipedia.org/wiki/Symbol_table>`__.
|
||||
|
||||
Scope
|
||||
^^^^^
|
||||
|
||||
A Python program is a group of modules. Technically a module is just a list of statements, but we often think of it as composed of classes and functions. These top-level entities, the module, class, and function are represented by the three CodeQL classes (`Module <https://help.semmle.com/qldoc/python/semmle/python/Module.qll/type.Module$Module.html>`__, `Class <https://help.semmle.com/qldoc/python/semmle/python/Class.qll/type.Class$Class.html>`__ and `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__ which are all subclasses of ``Scope``.
|
||||
A Python program is a group of modules. Technically a module is just a list of statements, but we often think of it as composed of classes and functions. These top-level entities, the module, class, and function are represented by the three CodeQL classes (`Module <https://help.semmle.com/qldoc/python/semmle/python/Module.qll/type.Module$Module.html>`__, `Class <https://help.semmle.com/qldoc/python/semmle/python/Class.qll/type.Class$Class.html>`__ and `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__ which are all subclasses of ``Scope``).
|
||||
|
||||
- ``Scope``
|
||||
|
||||
@@ -153,8 +153,8 @@ Both forms are equivalent. Using the positive expression, the whole query looks
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/690010036/>`__. Many projects include pass-only ``except`` blocks.
|
||||
|
||||
Summary
|
||||
^^^^^^^
|
||||
Summary of syntactic classes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The most commonly used standard classes in the syntactic part of the library are organized as follows:
|
||||
|
||||
@@ -237,11 +237,14 @@ Other
|
||||
- ``Comment`` – A comment
|
||||
|
||||
Control flow classes
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
--------------------
|
||||
|
||||
This part of the library represents the control flow graph of each ``Scope`` (classes, functions, and modules). Each ``Scope`` contains a graph of ``ControlFlowNode`` elements. Each scope has a single entry point and at least one (potentially many) exit points. To speed up control and data flow analysis, control flow nodes are grouped into `basic blocks <http://en.wikipedia.org/wiki/Basic_block>`__.
|
||||
|
||||
As an example, we might want to find the longest sequence of code without any branches. A ``BasicBlock`` is, by definition, a sequence of code without any branches, so we just need to find the longest ``BasicBlock``.
|
||||
Example
|
||||
^^^^^^^
|
||||
|
||||
If we want to find the longest sequence of code without any branches, we need to consider control flow. A ``BasicBlock`` is, by definition, a sequence of code without any branches, so we just need to find the longest ``BasicBlock``.
|
||||
|
||||
First of all we introduce a simple predicate ``bb_length()`` which relates ``BasicBlock``\ s to their length.
|
||||
|
||||
@@ -289,7 +292,12 @@ The classes in the control-flow part of the library are:
|
||||
Type-inference classes
|
||||
----------------------
|
||||
|
||||
The CodeQL library for Python also supplies some classes for accessing the inferred types of values. The classes ``Value`` and ``ClassValue`` allow you to query the possible classes that an expression may have at runtime. For example, which ``ClassValue``\ s are iterable can be determined using the query:
|
||||
The CodeQL library for Python also supplies some classes for accessing the inferred types of values. The classes ``Value`` and ``ClassValue`` allow you to query the possible classes that an expression may have at runtime.
|
||||
|
||||
Example
|
||||
^^^^^^^
|
||||
|
||||
For example, which ``ClassValue``\ s are iterable can be determined using the query:
|
||||
|
||||
**Find iterable "ClassValue"s**
|
||||
|
||||
@@ -304,7 +312,7 @@ The CodeQL library for Python also supplies some classes for accessing the infer
|
||||
➤ `See this in the query console <https://lgtm.com/query/5151030165280978402/>`__ This query returns a list of classes for the projects analyzed. If you want to include the results for `builtin classes <http://docs.python.org/library/stdtypes.html>`__, which do not have any Python source code, show the non-source results.
|
||||
|
||||
Summary
|
||||
~~~~~~~
|
||||
^^^^^^^
|
||||
|
||||
- `Value <https://help.semmle.com/qldoc/python/semmle/python/objects/ObjectAPI.qll/type.ObjectAPI$Value.html>`__
|
||||
|
||||
@@ -312,7 +320,7 @@ Summary
|
||||
- ``CallableValue``
|
||||
- ``ModuleValue``
|
||||
|
||||
These classes are explained in more detail in :doc:`Tutorial: Points-to analysis and type inference <pointsto-type-infer>`.
|
||||
For more information about these classes, see :doc:`Pointer analysis and type inference in Python <pointsto-type-infer>`.
|
||||
|
||||
Taint-tracking classes
|
||||
----------------------
|
||||
@@ -321,12 +329,12 @@ The CodeQL library for Python also supplies classes to specify taint-tracking an
|
||||
|
||||
|
||||
Summary
|
||||
~~~~~~~
|
||||
^^^^^^^
|
||||
|
||||
- `TaintKind <https://help.semmle.com/qldoc/python/semmle/python/dataflow/TaintTracking.qll/type.TaintTracking$TaintKind.html>`__
|
||||
- `Configuration <https://help.semmle.com/qldoc/python/semmle/python/dataflow/Configuration.qll/type.Configuration$TaintTracking$Configuration.html>`__
|
||||
|
||||
These classes are explained in more detail in :doc:`Tutorial: Taint tracking and data flow analysis in Python <taint-tracking>`.
|
||||
For more information about these classes, see :doc:`Analyzing data flow and tracking tainted data in Python <taint-tracking>`.
|
||||
|
||||
|
||||
Further reading
|
||||
|
||||
@@ -3,6 +3,7 @@ Pointer analysis and type inference in Python
|
||||
|
||||
At run time, each Python expression has a value with an associated type. You can learn how an expression behaves at run time using type-inference classes from the standard CodeQL library.
|
||||
|
||||
|
||||
This topic contains worked examples of how to write queries using the standard CodeQL library classes for Python type inference.
|
||||
|
||||
The ``Value`` class
|
||||
@@ -11,7 +12,7 @@ The ``Value`` class
|
||||
The ``Value`` class and its subclasses ``FunctionValue``, ``ClassValue``, and ``ModuleValue`` represent the values an expression may hold at runtime.
|
||||
|
||||
Summary
|
||||
~~~~~~~
|
||||
^^^^^^^
|
||||
|
||||
Class hierarchy for ``Value``:
|
||||
|
||||
|
||||
@@ -39,13 +39,11 @@ Here is the full class hierarchy:
|
||||
- ``While`` – A ``while`` statement
|
||||
- ``With`` – A ``with`` statement
|
||||
|
||||
Example: Finding redundant 'global' statements
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Example finding redundant 'global' statements
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``global`` statement in Python declares a variable with a global (module-level) scope, when it would otherwise be local. Using the ``global`` statement outside a class or function is redundant as the variable is already global.
|
||||
|
||||
**Finding redundant global statements**
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
import python
|
||||
@@ -58,13 +56,11 @@ The ``global`` statement in Python declares a variable with a global (module-lev
|
||||
|
||||
The line: ``g.getScope() instanceof Module`` ensures that the ``Scope`` of ``Global g`` is a ``Module``, rather than a class or function.
|
||||
|
||||
Example: Finding 'if' statements with redundant branches
|
||||
--------------------------------------------------------
|
||||
Example finding 'if' statements with redundant branches
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
An ``if`` statement where one branch is composed of just ``pass`` statements could be simplified by negating the condition and dropping the ``else`` clause.
|
||||
|
||||
**An 'if' statement that could be simplified**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if cond():
|
||||
@@ -72,9 +68,7 @@ An ``if`` statement where one branch is composed of just ``pass`` statements cou
|
||||
else:
|
||||
do_something
|
||||
|
||||
To find statements like this we can run the following query:
|
||||
|
||||
**Find 'if' statements with empty branches**
|
||||
To find statements like this that could be simplified we can write a query.
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
@@ -133,8 +127,8 @@ Each kind of Python expression has its own class. Here is the full class hierarc
|
||||
- ``Yield`` – A ``yield`` expression
|
||||
- ``YieldFrom`` – A ``yield from`` expression (Python 3.3+)
|
||||
|
||||
Example: Finding comparisons to integer or string literals using 'is'
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Example finding comparisons to integer or string literals using 'is'
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Python implementations commonly cache small integers and single character strings, which means that comparisons such as the following often work correctly, but this is not guaranteed and we might want to check for them.
|
||||
|
||||
@@ -143,9 +137,7 @@ Python implementations commonly cache small integers and single character string
|
||||
x is 10
|
||||
x is "A"
|
||||
|
||||
We can check for these as follows:
|
||||
|
||||
**Find comparisons to integer or string literals using** ``is``
|
||||
We can check for these using a query.
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
@@ -166,15 +158,11 @@ The clause ``cmp.getOp(0) instanceof Is and cmp.getComparator(0) = literal`` che
|
||||
|
||||
We have to use ``cmp.getOp(0)`` and ``cmp.getComparator(0)``\ as there is no ``cmp.getOp()`` or ``cmp.getComparator()``. The reason for this is that a ``Compare`` expression can have multiple operators. For example, the expression ``3 < x < 7`` has two operators and two comparators. You use ``cmp.getComparator(0)`` to get the first comparator (in this example the ``3``) and ``cmp.getComparator(1)`` to get the second comparator (in this example the ``7``).
|
||||
|
||||
Example: Duplicates in dictionary literals
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Example finding duplicates in dictionary literals
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If there are duplicate keys in a Python dictionary, then the second key will overwrite the first, which is almost certainly a mistake. We can find these duplicates with CodeQL, but the query is more complex than previous examples and will require us to write a ``predicate`` as a helper.
|
||||
|
||||
Here is the query:
|
||||
|
||||
**Find duplicate dictionary keys**
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
import python
|
||||
@@ -206,12 +194,10 @@ is equivalent to
|
||||
|
||||
The short version is usually used as this is easier to read.
|
||||
|
||||
Example: Finding Java-style getters
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Example finding Java-style getters
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Returning to the example from :doc:`Tutorial: Functions <functions>`, the query identified all methods with a single line of code and a name starting with ``get``:
|
||||
|
||||
**Basic: Find Java-style getters**
|
||||
Returning to the example from :doc:`Tutorial: Functions <functions>`, the query identified all methods with a single line of code and a name starting with ``get``.
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
@@ -222,9 +208,7 @@ Returning to the example from :doc:`Tutorial: Functions <functions>`, the query
|
||||
and count(f.getAStmt()) = 1
|
||||
select f, "This function is (probably) a getter."
|
||||
|
||||
This basic query can be improved by checking that the one line of code is of the form ``return self.attr``
|
||||
|
||||
**Improved: Find Java-style getters**
|
||||
This basic query can be improved by checking that the one line of code is a Java-style getter of the form ``return self.attr``.
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
@@ -238,21 +222,17 @@ This basic query can be improved by checking that the one line of code is of the
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/669220054/>`__. Of the demo projects on LGTM.com, only the *openstack/nova* project has examples of functions that appear to be Java-style getters.
|
||||
|
||||
In this query, the condition:
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
ret = f.getStmt(0) and ret.getValue() = attr
|
||||
|
||||
checks that the first line in the method is a return statement and that the expression returned (``ret.getValue()``) is an ``Attribute`` expression. Note that the equality ``ret.getValue() = attr`` means that ``ret.getValue()`` is restricted to ``Attribute``\ s, since ``attr`` is an ``Attribute``.
|
||||
|
||||
The condition:
|
||||
This condition checks that the first line in the method is a return statement and that the expression returned (``ret.getValue()``) is an ``Attribute`` expression. Note that the equality ``ret.getValue() = attr`` means that ``ret.getValue()`` is restricted to ``Attribute``\ s, since ``attr`` is an ``Attribute``.
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
attr.getObject() = self and self.getId() = "self"
|
||||
|
||||
checks that the value of the attribute (the expression to the left of the dot in ``value.attr``) is an access to a variable called ``"self"``.
|
||||
This condition checks that the value of the attribute (the expression to the left of the dot in ``value.attr``) is an access to a variable called ``"self"``.
|
||||
|
||||
Class and function definitions
|
||||
------------------------------
|
||||
|
||||
@@ -3,8 +3,8 @@ Analyzing data flow and tracking tainted data in Python
|
||||
|
||||
You can use CodeQL to track the flow of data through a Python program to its use. Tracking user-controlled, or tainted, data is a key technique for security researchers.
|
||||
|
||||
Overview
|
||||
--------
|
||||
About data flow and taint tracking
|
||||
----------------------------------
|
||||
|
||||
Taint tracking is used to analyze how potentially insecure, or 'tainted' data flows throughout a program at runtime.
|
||||
You can use taint tracking to find out whether user-controlled input can be used in a malicious way,
|
||||
@@ -16,12 +16,12 @@ For example, in the assignment ``dir = path + "/"``, if ``path`` is tainted then
|
||||
even though there is no data flow from ``path`` to ``path + "/"``.
|
||||
|
||||
Separate CodeQL libraries have been written to handle 'normal' data flow and taint tracking in :doc:`C/C++ <../cpp/dataflow>`, :doc:`C# <../csharp/dataflow>`, :doc:`Java <../java/dataflow>`, and :doc:`JavaScript <../javascript/dataflow>`. You can access the appropriate classes and predicates that reason about these different modes of data flow by importing the appropriate library in your query.
|
||||
In Python analysis, we can use the same taint tracking library to model both 'normal' data flow and taint flow, but we are still able make the distinction between steps that preserve value and those that don't by defining additional data flow properties.
|
||||
In Python analysis, we can use the same taint tracking library to model both 'normal' data flow and taint flow, but we are still able make the distinction between steps that preserve values and those that don't by defining additional data flow properties.
|
||||
|
||||
For further information on data flow and taint tracking with CodeQL, see :doc:`Introduction to data flow <../intro-to-data-flow>`.
|
||||
|
||||
Fundamentals of taint tracking and data flow analysis
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Fundamentals of taint tracking using data flow analysis
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The taint tracking library is in the `TaintTracking <https://help.semmle.com/qldoc/python/semmle/python/dataflow/TaintTracking.qll/module.TaintTracking.html>`__ module.
|
||||
Any taint tracking or data flow analysis query has three explicit components, one of which is optional, and an implicit component.
|
||||
@@ -41,7 +41,7 @@ The kind of taint determines which non-value-preserving steps are possible, in a
|
||||
In the above example ``dir = path + "/"``, taint flows from ``path`` to ``dir`` if the taint represents a string, but not if the taint is ``None``.
|
||||
|
||||
Limitations
|
||||
~~~~~~~~~~~
|
||||
^^^^^^^^^^^
|
||||
|
||||
Although taint tracking is a powerful technique, it is worth noting that it depends on the underlying data flow graphs.
|
||||
Creating a data flow graph that is both accurate and covers a large enough part of a program is a challenge,
|
||||
@@ -81,6 +81,9 @@ A simple taint tracking query has the basic form:
|
||||
where config.hasFlow(src, sink)
|
||||
select sink, "Alert message, including reference to $@.", src, "string describing the source"
|
||||
|
||||
Example
|
||||
^^^^^^^
|
||||
|
||||
As a contrived example, here is a query that looks for flow from a HTTP request to a function called ``"unsafe"``.
|
||||
The sources are predefined and accessed by importing library ``semmle.python.web.HttpRequest``.
|
||||
The sink is defined by using a custom ``TaintTracking::Sink`` class.
|
||||
@@ -128,8 +131,8 @@ The sink is defined by using a custom ``TaintTracking::Sink`` class.
|
||||
|
||||
|
||||
|
||||
Implementing path queries
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Converting a taint-tracking query to a path query
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Although the taint tracking query above tells which sources flow to which sinks, it doesn't tell us how.
|
||||
For that we need a path query.
|
||||
@@ -204,8 +207,8 @@ Thus, our example query becomes:
|
||||
|
||||
|
||||
|
||||
Custom taint kinds and flows
|
||||
----------------------------
|
||||
Tracking custom taint kinds and flows
|
||||
-------------------------------------
|
||||
|
||||
In the above examples, we have assumed the existence of a suitable ``TaintKind``,
|
||||
but sometimes it is necessary to model the flow of other objects, such as database connections, or ``None``.
|
||||
|
||||
Reference in New Issue
Block a user