-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Add a new CodelQL query for detecting the use of non-HTTPs URLs in Rust code. That is, a query that detects when Rust code may be accessing an http
(rather than https
) URL, which is likely to be a security issue.
This will work similarly to existing non-HTTPs URL queries we have for other target languages, for example:
java/non-https-url
(java/ql/src/Security/CWE/CWE-319/HttpsUrls.ql
) for non-HTTPs URLs accessed in Java code.cpp/non-https-url
(cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql
) for non-HTTPs URLs accessed in C/C++ code.
However the target language for this query will be Rust, the QL should be written to analyse Rust code and in a style consistent with our existing Rust queries - as a preference to the style of the Java and CPP queries above. For a style example see this existing SQL injection query for Rust:
rust/sql-injection
(rust/ql/src/queries/security/CWE-089/SqlInjection.ql
)
You will need to create the following files:
rust/ql/src/queries/security/CWE-319/UseOfHttpBad.rs
- a simple example demonstrating the vulnerability, written in Rust code. This could be ported from the Java or CPP example in the equivalent location, or written from scratch, but either way it should be in concise, clear, idiomatic Rust. For readability we usually just want to show one case in the example, and save any interesting variations for the tests.rust/ql/src/queries/security/CWE-319/UseOfHttpGood.rs
- a fixed version of the Bad example that no longer exhibits the vulnerability.rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp
- a.qhelp
file describing the query / vulnerability. Use a corresponding.qhelp
from one of the other languages as a starting point, but translate any language specific parts to refer to Rust and update any language specific links you find (or remove them if you can't find an equivalent reference).- note that you do not need to include a link to the CWE definition at cwe.mitre.org, since the qhelp processor adds these automatically.
rust/ql/src/queries/security/CWE-319/UseOfHttp.ql
- the query itself, including any required dataflow configuration (module ... implements DataFlow::ConfigSig
) for tracking HTTP URLs from their definition to where they are used. Again, look to the three examples I have provided above to produce a quality Rust query for non-HTTPs URLs.rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll
- defining sources, sinks and potentially barriers needed by the query. Once again, look to the three examples as a guide, and the Rust query in particular for how best to lay out the code.- we will need to define the sources in CodeQL, similarly to Java and CPP
HttpStringLiteral
classes. Note thatStringLiteral
is calledStringLiteralExpr
in CodeQL for Rust, and it has a method.getTextValue()
. - for sinks, I believe the existing models-as-data
request-url
sinks will be sufficient for now - usesinkNode(this, "request-url")
.
- we will need to define the sources in CodeQL, similarly to Java and CPP
rust/ql/test/query-tests/security/CWE-319/main.rs
- a Rust source file containing multiple examples of code containing non-HTTPs URL vulnerabilities (i.e. that the query should find), and multiple examples of code that is fixed or not vulnerable. Your Bad and Good examples should be included as part of this test, and you should use "inline expectations" comments to mark lines where you expect query results:// $ Alert[rust/non-https-url]
.rust/ql/test/query-tests/security/CWE-319/options.yml
- defines any dependencies required by the test.rust/ql/test/query-tests/security/CWE-319/UseOfHttp.qlref
- links to theUseOfHttp.ql
file, so that the test runner can find the query. Also defines the test post-processing steps that should be performed.rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected
- this file contains the results from the test runner. Do not attempt to fill this in yourself - have the test runner generate it:- download and extract CodeQL CLI:
cd /tmp && curl -L -o codeql-linux64.zip https://github.com/github/codeql-cli-binaries/releases/latest/download/codeql-linux64.zip && unzip -q codeql-linux64.zip
- add to PATH:
export PATH="/tmp/codeql:$PATH"
- from the test directory,
codeql test run . --learn
.
- the most important section of the
.expected
file is the#select
section containing the results of the query. - it's OK if the query doesn't find every result we wanted. If it finds nothing, we can work to debug it together.
- download and extract CodeQL CLI:
rust/ql/test/query-tests/security/CWE-319/Cargo.lock
- this file is also generated by the test runner, and should be committed.
In most cases equivalent files to the ones you need to create will exist for all three existing queries I have cited - though exact file names may differ a little. I strongly recommend you look at each of these, as it's likely they contain everything you need to succeed at this task. Note that the CodeQL libraries are slightly different depending on the target language, so when in doubt, lean towards how things are done in the Rust query.
If you run into any problems and get stuck, feel free to stop and ask for help!
When the work is done, I request that you complete a few final cleanup / admin tasks:
- run the CodeQL CLI autoformatter on all
.ql
and.qll
files you have written. With the CodeQL CLI installed:codeql query format [file] --in-place
. - add any new query
.ql
file to the suite lists inrust/ql/integration-tests/query-suite
. Typically new security queries should be in therust-security-and-quality.qls.expected
andrust-security-extended.qls.expected
lists, and if they have the@precision high
tag alsorust-code-scanning.qls.expected
. - add a brief change note file in
rust/ql/src/change-notes
. See https://github.com/github/codeql/blob/main/docs/change-notes.md for more information about change notes. - add any
*Extensions.qll
file containing classes that extendQuerySink::Range
as an import inrust/ql/src/queries/summary/Stats.qll
. This is to ensure that the new query sinks are visible to our statistics module.