mirror of
https://github.com/hohn/codeql-info.git
synced 2025-12-16 20:53:04 +01:00
546 lines
36 KiB
HTML
546 lines
36 KiB
HTML
<!DOCTYPE html>
|
|
|
|
<html lang="en" data-content_root="../">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
|
|
<title>Analyzing data flow in Java — CodeQL</title>
|
|
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=fa44fd50" />
|
|
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=93459777" />
|
|
<script src="../_static/documentation_options.js?v=5929fcd5"></script>
|
|
<script src="../_static/doctools.js?v=888ff710"></script>
|
|
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
|
<link rel="icon" href="../_static/favicon.ico"/>
|
|
<link rel="index" title="Index" href="../genindex.html" />
|
|
<link rel="search" title="Search" href="../search.html" />
|
|
<link rel="next" title="Types in Java" href="types-in-java.html" />
|
|
<link rel="prev" title="CodeQL library for Java" href="codeql-library-for-java.html" />
|
|
|
|
<title>CodeQL docs</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
|
|
<link rel="stylesheet" href="../_static/primer.css" type="text/css" />
|
|
|
|
|
|
</head><body>
|
|
<header class="Header">
|
|
<div class="Header-item--full">
|
|
<a href="https://codeql.github.com/docs" class="Header-link f2 d-flex flex-items-center">
|
|
<!-- <%= octicon "mark-github", class: "mr-2", height: 32 %> -->
|
|
<svg height="32" class="octicon octicon-mark-github mr-2" viewBox="0 0 16 16" version="1.1" width="32"
|
|
aria-hidden="true">
|
|
<path fill-rule="evenodd"
|
|
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z">
|
|
</path>
|
|
</svg>
|
|
<span class="hide-sm">CodeQL documentation</span>
|
|
</a>
|
|
</div>
|
|
<div class="Header-item hide-sm hide-md">
|
|
<script src="https://addsearch.com/js/?key=93b4d287e2fc079a4089412b669785d5&categories=!0xhelp.semmle.com,0xcodeql.github.com,1xdocs,1xcodeql-standard-libraries,1xcodeql-query-help"></script>
|
|
</div>
|
|
<div class="Header-item">
|
|
|
|
<details class="dropdown details-reset details-overlay d-inline-block">
|
|
<summary class="btn bg-gray-dark text-white border" aria-haspopup="true">
|
|
CodeQL resources
|
|
<div class="dropdown-caret"></div>
|
|
</summary>
|
|
|
|
<ul class="dropdown-menu dropdown-menu-se dropdown-menu-dark">
|
|
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-overview">CodeQL overview</a></li>
|
|
<li class="dropdown-divider" role="separator"></li>
|
|
<div class="dropdown-header">
|
|
CodeQL tools
|
|
</div>
|
|
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-for-visual-studio-code">CodeQL for VS Code</a>
|
|
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-cli">CodeQL CLI</a>
|
|
</li>
|
|
<li class="dropdown-divider" role="separator"></li>
|
|
<div class="dropdown-header">
|
|
CodeQL guides
|
|
</div>
|
|
<li><a class="dropdown-item" href="https://codeql.github.com/docs/writing-codeql-queries">Writing CodeQL queries</a></li>
|
|
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-language-guides">CodeQL language guides</a>
|
|
<li class="dropdown-divider" role="separator"></li>
|
|
<div class="dropdown-header">
|
|
Reference docs
|
|
</div>
|
|
<li><a class="dropdown-item" href="https://codeql.github.com/docs/ql-language-reference/">QL language
|
|
reference</a>
|
|
<li><a class="dropdown-item" href="https://codeql.github.com/codeql-standard-libraries">CodeQL
|
|
standard-libraries</a>
|
|
<li><a class="dropdown-item" href="https://codeql.github.com/codeql-query-help">CodeQL
|
|
query help</a>
|
|
<li class="dropdown-divider" role="separator"></li>
|
|
<div class="dropdown-header">
|
|
Source files
|
|
</div>
|
|
<li><a class="dropdown-item" href="https://github.com/github/codeql">CodeQL repository</a>
|
|
</ul>
|
|
</details>
|
|
|
|
</div>
|
|
|
|
</header>
|
|
<main class="bg-gray-light clearfix">
|
|
<nav class="SideNav position-sticky top-0 col-lg-3 col-md-3 float-left p-4 hide-sm hide-md overflow-y-auto">
|
|
|
|
<ul class="current">
|
|
<li class="toctree-l1"><a class="reference internal" href="../codeql-overview/index.html">CodeQL overview</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../codeql-for-visual-studio-code/index.html">CodeQL for Visual Studio Code</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../codeql-cli/index.html">CodeQL CLI</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../writing-codeql-queries/index.html">Writing CodeQL queries</a></li>
|
|
<li class="toctree-l1 current"><a class="reference internal" href="index.html">CodeQL language guides</a><ul class="current">
|
|
<li class="toctree-l2"><a class="reference internal" href="codeql-for-cpp.html">CodeQL for C and C++</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="codeql-for-csharp.html">CodeQL for C#</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="codeql-for-go.html">CodeQL for Go</a></li>
|
|
<li class="toctree-l2 current"><a class="reference internal" href="codeql-for-java.html">CodeQL for Java</a><ul class="current">
|
|
<li class="toctree-l3"><a class="reference internal" href="basic-query-for-java-code.html">Basic query for Java code</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="codeql-library-for-java.html">CodeQL library for Java</a></li>
|
|
<li class="toctree-l3 current"><a class="current reference internal" href="#">Analyzing data flow in Java</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="types-in-java.html">Types in Java</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="overflow-prone-comparisons-in-java.html">Overflow-prone comparisons in Java</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="navigating-the-call-graph.html">Navigating the call graph</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="annotations-in-java.html">Annotations in Java</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="javadoc.html">Javadoc</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="working-with-source-locations.html">Working with source locations</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="abstract-syntax-tree-classes-for-working-with-java-programs.html">Abstract syntax tree classes for working with Java programs</a></li>
|
|
</ul>
|
|
</li>
|
|
<li class="toctree-l2"><a class="reference internal" href="codeql-for-javascript.html">CodeQL for JavaScript</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="codeql-for-python.html">CodeQL for Python</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="codeql-for-ruby.html">CodeQL for Ruby</a></li>
|
|
</ul>
|
|
</li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../ql-language-reference/index.html">QL language reference</a></li>
|
|
</ul>
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
<div class="body col-sm-12 col-md-9 col-lg-9 float-left border-left">
|
|
|
|
<div class="hide-lg hide-xl px-4 pt-4">
|
|
|
|
<div class="related" role="navigation" aria-label="related navigation">
|
|
<ul>
|
|
<li class="nav-item nav-item-0"><a href="../contents.html">CodeQL</a> »</li>
|
|
<li class="nav-item nav-item-1"><a href="index.html"
|
|
>CodeQL language guides</a> »</li>
|
|
<li class="nav-item nav-item-2"><a href="codeql-for-java.html"
|
|
accesskey="U">CodeQL for Java</a> »</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<article class="p-4 col-lg-10 col-md-10 col-sm-12">
|
|
|
|
<section id="analyzing-data-flow-in-java">
|
|
<span id="id1"></span><h1>Analyzing data flow in Java<a class="headerlink" href="#analyzing-data-flow-in-java" title="Link to this heading">¶</a></h1>
|
|
<p>You can use CodeQL to track the flow of data through a Java program to its use.</p>
|
|
<section id="about-this-article">
|
|
<h2>About this article<a class="headerlink" href="#about-this-article" title="Link to this heading">¶</a></h2>
|
|
<p>This article describes how data flow analysis is implemented in the CodeQL libraries for Java and includes examples to help you write your own data flow queries.
|
|
The following sections describe how to use the libraries for local data flow, global data flow, and taint tracking.</p>
|
|
<p>For a more general introduction to modeling data flow, see “<a class="reference internal" href="../writing-codeql-queries/about-data-flow-analysis.html#about-data-flow-analysis"><span class="std std-ref">About data flow analysis</span></a>.”</p>
|
|
</section>
|
|
<section id="local-data-flow">
|
|
<h2>Local data flow<a class="headerlink" href="#local-data-flow" title="Link to this heading">¶</a></h2>
|
|
<p>Local data flow is data flow within a single method or callable. Local data flow is usually easier, faster, and more precise than global data flow, and is sufficient for many queries.</p>
|
|
<section id="using-local-data-flow">
|
|
<h3>Using local data flow<a class="headerlink" href="#using-local-data-flow" title="Link to this heading">¶</a></h3>
|
|
<p>The local data flow library is in the module <code class="docutils literal notranslate"><span class="pre">DataFlow</span></code>, which defines the class <code class="docutils literal notranslate"><span class="pre">Node</span></code> denoting any element that data can flow through. <code class="docutils literal notranslate"><span class="pre">Node</span></code>s are divided into expression nodes (<code class="docutils literal notranslate"><span class="pre">ExprNode</span></code>) and parameter nodes (<code class="docutils literal notranslate"><span class="pre">ParameterNode</span></code>). You can map between data flow nodes and expressions/parameters using the member predicates <code class="docutils literal notranslate"><span class="pre">asExpr</span></code> and <code class="docutils literal notranslate"><span class="pre">asParameter</span></code>:</p>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>class Node {
|
|
/** Gets the expression corresponding to this node, if any. */
|
|
Expr asExpr() { ... }
|
|
|
|
/** Gets the parameter corresponding to this node, if any. */
|
|
Parameter asParameter() { ... }
|
|
|
|
...
|
|
}
|
|
</pre></div>
|
|
</div>
|
|
<p>or using the predicates <code class="docutils literal notranslate"><span class="pre">exprNode</span></code> and <code class="docutils literal notranslate"><span class="pre">parameterNode</span></code>:</p>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>/**
|
|
* Gets the node corresponding to expression `e`.
|
|
*/
|
|
ExprNode exprNode(Expr e) { ... }
|
|
|
|
/**
|
|
* Gets the node corresponding to the value of parameter `p` at function entry.
|
|
*/
|
|
ParameterNode parameterNode(Parameter p) { ... }
|
|
</pre></div>
|
|
</div>
|
|
<p>The predicate <code class="docutils literal notranslate"><span class="pre">localFlowStep(Node</span> <span class="pre">nodeFrom,</span> <span class="pre">Node</span> <span class="pre">nodeTo)</span></code> holds if there is an immediate data flow edge from the node <code class="docutils literal notranslate"><span class="pre">nodeFrom</span></code> to the node <code class="docutils literal notranslate"><span class="pre">nodeTo</span></code>. You can apply the predicate recursively by using the <code class="docutils literal notranslate"><span class="pre">+</span></code> and <code class="docutils literal notranslate"><span class="pre">*</span></code> operators, or by using the predefined recursive predicate <code class="docutils literal notranslate"><span class="pre">localFlow</span></code>, which is equivalent to <code class="docutils literal notranslate"><span class="pre">localFlowStep*</span></code>.</p>
|
|
<p>For example, you can find flow from a parameter <code class="docutils literal notranslate"><span class="pre">source</span></code> to an expression <code class="docutils literal notranslate"><span class="pre">sink</span></code> in zero or more local steps:</p>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>DataFlow::localFlow(DataFlow::parameterNode(source), DataFlow::exprNode(sink))
|
|
</pre></div>
|
|
</div>
|
|
</section>
|
|
<section id="using-local-taint-tracking">
|
|
<h3>Using local taint tracking<a class="headerlink" href="#using-local-taint-tracking" title="Link to this heading">¶</a></h3>
|
|
<p>Local taint tracking extends local data flow by including non-value-preserving flow steps. For example:</p>
|
|
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="n">String</span><span class="w"> </span><span class="n">temp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">;</span>
|
|
<span class="n">String</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">temp</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s">", "</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">temp</span><span class="p">;</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>If <code class="docutils literal notranslate"><span class="pre">x</span></code> is a tainted string then <code class="docutils literal notranslate"><span class="pre">y</span></code> is also tainted.</p>
|
|
<p>The local taint tracking library is in the module <code class="docutils literal notranslate"><span class="pre">TaintTracking</span></code>. Like local data flow, a predicate <code class="docutils literal notranslate"><span class="pre">localTaintStep(DataFlow::Node</span> <span class="pre">nodeFrom,</span> <span class="pre">DataFlow::Node</span> <span class="pre">nodeTo)</span></code> holds if there is an immediate taint propagation edge from the node <code class="docutils literal notranslate"><span class="pre">nodeFrom</span></code> to the node <code class="docutils literal notranslate"><span class="pre">nodeTo</span></code>. You can apply the predicate recursively by using the <code class="docutils literal notranslate"><span class="pre">+</span></code> and <code class="docutils literal notranslate"><span class="pre">*</span></code> operators, or by using the predefined recursive predicate <code class="docutils literal notranslate"><span class="pre">localTaint</span></code>, which is equivalent to <code class="docutils literal notranslate"><span class="pre">localTaintStep*</span></code>.</p>
|
|
<p>For example, you can find taint propagation from a parameter <code class="docutils literal notranslate"><span class="pre">source</span></code> to an expression <code class="docutils literal notranslate"><span class="pre">sink</span></code> in zero or more local steps:</p>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>TaintTracking::localTaint(DataFlow::parameterNode(source), DataFlow::exprNode(sink))
|
|
</pre></div>
|
|
</div>
|
|
</section>
|
|
<section id="examples">
|
|
<h3>Examples<a class="headerlink" href="#examples" title="Link to this heading">¶</a></h3>
|
|
<p>This query finds the filename passed to <code class="docutils literal notranslate"><span class="pre">new</span> <span class="pre">FileReader(..)</span></code>.</p>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import java
|
|
|
|
from Constructor fileReader, Call call
|
|
where
|
|
fileReader.getDeclaringType().hasQualifiedName("java.io", "FileReader") and
|
|
call.getCallee() = fileReader
|
|
select call.getArgument(0)
|
|
</pre></div>
|
|
</div>
|
|
<p>Unfortunately, this only gives the expression in the argument, not the values which could be passed to it. So we use local data flow to find all expressions that flow into the argument:</p>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import java
|
|
import semmle.code.java.dataflow.DataFlow
|
|
|
|
from Constructor fileReader, Call call, Expr src
|
|
where
|
|
fileReader.getDeclaringType().hasQualifiedName("java.io", "FileReader") and
|
|
call.getCallee() = fileReader and
|
|
DataFlow::localFlow(DataFlow::exprNode(src), DataFlow::exprNode(call.getArgument(0)))
|
|
select src
|
|
</pre></div>
|
|
</div>
|
|
<p>Then we can make the source more specific, for example an access to a public parameter. This query finds where a public parameter is passed to <code class="docutils literal notranslate"><span class="pre">new</span> <span class="pre">FileReader(..)</span></code>:</p>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import java
|
|
import semmle.code.java.dataflow.DataFlow
|
|
|
|
from Constructor fileReader, Call call, Parameter p
|
|
where
|
|
fileReader.getDeclaringType().hasQualifiedName("java.io", "FileReader") and
|
|
call.getCallee() = fileReader and
|
|
DataFlow::localFlow(DataFlow::parameterNode(p), DataFlow::exprNode(call.getArgument(0)))
|
|
select p
|
|
</pre></div>
|
|
</div>
|
|
<p>This query finds calls to formatting functions where the format string is not hard-coded.</p>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import java
|
|
import semmle.code.java.dataflow.DataFlow
|
|
import semmle.code.java.StringFormat
|
|
|
|
from StringFormatMethod format, MethodAccess call, Expr formatString
|
|
where
|
|
call.getMethod() = format and
|
|
call.getArgument(format.getFormatStringIndex()) = formatString and
|
|
not exists(DataFlow::Node source, DataFlow::Node sink |
|
|
DataFlow::localFlow(source, sink) and
|
|
source.asExpr() instanceof StringLiteral and
|
|
sink.asExpr() = formatString
|
|
)
|
|
select call, "Argument to String format method isn't hard-coded."
|
|
</pre></div>
|
|
</div>
|
|
</section>
|
|
<section id="exercises">
|
|
<h3>Exercises<a class="headerlink" href="#exercises" title="Link to this heading">¶</a></h3>
|
|
<p>Exercise 1: Write a query that finds all hard-coded strings used to create a <code class="docutils literal notranslate"><span class="pre">java.net.URL</span></code>, using local data flow. (<a class="reference external" href="#exercise-1">Answer</a>)</p>
|
|
</section>
|
|
</section>
|
|
<section id="global-data-flow">
|
|
<h2>Global data flow<a class="headerlink" href="#global-data-flow" title="Link to this heading">¶</a></h2>
|
|
<p>Global data flow tracks data flow throughout the entire program, and is therefore more powerful than local data flow. However, global data flow is less precise than local data flow, and the analysis typically requires significantly more time and memory to perform.</p>
|
|
<blockquote class="pull-quote">
|
|
<div><p>Note</p>
|
|
<p>You can model data flow paths in CodeQL by creating path queries. To view data flow paths generated by a path query in CodeQL for VS Code, you need to make sure that it has the correct metadata and <code class="docutils literal notranslate"><span class="pre">select</span></code> clause. For more information, see <a class="reference internal" href="../writing-codeql-queries/creating-path-queries.html#creating-path-queries"><span class="std std-ref">Creating path queries</span></a>.</p>
|
|
</div></blockquote>
|
|
<section id="using-global-data-flow">
|
|
<h3>Using global data flow<a class="headerlink" href="#using-global-data-flow" title="Link to this heading">¶</a></h3>
|
|
<p>You use the global data flow library by extending the class <code class="docutils literal notranslate"><span class="pre">DataFlow::Configuration</span></code>:</p>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import semmle.code.java.dataflow.DataFlow
|
|
|
|
class MyDataFlowConfiguration extends DataFlow::Configuration {
|
|
MyDataFlowConfiguration() { this = "MyDataFlowConfiguration" }
|
|
|
|
override predicate isSource(DataFlow::Node source) {
|
|
...
|
|
}
|
|
|
|
override predicate isSink(DataFlow::Node sink) {
|
|
...
|
|
}
|
|
}
|
|
</pre></div>
|
|
</div>
|
|
<p>These predicates are defined in the configuration:</p>
|
|
<ul class="simple">
|
|
<li><p><code class="docutils literal notranslate"><span class="pre">isSource</span></code>—defines where data may flow from</p></li>
|
|
<li><p><code class="docutils literal notranslate"><span class="pre">isSink</span></code>—defines where data may flow to</p></li>
|
|
<li><p><code class="docutils literal notranslate"><span class="pre">isBarrier</span></code>—optional, restricts the data flow</p></li>
|
|
<li><p><code class="docutils literal notranslate"><span class="pre">isAdditionalFlowStep</span></code>—optional, adds additional flow steps</p></li>
|
|
</ul>
|
|
<p>The characteristic predicate <code class="docutils literal notranslate"><span class="pre">MyDataFlowConfiguration()</span></code> defines the name of the configuration, so <code class="docutils literal notranslate"><span class="pre">"MyDataFlowConfiguration"</span></code> should be a unique name, for example, the name of your class.</p>
|
|
<p>The data flow analysis is performed using the predicate <code class="docutils literal notranslate"><span class="pre">hasFlow(DataFlow::Node</span> <span class="pre">source,</span> <span class="pre">DataFlow::Node</span> <span class="pre">sink)</span></code>:</p>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>from MyDataFlowConfiguration dataflow, DataFlow::Node source, DataFlow::Node sink
|
|
where dataflow.hasFlow(source, sink)
|
|
select source, "Data flow to $@.", sink, sink.toString()
|
|
</pre></div>
|
|
</div>
|
|
</section>
|
|
<section id="using-global-taint-tracking">
|
|
<h3>Using global taint tracking<a class="headerlink" href="#using-global-taint-tracking" title="Link to this heading">¶</a></h3>
|
|
<p>Global taint tracking is to global data flow as local taint tracking is to local data flow. That is, global taint tracking extends global data flow with additional non-value-preserving steps. You use the global taint tracking library by extending the class <code class="docutils literal notranslate"><span class="pre">TaintTracking::Configuration</span></code>:</p>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import semmle.code.java.dataflow.TaintTracking
|
|
|
|
class MyTaintTrackingConfiguration extends TaintTracking::Configuration {
|
|
MyTaintTrackingConfiguration() { this = "MyTaintTrackingConfiguration" }
|
|
|
|
override predicate isSource(DataFlow::Node source) {
|
|
...
|
|
}
|
|
|
|
override predicate isSink(DataFlow::Node sink) {
|
|
...
|
|
}
|
|
}
|
|
</pre></div>
|
|
</div>
|
|
<p>These predicates are defined in the configuration:</p>
|
|
<ul class="simple">
|
|
<li><p><code class="docutils literal notranslate"><span class="pre">isSource</span></code>—defines where taint may flow from</p></li>
|
|
<li><p><code class="docutils literal notranslate"><span class="pre">isSink</span></code>—defines where taint may flow to</p></li>
|
|
<li><p><code class="docutils literal notranslate"><span class="pre">isSanitizer</span></code>—optional, restricts the taint flow</p></li>
|
|
<li><p><code class="docutils literal notranslate"><span class="pre">isAdditionalTaintStep</span></code>—optional, adds additional taint steps</p></li>
|
|
</ul>
|
|
<p>Similar to global data flow, the characteristic predicate <code class="docutils literal notranslate"><span class="pre">MyTaintTrackingConfiguration()</span></code> defines the unique name of the configuration.</p>
|
|
<p>The taint tracking analysis is performed using the predicate <code class="docutils literal notranslate"><span class="pre">hasFlow(DataFlow::Node</span> <span class="pre">source,</span> <span class="pre">DataFlow::Node</span> <span class="pre">sink)</span></code>.</p>
|
|
</section>
|
|
<section id="flow-sources">
|
|
<h3>Flow sources<a class="headerlink" href="#flow-sources" title="Link to this heading">¶</a></h3>
|
|
<p>The data flow library contains some predefined flow sources. The class <code class="docutils literal notranslate"><span class="pre">RemoteFlowSource</span></code> (defined in <code class="docutils literal notranslate"><span class="pre">semmle.code.java.dataflow.FlowSources</span></code>) represents data flow sources that may be controlled by a remote user, which is useful for finding security problems.</p>
|
|
</section>
|
|
<section id="id2">
|
|
<h3>Examples<a class="headerlink" href="#id2" title="Link to this heading">¶</a></h3>
|
|
<p>This query shows a taint-tracking configuration that uses remote user input as data sources.</p>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import java
|
|
import semmle.code.java.dataflow.FlowSources
|
|
|
|
class MyTaintTrackingConfiguration extends TaintTracking::Configuration {
|
|
MyTaintTrackingConfiguration() {
|
|
this = "..."
|
|
}
|
|
|
|
override predicate isSource(DataFlow::Node source) {
|
|
source instanceof RemoteFlowSource
|
|
}
|
|
|
|
...
|
|
}
|
|
</pre></div>
|
|
</div>
|
|
</section>
|
|
<section id="id3">
|
|
<h3>Exercises<a class="headerlink" href="#id3" title="Link to this heading">¶</a></h3>
|
|
<p>Exercise 2: Write a query that finds all hard-coded strings used to create a <code class="docutils literal notranslate"><span class="pre">java.net.URL</span></code>, using global data flow. (<a class="reference external" href="#exercise-2">Answer</a>)</p>
|
|
<p>Exercise 3: Write a class that represents flow sources from <code class="docutils literal notranslate"><span class="pre">java.lang.System.getenv(..)</span></code>. (<a class="reference external" href="#exercise-3">Answer</a>)</p>
|
|
<p>Exercise 4: Using the answers from 2 and 3, write a query which finds all global data flows from <code class="docutils literal notranslate"><span class="pre">getenv</span></code> to <code class="docutils literal notranslate"><span class="pre">java.net.URL</span></code>. (<a class="reference external" href="#exercise-4">Answer</a>)</p>
|
|
</section>
|
|
</section>
|
|
<section id="answers">
|
|
<h2>Answers<a class="headerlink" href="#answers" title="Link to this heading">¶</a></h2>
|
|
<section id="exercise-1">
|
|
<h3>Exercise 1<a class="headerlink" href="#exercise-1" title="Link to this heading">¶</a></h3>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import semmle.code.java.dataflow.DataFlow
|
|
|
|
from Constructor url, Call call, StringLiteral src
|
|
where
|
|
url.getDeclaringType().hasQualifiedName("java.net", "URL") and
|
|
call.getCallee() = url and
|
|
DataFlow::localFlow(DataFlow::exprNode(src), DataFlow::exprNode(call.getArgument(0)))
|
|
select src
|
|
</pre></div>
|
|
</div>
|
|
</section>
|
|
<section id="exercise-2">
|
|
<h3>Exercise 2<a class="headerlink" href="#exercise-2" title="Link to this heading">¶</a></h3>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import semmle.code.java.dataflow.DataFlow
|
|
|
|
class Configuration extends DataFlow::Configuration {
|
|
Configuration() {
|
|
this = "LiteralToURL Configuration"
|
|
}
|
|
|
|
override predicate isSource(DataFlow::Node source) {
|
|
source.asExpr() instanceof StringLiteral
|
|
}
|
|
|
|
override predicate isSink(DataFlow::Node sink) {
|
|
exists(Call call |
|
|
sink.asExpr() = call.getArgument(0) and
|
|
call.getCallee().(Constructor).getDeclaringType().hasQualifiedName("java.net", "URL")
|
|
)
|
|
}
|
|
}
|
|
|
|
from DataFlow::Node src, DataFlow::Node sink, Configuration config
|
|
where config.hasFlow(src, sink)
|
|
select src, "This string constructs a URL $@.", sink, "here"
|
|
</pre></div>
|
|
</div>
|
|
</section>
|
|
<section id="exercise-3">
|
|
<h3>Exercise 3<a class="headerlink" href="#exercise-3" title="Link to this heading">¶</a></h3>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import java
|
|
|
|
class GetenvSource extends MethodAccess {
|
|
GetenvSource() {
|
|
exists(Method m | m = this.getMethod() |
|
|
m.hasName("getenv") and
|
|
m.getDeclaringType() instanceof TypeSystem
|
|
)
|
|
}
|
|
}
|
|
</pre></div>
|
|
</div>
|
|
</section>
|
|
<section id="exercise-4">
|
|
<h3>Exercise 4<a class="headerlink" href="#exercise-4" title="Link to this heading">¶</a></h3>
|
|
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import semmle.code.java.dataflow.DataFlow
|
|
|
|
class GetenvSource extends DataFlow::ExprNode {
|
|
GetenvSource() {
|
|
exists(Method m | m = this.asExpr().(MethodAccess).getMethod() |
|
|
m.hasName("getenv") and
|
|
m.getDeclaringType() instanceof TypeSystem
|
|
)
|
|
}
|
|
}
|
|
|
|
class GetenvToURLConfiguration extends DataFlow::Configuration {
|
|
GetenvToURLConfiguration() {
|
|
this = "GetenvToURLConfiguration"
|
|
}
|
|
|
|
override predicate isSource(DataFlow::Node source) {
|
|
source instanceof GetenvSource
|
|
}
|
|
|
|
override predicate isSink(DataFlow::Node sink) {
|
|
exists(Call call |
|
|
sink.asExpr() = call.getArgument(0) and
|
|
call.getCallee().(Constructor).getDeclaringType().hasQualifiedName("java.net", "URL")
|
|
)
|
|
}
|
|
}
|
|
|
|
from DataFlow::Node src, DataFlow::Node sink, GetenvToURLConfiguration config
|
|
where config.hasFlow(src, sink)
|
|
select src, "This environment variable constructs a URL $@.", sink, "here"
|
|
</pre></div>
|
|
</div>
|
|
</section>
|
|
</section>
|
|
<section id="further-reading">
|
|
<h2>Further reading<a class="headerlink" href="#further-reading" title="Link to this heading">¶</a></h2>
|
|
<ul class="simple">
|
|
<li><p>“<a class="reference internal" href="../codeql-for-visual-studio-code/exploring-data-flow-with-path-queries.html#exploring-data-flow-with-path-queries"><span class="std std-ref">Exploring data flow with path queries</span></a>”</p></li>
|
|
</ul>
|
|
<ul class="simple">
|
|
<li><p><a class="reference external" href="https://github.com/github/codeql/tree/main/java/ql/src">CodeQL queries for Java</a></p></li>
|
|
<li><p><a class="reference external" href="https://github.com/github/codeql/tree/main/java/ql/examples">Example queries for Java</a></p></li>
|
|
<li><p><a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/java/">CodeQL library reference for Java</a></p></li>
|
|
</ul>
|
|
<ul class="simple">
|
|
<li><p>“<a class="reference internal" href="../ql-language-reference/index.html#ql-language-reference"><span class="std std-ref">QL language reference</span></a>”</p></li>
|
|
<li><p>“<a class="reference internal" href="../codeql-overview/codeql-tools.html#codeql-tools"><span class="std std-ref">CodeQL tools</span></a>”</p></li>
|
|
</ul>
|
|
</section>
|
|
</section>
|
|
|
|
|
|
</article>
|
|
|
|
<!-- GitHub footer, with links to terms and privacy statement -->
|
|
<div class="px-3 px-md-6 f6 py-4 d-sm-flex flex-justify-between flex-row-reverse flex-items-center border-top">
|
|
<ul class="list-style-none d-flex flex-items-center mb-3 mb-sm-0 lh-condensed-ultra">
|
|
<li class="mr-3">
|
|
<a href="https://twitter.com/github" title="GitHub on Twitter" style="color: #959da5;">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 273.5 222.3" class="d-block" height="18">
|
|
<path
|
|
d="M273.5 26.3a109.77 109.77 0 0 1-32.2 8.8 56.07 56.07 0 0 0 24.7-31 113.39 113.39 0 0 1-35.7 13.6 56.1 56.1 0 0 0-97 38.4 54 54 0 0 0 1.5 12.8A159.68 159.68 0 0 1 19.1 10.3a56.12 56.12 0 0 0 17.4 74.9 56.06 56.06 0 0 1-25.4-7v.7a56.11 56.11 0 0 0 45 55 55.65 55.65 0 0 1-14.8 2 62.39 62.39 0 0 1-10.6-1 56.24 56.24 0 0 0 52.4 39 112.87 112.87 0 0 1-69.7 24 119 119 0 0 1-13.4-.8 158.83 158.83 0 0 0 86 25.2c103.2 0 159.6-85.5 159.6-159.6 0-2.4-.1-4.9-.2-7.3a114.25 114.25 0 0 0 28.1-29.1"
|
|
fill="currentColor"></path>
|
|
</svg>
|
|
</a>
|
|
</li>
|
|
<li class="mr-3">
|
|
<a href="https://www.facebook.com/GitHub" title="GitHub on Facebook" style="color: #959da5;">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.3 15.4" class="d-block" height="18">
|
|
<path
|
|
d="M14.5 0H.8a.88.88 0 0 0-.8.9v13.6a.88.88 0 0 0 .8.9h7.3v-6h-2V7.1h2V5.4a2.87 2.87 0 0 1 2.5-3.1h.5a10.87 10.87 0 0 1 1.8.1v2.1h-1.3c-1 0-1.1.5-1.1 1.1v1.5h2.3l-.3 2.3h-2v5.9h3.9a.88.88 0 0 0 .9-.8V.8a.86.86 0 0 0-.8-.8z"
|
|
fill="currentColor"></path>
|
|
</svg>
|
|
</a>
|
|
</li>
|
|
<li class="mr-3">
|
|
<a href="https://www.youtube.com/github" title="GitHub on YouTube" style="color: #959da5;">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.17 13.6" class="d-block" height="16">
|
|
<path
|
|
d="M18.77 2.13A2.4 2.4 0 0 0 17.09.42C15.59 0 9.58 0 9.58 0a57.55 57.55 0 0 0-7.5.4A2.49 2.49 0 0 0 .39 2.13 26.27 26.27 0 0 0 0 6.8a26.15 26.15 0 0 0 .39 4.67 2.43 2.43 0 0 0 1.69 1.71c1.52.42 7.5.42 7.5.42a57.69 57.69 0 0 0 7.51-.4 2.4 2.4 0 0 0 1.68-1.71 25.63 25.63 0 0 0 .4-4.67 24 24 0 0 0-.4-4.69zM7.67 9.71V3.89l5 2.91z"
|
|
fill="currentColor"></path>
|
|
</svg>
|
|
</a>
|
|
</li>
|
|
<li class="mr-3 flex-self-start">
|
|
<a href="https://www.linkedin.com/company/github" title="GitHub on Linkedin" style="color: #959da5;">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19 18" class="d-block" height="18">
|
|
<path
|
|
d="M3.94 2A2 2 0 1 1 2 0a2 2 0 0 1 1.94 2zM4 5.48H0V18h4zm6.32 0H6.34V18h3.94v-6.57c0-3.66 4.77-4 4.77 0V18H19v-7.93c0-6.17-7.06-5.94-8.72-2.91z"
|
|
fill="currentColor"></path>
|
|
</svg>
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="https://github.com/github" title="GitHub's organization" style="color: #959da5;">
|
|
<svg version="1.1" width="20" height="20" viewBox="0 0 16 16" class="octicon octicon-mark-github"
|
|
aria-hidden="true">
|
|
<path fill-rule="evenodd"
|
|
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z">
|
|
</path>
|
|
</svg>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
<ul class="list-style-none d-flex text-gray">
|
|
<li class="mr-3">©
|
|
<script type="text/javascript">document.write(new Date().getFullYear());</script> GitHub, Inc.</li>
|
|
<li class="mr-3"><a
|
|
href="https://docs.github.com/github/site-policy/github-terms-of-service"
|
|
class="link-gray">Terms </a></li>
|
|
<li><a href="https://docs.github.com/github/site-policy/github-privacy-statement"
|
|
class="link-gray">Privacy </a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<script type="text/javascript">
|
|
$(document).ready(function () {
|
|
$(".toggle > *").hide();
|
|
$(".toggle .name").show();
|
|
$(".toggle .name").click(function () {
|
|
$(this).parent().children().not(".name").toggle(400);
|
|
$(this).parent().children(".name").toggleClass("open");
|
|
})
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html> |