Skip to content

Commit d773890

Browse files
authored
Merge pull request #2 from advanced-security-demo/codeql-bundle-demo
Codeql bundle demo
2 parents 562fb34 + 9c39e77 commit d773890

File tree

7 files changed

+142
-0
lines changed

7 files changed

+142
-0
lines changed

.github/workflows/bundle.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Create Bundle
2+
on:
3+
workflow_dispatch:
4+
5+
jobs:
6+
build-and-release:
7+
runs-on: ubuntu-latest
8+
name: Build and release bundle
9+
steps:
10+
- name: Checkout
11+
uses: actions/checkout@v2
12+
- name: CodeQL bundle
13+
id: codeql-bundle
14+
uses: advanced-security/codeql-bundle-action@add-support-for-qlx-compiled-queries
15+
with:
16+
packs: "advanced-security-demo/vapi-customizations"
17+
- name: Bundle release
18+
env:
19+
BUNDLE_PATH: ${{ steps.codeql-bundle.outputs.bundle-path }}
20+
BUNDLE_TAG: ${{ steps.codeql-bundle.outputs.bundle-tag }}
21+
GITHUB_TOKEN: ${{ github.token }}
22+
run: |
23+
if gh release view $BUNDLE_TAG; then
24+
gh release upload --clobber $BUNDLE_TAG $BUNDLE_PATH
25+
else
26+
gh release create $BUNDLE_TAG $BUNDLE_PATH --generate-notes
27+
fi

.github/workflows/codeql.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: "CodeQL"
2+
on:
3+
workflow_dispatch:
4+
5+
permissions:
6+
actions: read
7+
contents: read
8+
security-events: write
9+
10+
jobs:
11+
analyze:
12+
name: "Analyze"
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v2
18+
19+
- name: Download custom bundle
20+
env:
21+
GH_TOKEN: ${{ github.token }}
22+
run: |
23+
gh release download --pattern 'codeql-bundle.tar.gz'
24+
25+
- name: CodeQL Initialize
26+
uses: github/codeql-action/init@v2
27+
with:
28+
tools: codeql-bundle.tar.gz
29+
queries: security-extended
30+
31+
- name: CodeQL Analyze
32+
uses: github/codeql-action/analyze@v2

codeql-workspace.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
provide:
2+
- "vapi-customizations/qlpack.yml"
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import python
2+
private import semmle.python.ApiGraphs
3+
private import semmle.python.dataflow.new.RemoteFlowSources
4+
private import semmle.python.frameworks.internal.InstanceTaintStepsHelper
5+
6+
module Connexion {
7+
API::Node request() { result = API::moduleImport("connexion").getMember("request") }
8+
9+
private class ConnexionRequestSource extends RemoteFlowSource::Range {
10+
ConnexionRequestSource() {
11+
this = request().getAUse() and
12+
not any(Import imp).contains(this.asExpr()) and
13+
not exists(ControlFlowNode def | this.asVar().getSourceVariable().hasDefiningNode(def) |
14+
any(Import imp).contains(def.getNode())
15+
)
16+
}
17+
18+
override string getSourceType() { result = "connexion.request" }
19+
}
20+
21+
private class InstanceTaintSteps extends InstanceTaintStepsHelper {
22+
InstanceTaintSteps() { this = "connexion.Request" }
23+
24+
override DataFlow::Node getInstance() { result = request().getAUse() }
25+
26+
override string getAttributeName() {
27+
result in [
28+
// str
29+
"path", "full_path", "base_url", "url", "access_control_request_method",
30+
"content_encoding", "content_md5", "content_type", "data", "method", "mimetype", "origin",
31+
"query_string", "referrer", "remote_addr", "remote_user", "user_agent",
32+
// dict
33+
"environ", "cookies", "mimetype_params", "view_args",
34+
// json
35+
"json",
36+
// List[str]
37+
"access_route",
38+
// file-like
39+
"stream", "input_stream",
40+
// MultiDict[str, str]
41+
// https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.MultiDict
42+
"args", "values", "form",
43+
// MultiDict[str, FileStorage]
44+
// https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.FileStorage
45+
// TODO: FileStorage needs extra taint steps
46+
"files",
47+
// https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.HeaderSet
48+
"access_control_request_headers", "pragma",
49+
// https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.Accept
50+
// TODO: Kinda badly modeled for now -- has type List[Tuple[value, quality]], and some extra methods
51+
"accept_charsets", "accept_encodings", "accept_languages", "accept_mimetypes",
52+
// https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.Authorization
53+
// TODO: dict subclass with extra attributes like `username` and `password`
54+
"authorization",
55+
// https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.RequestCacheControl
56+
// TODO: has attributes like `no_cache`, and `to_header` method (actually, many of these models do)
57+
"cache_control",
58+
// https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.Headers
59+
// TODO: dict-like with wsgiref.headers.Header compatibility methods
60+
"headers"
61+
]
62+
}
63+
64+
override string getMethodName() { result in ["get_data", "get_json"] }
65+
66+
override string getAsyncMethodName() { none() }
67+
}
68+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
dependencies:
3+
codeql/python-all:
4+
version: 0.4.1
5+
compiled: false
6+
lockVersion: 1.0.0

vapi-customizations/qlpack.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
library: true
3+
name: advanced-security-demo/vapi-customizations
4+
version: 0.0.1
5+
dependencies:
6+
codeql/python-all: 0.4.1
7+
extractor: python

0 commit comments

Comments
 (0)