mirror of
https://github.com/hohn/codeql-workshop-sql-injection-java.git
synced 2025-12-16 10:43:05 +01:00
Initial clone from https://github.com/advanced-security/codeql-workshops-staging/tree/master/java/codeql-dataflow-sql-injection
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
*~
|
||||||
|
*.html
|
||||||
7
README.org
Normal file
7
README.org
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
* SQL injection example
|
||||||
|
This is an introductory codeql workshop for Java.
|
||||||
|
1. The problem and its source code are in [[./src]] along with a full description in
|
||||||
|
[[./src/README.org]].
|
||||||
|
2. The developed queries are in [[./solutions]] and their tests in [[./tests]]. The
|
||||||
|
derivation of those queries is described in [[./solutions/README.org]]
|
||||||
|
|
||||||
BIN
codeql-overview-for-workshop.pdf
Normal file
BIN
codeql-overview-for-workshop.pdf
Normal file
Binary file not shown.
10
java-demo.code-workspace
Normal file
10
java-demo.code-workspace
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"git.ignoreLimitWarning": true
|
||||||
|
}
|
||||||
|
}
|
||||||
366
solutions/README.html
Normal file
366
solutions/README.html
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- 2023-08-16 Wed 10:26 -->
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>‎</title>
|
||||||
|
<meta name="author" content="Michael Hohn" />
|
||||||
|
<meta name="generator" content="Org Mode" />
|
||||||
|
<style>
|
||||||
|
#content { max-width: 60em; margin: auto; }
|
||||||
|
.title { text-align: center;
|
||||||
|
margin-bottom: .2em; }
|
||||||
|
.subtitle { text-align: center;
|
||||||
|
font-size: medium;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top:0; }
|
||||||
|
.todo { font-family: monospace; color: red; }
|
||||||
|
.done { font-family: monospace; color: green; }
|
||||||
|
.priority { font-family: monospace; color: orange; }
|
||||||
|
.tag { background-color: #eee; font-family: monospace;
|
||||||
|
padding: 2px; font-size: 80%; font-weight: normal; }
|
||||||
|
.timestamp { color: #bebebe; }
|
||||||
|
.timestamp-kwd { color: #5f9ea0; }
|
||||||
|
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
|
||||||
|
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
|
||||||
|
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
|
||||||
|
.underline { text-decoration: underline; }
|
||||||
|
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
|
||||||
|
p.verse { margin-left: 3%; }
|
||||||
|
pre {
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
padding: 8pt;
|
||||||
|
font-family: monospace;
|
||||||
|
overflow: auto;
|
||||||
|
margin: 1.2em;
|
||||||
|
}
|
||||||
|
pre.src {
|
||||||
|
position: relative;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
pre.src:before {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: -8px;
|
||||||
|
right: 12px;
|
||||||
|
padding: 3px;
|
||||||
|
color: #555;
|
||||||
|
background-color: #f2f2f299;
|
||||||
|
}
|
||||||
|
pre.src:hover:before { display: inline; margin-top: 14px;}
|
||||||
|
/* Languages per Org manual */
|
||||||
|
pre.src-asymptote:before { content: 'Asymptote'; }
|
||||||
|
pre.src-awk:before { content: 'Awk'; }
|
||||||
|
pre.src-authinfo::before { content: 'Authinfo'; }
|
||||||
|
pre.src-C:before { content: 'C'; }
|
||||||
|
/* pre.src-C++ doesn't work in CSS */
|
||||||
|
pre.src-clojure:before { content: 'Clojure'; }
|
||||||
|
pre.src-css:before { content: 'CSS'; }
|
||||||
|
pre.src-D:before { content: 'D'; }
|
||||||
|
pre.src-ditaa:before { content: 'ditaa'; }
|
||||||
|
pre.src-dot:before { content: 'Graphviz'; }
|
||||||
|
pre.src-calc:before { content: 'Emacs Calc'; }
|
||||||
|
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
|
||||||
|
pre.src-fortran:before { content: 'Fortran'; }
|
||||||
|
pre.src-gnuplot:before { content: 'gnuplot'; }
|
||||||
|
pre.src-haskell:before { content: 'Haskell'; }
|
||||||
|
pre.src-hledger:before { content: 'hledger'; }
|
||||||
|
pre.src-java:before { content: 'Java'; }
|
||||||
|
pre.src-js:before { content: 'Javascript'; }
|
||||||
|
pre.src-latex:before { content: 'LaTeX'; }
|
||||||
|
pre.src-ledger:before { content: 'Ledger'; }
|
||||||
|
pre.src-lisp:before { content: 'Lisp'; }
|
||||||
|
pre.src-lilypond:before { content: 'Lilypond'; }
|
||||||
|
pre.src-lua:before { content: 'Lua'; }
|
||||||
|
pre.src-matlab:before { content: 'MATLAB'; }
|
||||||
|
pre.src-mscgen:before { content: 'Mscgen'; }
|
||||||
|
pre.src-ocaml:before { content: 'Objective Caml'; }
|
||||||
|
pre.src-octave:before { content: 'Octave'; }
|
||||||
|
pre.src-org:before { content: 'Org mode'; }
|
||||||
|
pre.src-oz:before { content: 'OZ'; }
|
||||||
|
pre.src-plantuml:before { content: 'Plantuml'; }
|
||||||
|
pre.src-processing:before { content: 'Processing.js'; }
|
||||||
|
pre.src-python:before { content: 'Python'; }
|
||||||
|
pre.src-R:before { content: 'R'; }
|
||||||
|
pre.src-ruby:before { content: 'Ruby'; }
|
||||||
|
pre.src-sass:before { content: 'Sass'; }
|
||||||
|
pre.src-scheme:before { content: 'Scheme'; }
|
||||||
|
pre.src-screen:before { content: 'Gnu Screen'; }
|
||||||
|
pre.src-sed:before { content: 'Sed'; }
|
||||||
|
pre.src-sh:before { content: 'shell'; }
|
||||||
|
pre.src-sql:before { content: 'SQL'; }
|
||||||
|
pre.src-sqlite:before { content: 'SQLite'; }
|
||||||
|
/* additional languages in org.el's org-babel-load-languages alist */
|
||||||
|
pre.src-forth:before { content: 'Forth'; }
|
||||||
|
pre.src-io:before { content: 'IO'; }
|
||||||
|
pre.src-J:before { content: 'J'; }
|
||||||
|
pre.src-makefile:before { content: 'Makefile'; }
|
||||||
|
pre.src-maxima:before { content: 'Maxima'; }
|
||||||
|
pre.src-perl:before { content: 'Perl'; }
|
||||||
|
pre.src-picolisp:before { content: 'Pico Lisp'; }
|
||||||
|
pre.src-scala:before { content: 'Scala'; }
|
||||||
|
pre.src-shell:before { content: 'Shell Script'; }
|
||||||
|
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
|
||||||
|
/* additional language identifiers per "defun org-babel-execute"
|
||||||
|
in ob-*.el */
|
||||||
|
pre.src-cpp:before { content: 'C++'; }
|
||||||
|
pre.src-abc:before { content: 'ABC'; }
|
||||||
|
pre.src-coq:before { content: 'Coq'; }
|
||||||
|
pre.src-groovy:before { content: 'Groovy'; }
|
||||||
|
/* additional language identifiers from org-babel-shell-names in
|
||||||
|
ob-shell.el: ob-shell is the only babel language using a lambda to put
|
||||||
|
the execution function name together. */
|
||||||
|
pre.src-bash:before { content: 'bash'; }
|
||||||
|
pre.src-csh:before { content: 'csh'; }
|
||||||
|
pre.src-ash:before { content: 'ash'; }
|
||||||
|
pre.src-dash:before { content: 'dash'; }
|
||||||
|
pre.src-ksh:before { content: 'ksh'; }
|
||||||
|
pre.src-mksh:before { content: 'mksh'; }
|
||||||
|
pre.src-posh:before { content: 'posh'; }
|
||||||
|
/* Additional Emacs modes also supported by the LaTeX listings package */
|
||||||
|
pre.src-ada:before { content: 'Ada'; }
|
||||||
|
pre.src-asm:before { content: 'Assembler'; }
|
||||||
|
pre.src-caml:before { content: 'Caml'; }
|
||||||
|
pre.src-delphi:before { content: 'Delphi'; }
|
||||||
|
pre.src-html:before { content: 'HTML'; }
|
||||||
|
pre.src-idl:before { content: 'IDL'; }
|
||||||
|
pre.src-mercury:before { content: 'Mercury'; }
|
||||||
|
pre.src-metapost:before { content: 'MetaPost'; }
|
||||||
|
pre.src-modula-2:before { content: 'Modula-2'; }
|
||||||
|
pre.src-pascal:before { content: 'Pascal'; }
|
||||||
|
pre.src-ps:before { content: 'PostScript'; }
|
||||||
|
pre.src-prolog:before { content: 'Prolog'; }
|
||||||
|
pre.src-simula:before { content: 'Simula'; }
|
||||||
|
pre.src-tcl:before { content: 'tcl'; }
|
||||||
|
pre.src-tex:before { content: 'TeX'; }
|
||||||
|
pre.src-plain-tex:before { content: 'Plain TeX'; }
|
||||||
|
pre.src-verilog:before { content: 'Verilog'; }
|
||||||
|
pre.src-vhdl:before { content: 'VHDL'; }
|
||||||
|
pre.src-xml:before { content: 'XML'; }
|
||||||
|
pre.src-nxml:before { content: 'XML'; }
|
||||||
|
/* add a generic configuration mode; LaTeX export needs an additional
|
||||||
|
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
|
||||||
|
pre.src-conf:before { content: 'Configuration File'; }
|
||||||
|
|
||||||
|
table { border-collapse:collapse; }
|
||||||
|
caption.t-above { caption-side: top; }
|
||||||
|
caption.t-bottom { caption-side: bottom; }
|
||||||
|
td, th { vertical-align:top; }
|
||||||
|
th.org-right { text-align: center; }
|
||||||
|
th.org-left { text-align: center; }
|
||||||
|
th.org-center { text-align: center; }
|
||||||
|
td.org-right { text-align: right; }
|
||||||
|
td.org-left { text-align: left; }
|
||||||
|
td.org-center { text-align: center; }
|
||||||
|
dt { font-weight: bold; }
|
||||||
|
.footpara { display: inline; }
|
||||||
|
.footdef { margin-bottom: 1em; }
|
||||||
|
.figure { padding: 1em; }
|
||||||
|
.figure p { text-align: center; }
|
||||||
|
.equation-container {
|
||||||
|
display: table;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.equation {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.equation-label {
|
||||||
|
display: table-cell;
|
||||||
|
text-align: right;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.inlinetask {
|
||||||
|
padding: 10px;
|
||||||
|
border: 2px solid gray;
|
||||||
|
margin: 10px;
|
||||||
|
background: #ffffcc;
|
||||||
|
}
|
||||||
|
#org-div-home-and-up
|
||||||
|
{ text-align: right; font-size: 70%; white-space: nowrap; }
|
||||||
|
textarea { overflow-x: auto; }
|
||||||
|
.linenr { font-size: smaller }
|
||||||
|
.code-highlighted { background-color: #ffff00; }
|
||||||
|
.org-info-js_info-navigation { border-style: none; }
|
||||||
|
#org-info-js_console-label
|
||||||
|
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
|
||||||
|
.org-info-js_search-highlight
|
||||||
|
{ background-color: #ffff00; color: #000000; font-weight: bold; }
|
||||||
|
.org-svg { }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="content" class="content">
|
||||||
|
<div id="table-of-contents" role="doc-toc">
|
||||||
|
<h2>Table of Contents</h2>
|
||||||
|
<div id="text-table-of-contents" role="doc-toc">
|
||||||
|
<ul>
|
||||||
|
<li><a href="#org791c6f8">1. Develop the query bottom-up</a></li>
|
||||||
|
<li><a href="#orga2253a0">2. Optional: sarif file review of the results</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="outline-container-org791c6f8" class="outline-2">
|
||||||
|
<h2 id="org791c6f8"><span class="section-number-2">1.</span> Develop the query bottom-up</h2>
|
||||||
|
<div class="outline-text-2" id="text-1">
|
||||||
|
<ol class="org-ol">
|
||||||
|
<li><p>
|
||||||
|
Identify the <i>source</i> part of the
|
||||||
|
</p>
|
||||||
|
<pre class="example">
|
||||||
|
System.console().readLine();
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
expression, the <code>buf</code> argument.
|
||||||
|
Start from a <code>from..where..select</code>, then convert to a predicate.
|
||||||
|
</p></li>
|
||||||
|
|
||||||
|
<li><p>
|
||||||
|
Identify the <i>sink</i> part of the
|
||||||
|
</p>
|
||||||
|
<pre class="example">
|
||||||
|
conn.createStatement().executeUpdate(query);
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
expression, the <code>query</code> argument. Again start from <code>from..where..select</code>,
|
||||||
|
then convert to a predicate.
|
||||||
|
</p></li>
|
||||||
|
|
||||||
|
<li><p>
|
||||||
|
Fill in the <i>taintflow configuration</i> boilerplate
|
||||||
|
</p>
|
||||||
|
<div class="org-src-container">
|
||||||
|
<pre class="src src-java"><span style="color: #a020f0;">class</span> <span style="color: #228b22;">SqliFlowConfig</span> <span style="color: #a020f0;">extends</span> <span style="color: #228b22;">TaintTracking</span>::Configuration {
|
||||||
|
SqliFlowConfig() { <span style="color: #a020f0;">this</span> = <span style="color: #8b2252;">"SqliFlow"</span> }
|
||||||
|
|
||||||
|
override <span style="color: #228b22;">predicate</span> <span style="color: #0000ff;">isSource</span>(DataFlow::Node node) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
|
override <span style="color: #228b22;">predicate</span> <span style="color: #0000ff;">isSink</span>(DataFlow::Node node) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</div></li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The final query (without <code>isAdditionalTaintStep</code>) is
|
||||||
|
</p>
|
||||||
|
<div class="org-src-container">
|
||||||
|
<pre class="src src-java"><span style="color: #8b2252;">/**</span>
|
||||||
|
<span style="color: #8b2252;"> * </span><span style="color: #008b8b;">@name</span><span style="color: #8b2252;"> SQLI Vulnerability</span>
|
||||||
|
<span style="color: #8b2252;"> * </span><span style="color: #008b8b;">@description</span><span style="color: #8b2252;"> Using untrusted strings in a sql query allows sql injection attacks.</span>
|
||||||
|
<span style="color: #8b2252;"> * </span><span style="color: #008b8b;">@kind</span><span style="color: #8b2252;"> path-problem</span>
|
||||||
|
<span style="color: #8b2252;"> * </span><span style="color: #008b8b;">@id</span><span style="color: #8b2252;"> java/SQLIVulnerable</span>
|
||||||
|
<span style="color: #8b2252;"> * </span><span style="color: #008b8b;">@problem</span><span style="color: #8b2252;">.severity warning</span>
|
||||||
|
<span style="color: #8b2252;"> */</span>
|
||||||
|
|
||||||
|
<span style="color: #a020f0;">import</span> <span style="color: #228b22;">java</span>
|
||||||
|
<span style="color: #a020f0;">import</span> <span style="color: #008b8b;">semmle</span>.<span style="color: #008b8b;">code</span>.<span style="color: #008b8b;">java</span>.<span style="color: #008b8b;">dataflow</span>.<span style="color: #228b22;">TaintTracking</span>
|
||||||
|
<span style="color: #a020f0;">import</span> <span style="color: #228b22;">DataFlow</span>::PathGraph
|
||||||
|
|
||||||
|
<span style="color: #a020f0;">class</span> SqliFlowConfig <span style="color: #a020f0;">extends</span> <span style="color: #228b22;">TaintTracking</span>::Configuration {
|
||||||
|
SqliFlowConfig() { <span style="color: #a020f0;">this</span> = <span style="color: #8b2252;">"SqliFlow"</span> }
|
||||||
|
|
||||||
|
override <span style="color: #228b22;">predicate</span> <span style="color: #0000ff;">isSource</span>(DataFlow::Node source) {
|
||||||
|
<span style="color: #b22222;">// </span><span style="color: #b22222;">System.console().readLine();</span>
|
||||||
|
exists(<span style="color: #228b22;">Call</span> <span style="color: #0000ff;">read</span> |
|
||||||
|
read.getCallee().getName() = <span style="color: #8b2252;">"readLine"</span> and
|
||||||
|
read = source.asExpr()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override <span style="color: #228b22;">predicate</span> <span style="color: #0000ff;">isSink</span>(DataFlow::Node sink) {
|
||||||
|
<span style="color: #b22222;">// </span><span style="color: #b22222;">conn.createStatement().executeUpdate(query);</span>
|
||||||
|
exists(<span style="color: #228b22;">Call</span> <span style="color: #0000ff;">exec</span> |
|
||||||
|
exec.getCallee().getName() = <span style="color: #8b2252;">"executeUpdate"</span> and
|
||||||
|
exec.getArgument(0) = sink.asExpr()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from <span style="color: #228b22;">SqliFlowConfig</span> <span style="color: #a0522d;">conf</span>, <span style="color: #a0522d;">DataFlow</span>::PathNode source, <span style="color: #0000ff;">DataFlow</span>::PathNode sink
|
||||||
|
where conf.hasFlowPath(source, sink)
|
||||||
|
select sink, source, sink, <span style="color: #8b2252;">"Possible SQL injection"</span>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="outline-container-orga2253a0" class="outline-2">
|
||||||
|
<h2 id="orga2253a0"><span class="section-number-2">2.</span> Optional: sarif file review of the results</h2>
|
||||||
|
<div class="outline-text-2" id="text-2">
|
||||||
|
<p>
|
||||||
|
Query results are available in several output formats using the cli. The
|
||||||
|
following produces the sarif format, a json-based result description.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="org-src-container">
|
||||||
|
<pre class="src src-sh"><span style="color: #b22222;"># </span><span style="color: #b22222;">The setup information from before</span>
|
||||||
|
<span style="color: #483d8b;">export</span> <span style="color: #a0522d;">PATH</span>=$<span style="color: #a0522d;">HOME</span>/local/vmsync/codeql250:<span style="color: #8b2252;">"$PATH"</span>
|
||||||
|
<span style="color: #a0522d;">SRCDIR</span>=$<span style="color: #a0522d;">HOME</span>/local/codeql-training-material.java-sqli/java/codeql-dataflow-sql-injection
|
||||||
|
<span style="color: #a0522d;">DB</span>=$<span style="color: #a0522d;">SRCDIR</span>/java-sqli-$(<span style="color: #ff00ff;">cd $SRCDIR && git rev-parse --short HEAD</span>)
|
||||||
|
|
||||||
|
<span style="color: #b22222;"># </span><span style="color: #b22222;">Check paths</span>
|
||||||
|
<span style="color: #483d8b;">echo</span> $<span style="color: #a0522d;">DB</span>
|
||||||
|
<span style="color: #483d8b;">echo</span> $<span style="color: #a0522d;">SRCDIR</span>
|
||||||
|
|
||||||
|
<span style="color: #b22222;"># </span><span style="color: #b22222;">To see the help</span>
|
||||||
|
codeql database analyze -h
|
||||||
|
|
||||||
|
<span style="color: #b22222;"># </span><span style="color: #b22222;">Run a query</span>
|
||||||
|
codeql database analyze <span style="color: #8b2252;">\</span>
|
||||||
|
-v <span style="color: #8b2252;">\</span>
|
||||||
|
--ram=14000 <span style="color: #8b2252;">\</span>
|
||||||
|
-j12 <span style="color: #8b2252;">\</span>
|
||||||
|
--rerun <span style="color: #8b2252;">\</span>
|
||||||
|
--search-path ~/local/vmsync/ql <span style="color: #8b2252;">\</span>
|
||||||
|
--format=sarif-latest <span style="color: #8b2252;">\</span>
|
||||||
|
--output java-sqli.sarif <span style="color: #8b2252;">\</span>
|
||||||
|
-- <span style="color: #8b2252;">\</span>
|
||||||
|
$<span style="color: #a0522d;">DB</span> <span style="color: #8b2252;">\</span>
|
||||||
|
$<span style="color: #a0522d;">SRCDIR</span>/SqlInjection.ql
|
||||||
|
|
||||||
|
<span style="color: #b22222;"># </span><span style="color: #b22222;">Examine the file in an editor</span>
|
||||||
|
edit java-sqli.sarif
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
An example of using the sarif data is in the the jq script <a href="./sarif-summary.jq">./sarif-summary.jq</a>.
|
||||||
|
When run against the sarif input via
|
||||||
|
</p>
|
||||||
|
<div class="org-src-container">
|
||||||
|
<pre class="src src-sh">jq --raw-output --join-output -f sarif-summary.jq < java-sqli.sarif > java-sqli.txt
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
it produces output in a form close to that of compiler error messages:
|
||||||
|
</p>
|
||||||
|
<div class="org-src-container">
|
||||||
|
<pre class="src src-text">query-id: message line
|
||||||
|
Path
|
||||||
|
...
|
||||||
|
Path
|
||||||
|
...
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="postamble" class="status">
|
||||||
|
<p class="author">Author: Michael Hohn</p>
|
||||||
|
<p class="date">Created: 2023-08-16 Wed 10:26</p>
|
||||||
|
<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
119
solutions/README.org
Normal file
119
solutions/README.org
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
* Develop the query bottom-up
|
||||||
|
1. Identify the /source/ part of the
|
||||||
|
: System.console().readLine();
|
||||||
|
expression, the =buf= argument.
|
||||||
|
Start from a =from..where..select=, then convert to a predicate.
|
||||||
|
|
||||||
|
2. Identify the /sink/ part of the
|
||||||
|
: conn.createStatement().executeUpdate(query);
|
||||||
|
expression, the =query= argument. Again start from =from..where..select=,
|
||||||
|
then convert to a predicate.
|
||||||
|
|
||||||
|
3. Fill in the /taintflow configuration/ boilerplate
|
||||||
|
XX: update for new module approach;
|
||||||
|
See ~/local/codeql-workshop-dataflow-c/exercises/Exercise16.ql
|
||||||
|
[[file:~/local/codeql-workshop-dataflow-c/exercises/Exercise16.ql::module InputTypesToTypeValidation = DataFlow::Make<InputTypesToTypeValidationConfig>;]]
|
||||||
|
or
|
||||||
|
[[file:~/local/codeql-workshop-dataflow-c/solutions/Exercise16.ql::module InputTypesToTypeValidation = DataFlow::Make<InputTypesToTypeValidationConfig>;]]
|
||||||
|
|
||||||
|
#+BEGIN_SRC java
|
||||||
|
class SqliFlowConfig extends TaintTracking::Configuration {
|
||||||
|
SqliFlowConfig() { this = "SqliFlow" }
|
||||||
|
|
||||||
|
override predicate isSource(DataFlow::Node node) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isSink(DataFlow::Node node) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
The final query (without =isAdditionalTaintStep=) is
|
||||||
|
#+BEGIN_SRC java
|
||||||
|
/**
|
||||||
|
,* @name SQLI Vulnerability
|
||||||
|
,* @description Using untrusted strings in a sql query allows sql injection attacks.
|
||||||
|
,* @kind path-problem
|
||||||
|
,* @id java/SQLIVulnerable
|
||||||
|
,* @problem.severity warning
|
||||||
|
,*/
|
||||||
|
|
||||||
|
import java
|
||||||
|
import semmle.code.java.dataflow.TaintTracking
|
||||||
|
import DataFlow::PathGraph
|
||||||
|
|
||||||
|
class SqliFlowConfig extends TaintTracking::Configuration {
|
||||||
|
SqliFlowConfig() { this = "SqliFlow" }
|
||||||
|
|
||||||
|
override predicate isSource(DataFlow::Node source) {
|
||||||
|
// System.console().readLine();
|
||||||
|
exists(Call read |
|
||||||
|
read.getCallee().getName() = "readLine" and
|
||||||
|
read = source.asExpr()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isSink(DataFlow::Node sink) {
|
||||||
|
// conn.createStatement().executeUpdate(query);
|
||||||
|
exists(Call exec |
|
||||||
|
exec.getCallee().getName() = "executeUpdate" and
|
||||||
|
exec.getArgument(0) = sink.asExpr()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from SqliFlowConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||||
|
where conf.hasFlowPath(source, sink)
|
||||||
|
select sink, source, sink, "Possible SQL injection"
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Optional: sarif file review of the results
|
||||||
|
Query results are available in several output formats using the cli. The
|
||||||
|
following produces the sarif format, a json-based result description.
|
||||||
|
|
||||||
|
#+BEGIN_SRC sh
|
||||||
|
# The setup information from before
|
||||||
|
export PATH=$HOME/local/vmsync/codeql250:"$PATH"
|
||||||
|
SRCDIR=$HOME/local/codeql-training-material.java-sqli/java/codeql-dataflow-sql-injection
|
||||||
|
DB=$SRCDIR/java-sqli-$(cd $SRCDIR && git rev-parse --short HEAD)
|
||||||
|
|
||||||
|
# Check paths
|
||||||
|
echo $DB
|
||||||
|
echo $SRCDIR
|
||||||
|
|
||||||
|
# To see the help
|
||||||
|
codeql database analyze -h
|
||||||
|
|
||||||
|
# Run a query
|
||||||
|
codeql database analyze \
|
||||||
|
-v \
|
||||||
|
--ram=14000 \
|
||||||
|
-j12 \
|
||||||
|
--rerun \
|
||||||
|
--search-path ~/local/vmsync/ql \
|
||||||
|
--format=sarif-latest \
|
||||||
|
--output java-sqli.sarif \
|
||||||
|
-- \
|
||||||
|
$DB \
|
||||||
|
$SRCDIR/SqlInjection.ql
|
||||||
|
|
||||||
|
# Examine the file in an editor
|
||||||
|
edit java-sqli.sarif
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
An example of using the sarif data is in the the jq script [[./sarif-summary.jq]].
|
||||||
|
When run against the sarif input via
|
||||||
|
#+BEGIN_SRC sh
|
||||||
|
jq --raw-output --join-output -f sarif-summary.jq < java-sqli.sarif > java-sqli.txt
|
||||||
|
#+END_SRC
|
||||||
|
it produces output in a form close to that of compiler error messages:
|
||||||
|
#+BEGIN_SRC text
|
||||||
|
query-id: message line
|
||||||
|
Path
|
||||||
|
...
|
||||||
|
Path
|
||||||
|
...
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
6
solutions/qlpack.yml
Normal file
6
solutions/qlpack.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
library: false
|
||||||
|
name: codeql-workshop/java-sql-injection
|
||||||
|
version: 0.0.1
|
||||||
|
dependencies:
|
||||||
|
codeql/java-all: "*"
|
||||||
45
src/AddUser.java
Normal file
45
src/AddUser.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class AddUser {
|
||||||
|
public static Connection connect() {
|
||||||
|
Connection conn = null;
|
||||||
|
try {
|
||||||
|
String url = "jdbc:sqlite:users.sqlite";
|
||||||
|
conn = DriverManager.getConnection(url);
|
||||||
|
System.out.println("Connected...");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String get_user_info() {
|
||||||
|
System.out.println("Enter name:");
|
||||||
|
return System.console().readLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_info(int id, String info) {
|
||||||
|
try (Connection conn = connect()) {
|
||||||
|
String query = String.format("INSERT INTO users VALUES (%d, '%s')", id, info);
|
||||||
|
conn.createStatement().executeUpdate(query);
|
||||||
|
System.err.printf("Sent: %s", query);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_new_id() {
|
||||||
|
return (int)(Math.random()*100000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String info;
|
||||||
|
int id;
|
||||||
|
|
||||||
|
info = get_user_info();
|
||||||
|
id = get_new_id();
|
||||||
|
write_info(id, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/Makefile
Normal file
26
src/Makefile
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
add-user: add-user.c
|
||||||
|
clang -Wall add-user.c -lsqlite3 -o add-user
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f README.html add-user cpp-sqli.sarif cpp-sqli.txt users.log
|
||||||
|
rm -f users.sqlite *.bak *~ cpp-sqli-demo.zip
|
||||||
|
|
||||||
|
ZIPLIST := \
|
||||||
|
Makefile \
|
||||||
|
README.org \
|
||||||
|
SqlInjection.ql \
|
||||||
|
add-user.c \
|
||||||
|
add-user.sh \
|
||||||
|
admin \
|
||||||
|
build.sh \
|
||||||
|
codeql-dataflow-sql-injection.md \
|
||||||
|
codeql-overview-for-workshop.pdf \
|
||||||
|
cpp-sqli.code-workspace \
|
||||||
|
dataflow-cropped.pdf \
|
||||||
|
qlpack.yml \
|
||||||
|
sarif-summary.jq \
|
||||||
|
session.ql
|
||||||
|
|
||||||
|
demo-zip:
|
||||||
|
rm -f cpp-sqli-demo.zip
|
||||||
|
zip cpp-sqli-demo.zip $(ZIPLIST)
|
||||||
218
src/README.org
Normal file
218
src/README.org
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
* SQL injection example
|
||||||
|
** Setup and sample run
|
||||||
|
The jdbc connector at https://github.com/xerial/sqlite-jdbc, from [[https://github.com/xerial/sqlite-jdbc/releases/download/3.36.0.1/sqlite-jdbc-3.36.0.1.jar][here]] is
|
||||||
|
included in the git repository.
|
||||||
|
|
||||||
|
#+BEGIN_SRC sh
|
||||||
|
# Use a simple headline prompt
|
||||||
|
PS1='
|
||||||
|
\033[32m---- SQL injection demo ----\[\033[33m\033[0m\]
|
||||||
|
$?:$ '
|
||||||
|
|
||||||
|
|
||||||
|
# Build
|
||||||
|
./build.sh
|
||||||
|
|
||||||
|
# Prepare db
|
||||||
|
./admin -r
|
||||||
|
./admin -c
|
||||||
|
./admin -s
|
||||||
|
|
||||||
|
# Add regular user interactively
|
||||||
|
./add-user 2>> users.log
|
||||||
|
First User
|
||||||
|
|
||||||
|
# Check
|
||||||
|
./admin -s
|
||||||
|
|
||||||
|
# Add Johnny Droptable
|
||||||
|
./add-user 2>> users.log
|
||||||
|
Johnny'); DROP TABLE users; --
|
||||||
|
|
||||||
|
# And the problem:
|
||||||
|
./admin -s
|
||||||
|
|
||||||
|
# Check the log
|
||||||
|
tail users.log
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** Identify the problem
|
||||||
|
=./add-user= is reading from =STDIN=, and writing to a database; looking at the code in
|
||||||
|
[[./AddUser.java]] leads to
|
||||||
|
: System.console().readLine();
|
||||||
|
for the read and
|
||||||
|
: conn.createStatement().executeUpdate(query);
|
||||||
|
for the write.
|
||||||
|
|
||||||
|
This problem is thus a dataflow problem; in codeql terminology we have
|
||||||
|
- a /source/ at the =System.console().readLine();=
|
||||||
|
- a /sink/ at the =conn.createStatement().executeUpdate(query);=
|
||||||
|
|
||||||
|
We write codeql to identify these two, and then connect them via
|
||||||
|
- a /dataflow configuration/ -- for this problem, the more general /taintflow
|
||||||
|
configuration/.
|
||||||
|
|
||||||
|
** Build codeql database
|
||||||
|
To get started, build the codeql database (adjust paths to your setup):
|
||||||
|
#+BEGIN_SRC sh
|
||||||
|
# Build the db with source commit id.
|
||||||
|
export PATH=$HOME/local/vmsync/codeql250:"$PATH"
|
||||||
|
SRCDIR=$(pwd)
|
||||||
|
DB=$SRCDIR/java-sqli-$(cd $SRCDIR && git rev-parse --short HEAD)
|
||||||
|
|
||||||
|
echo $DB
|
||||||
|
test -d "$DB" && rm -fR "$DB"
|
||||||
|
mkdir -p "$DB"
|
||||||
|
|
||||||
|
cd $SRCDIR && codeql database create --language=java -s . -j 8 -v $DB --command='./build.sh'
|
||||||
|
|
||||||
|
# Check for AddUser in the db
|
||||||
|
unzip -v $DB/src.zip | grep AddUser
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Then add this database directory to your VS Code =DATABASES= tab.
|
||||||
|
|
||||||
|
|
||||||
|
** Build codeql database in steps
|
||||||
|
For larger projects, using a single command to build everything is costly when
|
||||||
|
any part of the build fails.
|
||||||
|
|
||||||
|
To build a database in steps, use the following sequence, adjusting paths to
|
||||||
|
your setup:
|
||||||
|
#+BEGIN_SRC sh
|
||||||
|
# Build the db with source commit id.
|
||||||
|
export PATH=$HOME/local/vmsync/codeql250:"$PATH"
|
||||||
|
SRCDIR=$HOME/local/codeql-training-material.java-sqli/java/codeql-dataflow-sql-injection
|
||||||
|
DB=$SRCDIR/java-sqli-$(cd $SRCDIR && git rev-parse --short HEAD)
|
||||||
|
|
||||||
|
# Check paths
|
||||||
|
echo $DB
|
||||||
|
echo $SRCDIR
|
||||||
|
|
||||||
|
# Prepare db directory
|
||||||
|
test -d "$DB" && rm -fR "$DB"
|
||||||
|
mkdir -p "$DB"
|
||||||
|
|
||||||
|
# Run the build
|
||||||
|
cd $SRCDIR
|
||||||
|
codeql database init --language=java -s . -v $DB
|
||||||
|
# Repeat trace-command as needed to cover all targets
|
||||||
|
codeql database trace-command -v $DB -- make
|
||||||
|
codeql database finalize -j4 $DB
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Then add this database directory to your VS Code =DATABASES= tab.
|
||||||
|
|
||||||
|
** Develop the query bottom-up
|
||||||
|
1. Identify the /source/ part of the
|
||||||
|
: System.console().readLine();
|
||||||
|
expression, the =buf= argument.
|
||||||
|
Start from a =from..where..select=, then convert to a predicate.
|
||||||
|
|
||||||
|
2. Identify the /sink/ part of the
|
||||||
|
: conn.createStatement().executeUpdate(query);
|
||||||
|
expression, the =query= argument. Again start from =from..where..select=,
|
||||||
|
then convert to a predicate.
|
||||||
|
|
||||||
|
3. Fill in the /taintflow configuration/ boilerplate
|
||||||
|
#+BEGIN_SRC java
|
||||||
|
class SqliFlowConfig extends TaintTracking::Configuration {
|
||||||
|
SqliFlowConfig() { this = "SqliFlow" }
|
||||||
|
|
||||||
|
override predicate isSource(DataFlow::Node node) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isSink(DataFlow::Node node) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
The final query (without =isAdditionalTaintStep=) is
|
||||||
|
#+BEGIN_SRC java
|
||||||
|
/**
|
||||||
|
,* @name SQLI Vulnerability
|
||||||
|
,* @description Using untrusted strings in a sql query allows sql injection attacks.
|
||||||
|
,* @kind path-problem
|
||||||
|
,* @id java/SQLIVulnerable
|
||||||
|
,* @problem.severity warning
|
||||||
|
,*/
|
||||||
|
|
||||||
|
import java
|
||||||
|
import semmle.code.java.dataflow.TaintTracking
|
||||||
|
import DataFlow::PathGraph
|
||||||
|
|
||||||
|
class SqliFlowConfig extends TaintTracking::Configuration {
|
||||||
|
SqliFlowConfig() { this = "SqliFlow" }
|
||||||
|
|
||||||
|
override predicate isSource(DataFlow::Node source) {
|
||||||
|
// System.console().readLine();
|
||||||
|
exists(Call read |
|
||||||
|
read.getCallee().getName() = "readLine" and
|
||||||
|
read = source.asExpr()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isSink(DataFlow::Node sink) {
|
||||||
|
// conn.createStatement().executeUpdate(query);
|
||||||
|
exists(Call exec |
|
||||||
|
exec.getCallee().getName() = "executeUpdate" and
|
||||||
|
exec.getArgument(0) = sink.asExpr()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from SqliFlowConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||||
|
where conf.hasFlowPath(source, sink)
|
||||||
|
select sink, source, sink, "Possible SQL injection"
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** Optional: sarif file review of the results
|
||||||
|
Query results are available in several output formats using the cli. The
|
||||||
|
following produces the sarif format, a json-based result description.
|
||||||
|
|
||||||
|
#+BEGIN_SRC sh
|
||||||
|
# The setup information from before
|
||||||
|
export PATH=$HOME/local/vmsync/codeql250:"$PATH"
|
||||||
|
SRCDIR=$HOME/local/codeql-training-material.java-sqli/java/codeql-dataflow-sql-injection
|
||||||
|
DB=$SRCDIR/java-sqli-$(cd $SRCDIR && git rev-parse --short HEAD)
|
||||||
|
|
||||||
|
# Check paths
|
||||||
|
echo $DB
|
||||||
|
echo $SRCDIR
|
||||||
|
|
||||||
|
# To see the help
|
||||||
|
codeql database analyze -h
|
||||||
|
|
||||||
|
# Run a query
|
||||||
|
codeql database analyze \
|
||||||
|
-v \
|
||||||
|
--ram=14000 \
|
||||||
|
-j12 \
|
||||||
|
--rerun \
|
||||||
|
--search-path ~/local/vmsync/ql \
|
||||||
|
--format=sarif-latest \
|
||||||
|
--output java-sqli.sarif \
|
||||||
|
-- \
|
||||||
|
$DB \
|
||||||
|
$SRCDIR/SqlInjection.ql
|
||||||
|
|
||||||
|
# Examine the file in an editor
|
||||||
|
edit java-sqli.sarif
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
An example of using the sarif data is in the the jq script [[./sarif-summary.jq]].
|
||||||
|
When run against the sarif input via
|
||||||
|
#+BEGIN_SRC sh
|
||||||
|
jq --raw-output --join-output -f sarif-summary.jq < java-sqli.sarif > java-sqli.txt
|
||||||
|
#+END_SRC
|
||||||
|
it produces output in a form close to that of compiler error messages:
|
||||||
|
#+BEGIN_SRC text
|
||||||
|
query-id: message line
|
||||||
|
Path
|
||||||
|
...
|
||||||
|
Path
|
||||||
|
...
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
44
src/SqlInjection.ql
Normal file
44
src/SqlInjection.ql
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* @name SQLI Vulnerability
|
||||||
|
* @description Using untrusted strings in a sql query allows sql injection attacks.
|
||||||
|
* @kind path-problem
|
||||||
|
* @id cpp/SQLIVulnerable
|
||||||
|
* @problem.severity warning
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java
|
||||||
|
import semmle.code.java.dataflow.TaintTracking
|
||||||
|
import DataFlow::PathGraph
|
||||||
|
|
||||||
|
class SqliFlowConfig extends TaintTracking::Configuration {
|
||||||
|
SqliFlowConfig() { this = "SqliFlow" }
|
||||||
|
|
||||||
|
override predicate isSource(DataFlow::Node source) {
|
||||||
|
// System.console().readLine();
|
||||||
|
exists(Call read |
|
||||||
|
read.getCallee().getName() = "readLine" and
|
||||||
|
read = source.asExpr()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isSanitizer(DataFlow::Node sanitizer) { none() }
|
||||||
|
|
||||||
|
override predicate isAdditionalTaintStep(DataFlow::Node into, DataFlow::Node out) {
|
||||||
|
// Extra taint step
|
||||||
|
// String.format("INSERT INTO users VALUES (%d, '%s')", id, info);
|
||||||
|
// Not needed here, but may be needed for larger libraries.
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isSink(DataFlow::Node sink) {
|
||||||
|
// conn.createStatement().executeUpdate(query);
|
||||||
|
exists(Call exec |
|
||||||
|
exec.getCallee().getName() = "executeUpdate" and
|
||||||
|
exec.getArgument(0) = sink.asExpr()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from SqliFlowConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||||
|
where conf.hasFlowPath(source, sink)
|
||||||
|
select sink, source, sink, "Possible SQL injection"
|
||||||
3
src/add-user
Executable file
3
src/add-user
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
java -cp ".:sqlite-jdbc-3.36.0.1.jar" AddUser $@
|
||||||
|
|
||||||
60
src/admin
Executable file
60
src/admin
Executable file
@@ -0,0 +1,60 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
script=$(basename "$0")
|
||||||
|
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
MAGENTA='\033[0;95m'
|
||||||
|
NC='\033[0m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
YELLOW='\033[0;33m'
|
||||||
|
|
||||||
|
help() {
|
||||||
|
echo -e "Usage: ./${script} [options]" \
|
||||||
|
"\n${YELLOW}Options: ${NC}" \
|
||||||
|
"\n\t -h ${GREEN}Show Help ${NC}" \
|
||||||
|
"\n\t -c ${MAGENTA}Creates a users table ${NC}" \
|
||||||
|
"\n\t -s ${MAGENTA}Shows all records in the users table ${NC}" \
|
||||||
|
"\n\t -r ${RED}Removes users table ${NC}"
|
||||||
|
}
|
||||||
|
remove-db () {
|
||||||
|
rm users.sqlite
|
||||||
|
}
|
||||||
|
|
||||||
|
create-db () {
|
||||||
|
echo '
|
||||||
|
CREATE TABLE users (
|
||||||
|
user_id INTEGER not null,
|
||||||
|
name TEXT NOT NULL
|
||||||
|
);
|
||||||
|
' | sqlite3 users.sqlite
|
||||||
|
}
|
||||||
|
|
||||||
|
show-db () {
|
||||||
|
echo '
|
||||||
|
SELECT * FROM users;
|
||||||
|
' | sqlite3 users.sqlite
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# == 0 ]; then
|
||||||
|
help
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
while getopts "h?csr" option
|
||||||
|
do
|
||||||
|
case "${option}"
|
||||||
|
in
|
||||||
|
h|\?)
|
||||||
|
help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
c) create-db
|
||||||
|
;;
|
||||||
|
s) show-db
|
||||||
|
;;
|
||||||
|
r) remove-db
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
3
src/build.sh
Executable file
3
src/build.sh
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
javac AddUser.java
|
||||||
|
|
||||||
60
src/sarif-summary.jq
Normal file
60
src/sarif-summary.jq
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# -*- sh -*-
|
||||||
|
.runs | .[] | .results | .[] |
|
||||||
|
( (.ruleId, ": ",
|
||||||
|
(.message.text | split("\n") | ( .[0], " [", length-1 , " more]")),
|
||||||
|
"\n")
|
||||||
|
,
|
||||||
|
(if (.codeFlows != null) then
|
||||||
|
(.codeFlows | .[] |
|
||||||
|
(" Path\n"
|
||||||
|
,
|
||||||
|
( .threadFlows | .[] | .locations | .[] | .location | " "
|
||||||
|
,
|
||||||
|
( .physicalLocation | ( .artifactLocation.uri, ":", .region.startLine, ":"))
|
||||||
|
,
|
||||||
|
(.message.text, " ")
|
||||||
|
,
|
||||||
|
"\n"
|
||||||
|
)))
|
||||||
|
else
|
||||||
|
(.locations | .[] |
|
||||||
|
( " "
|
||||||
|
,
|
||||||
|
(.physicalLocation | ( .artifactLocation.uri, ":", .region.startLine, ":"))
|
||||||
|
))
|
||||||
|
,
|
||||||
|
# .message.text,
|
||||||
|
"\n"
|
||||||
|
end)
|
||||||
|
) | tostring
|
||||||
|
|
||||||
|
# This script extracts the following parts of the sarif output:
|
||||||
|
#
|
||||||
|
# # problem
|
||||||
|
# "runs" : [ {
|
||||||
|
# "results" : [ {
|
||||||
|
# "ruleId" : "cpp/UncheckedErrorCode",
|
||||||
|
|
||||||
|
# # path problem
|
||||||
|
# "runs" : [ {
|
||||||
|
# "tool" : {
|
||||||
|
# "driver" : {
|
||||||
|
# "rules" : [ {
|
||||||
|
# "properties" : {
|
||||||
|
# "kind" : "path-problem",
|
||||||
|
|
||||||
|
# "runs" : [ {
|
||||||
|
# "results" : [ {
|
||||||
|
# "ruleId" : "cpp/DangerousArithmetic",
|
||||||
|
# "ruleIndex" : 6,
|
||||||
|
# "message" : {
|
||||||
|
# "text" : "Potential overflow (conversion: int -> unsigned int)\nPotential overflow (con
|
||||||
|
|
||||||
|
# "runs" : [ {
|
||||||
|
# "results" : [ {
|
||||||
|
# "codeFlows" : [ {
|
||||||
|
# "threadFlows" : [ {
|
||||||
|
# "locations" : [ {
|
||||||
|
# "location" : {
|
||||||
|
# "message" : {
|
||||||
|
# "text" : "buff"
|
||||||
BIN
src/sqlite-jdbc-3.36.0.1.jar
Normal file
BIN
src/sqlite-jdbc-3.36.0.1.jar
Normal file
Binary file not shown.
Reference in New Issue
Block a user