Skip to content

Commit 9f4c958

Browse files
Merge pull request #12 from GitHubSecurityLab/part-4
Part 4
2 parents 95946e5 + d18bace commit 9f4c958

File tree

16 files changed

+271
-32
lines changed

16 files changed

+271
-32
lines changed

4/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
To run the queries in this folder, follow the set up instructions for [VS Code CodeQL starter workspace](https://github.com/github/vscode-codeql-starter) and install VS Code CodeQL extension. Then, in the CodeQL extension select the `vulnerable-code-snippets-db` database.
2+
3+
For more information around CodeQL, set up and running queries, see [CodeQL zero to hero part 2](https://github.blog/developer-skills/github/codeql-zero-to-hero-part-2-getting-started-with-codeql/) and the other blog posts in the series.

4/queries/1.ql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* @id codeql-zero-to-hero/4-1
3+
* @severity error
4+
* @kind problem
5+
*/
6+
7+
import python
8+
import semmle.python.ApiGraphs
9+
10+
from API::CallNode node
11+
where node =
12+
API::moduleImport("gradio").getMember("Interface").getACall()
13+
14+
select node, "Call to gr.Interface"

4/queries/2.ql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* @id codeql-zero-to-hero/4-2
3+
* @severity error
4+
* @kind problem
5+
*/
6+
7+
import python
8+
import semmle.python.ApiGraphs
9+
10+
from API::CallNode node
11+
where node =
12+
API::moduleImport("gradio").getMember("Interface").getACall()
13+
14+
select node.getParameter(0, "fn").getParameter(_).asSource(), "Gradio sources"

4/queries/3.ql

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @id codeql-zero-to-hero/4-3
3+
* @severity error
4+
* @kind problem
5+
*/
6+
7+
import python
8+
import semmle.python.ApiGraphs
9+
import semmle.python.dataflow.new.RemoteFlowSources
10+
11+
class GradioInterface extends RemoteFlowSource::Range {
12+
GradioInterface() {
13+
exists(API::CallNode n |
14+
n = API::moduleImport("gradio").getMember("Interface").getACall() |
15+
this = n.getParameter(0, "fn").getParameter(_).asSource())
16+
}
17+
override string getSourceType() { result = "Gradio untrusted input" }
18+
19+
}
20+
21+
from GradioInterface inp
22+
select inp, "Gradio sources"

4/queries/4.ql

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @id codeql-zero-to-hero/4-4
3+
* @severity error
4+
* @kind problem
5+
*/
6+
7+
import python
8+
import semmle.python.ApiGraphs
9+
import semmle.python.dataflow.new.RemoteFlowSources
10+
11+
class GradioInterface extends RemoteFlowSource::Range {
12+
GradioInterface() {
13+
exists(API::CallNode n |
14+
n = API::moduleImport("gradio").getMember("Interface").getACall() |
15+
this = n.getParameter(0, "fn").getParameter(_).asSource())
16+
}
17+
override string getSourceType() { result = "Gradio untrusted input" }
18+
19+
}
20+
21+
22+
from RemoteFlowSource rfs
23+
select rfs, "All python sources"

4/queries/5.ql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* @id codeql-zero-to-hero/4-5
3+
* @severity error
4+
* @kind problem
5+
*/
6+
7+
import python
8+
import semmle.python.ApiGraphs
9+
10+
from API::CallNode node
11+
where node =
12+
API::moduleImport("gradio").getMember("Button").getReturn()
13+
.getMember("click").getACall()
14+
15+
select node.getParameter(0, "fn").getParameter(_), "Gradio sources"

4/queries/6.ql

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
/**
3+
* @id codeql-zero-to-hero/4-6
4+
* @severity error
5+
* @kind problem
6+
*/
7+
8+
9+
import python
10+
import semmle.python.ApiGraphs
11+
import semmle.python.dataflow.new.RemoteFlowSources
12+
13+
class GradioButton extends RemoteFlowSource::Range {
14+
GradioButton() {
15+
exists(API::CallNode n |
16+
n = API::moduleImport("gradio").getMember("Button").getReturn()
17+
.getMember("click").getACall() |
18+
this = n.getParameter(0, "fn").getParameter(_).asSource())
19+
}
20+
21+
override string getSourceType() { result = "Gradio untrusted input" }
22+
23+
}
24+
25+
from GradioButton inp
26+
select inp, "Gradio sources"

4/queries/7.ql

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
2+
/**
3+
* @id codeql-zero-to-hero/4-7
4+
* @severity error
5+
* @kind path-problem
6+
*/
7+
8+
9+
import python
10+
import semmle.python.dataflow.new.DataFlow
11+
import semmle.python.dataflow.new.TaintTracking
12+
import semmle.python.ApiGraphs
13+
import semmle.python.dataflow.new.RemoteFlowSources
14+
import MyFlow::PathGraph
15+
16+
class GradioButton extends RemoteFlowSource::Range {
17+
GradioButton() {
18+
exists(API::CallNode n |
19+
n = API::moduleImport("gradio").getMember("Button").getReturn()
20+
.getMember("click").getACall() |
21+
this = n.getParameter(0, "fn").getParameter(_).asSource())
22+
}
23+
24+
override string getSourceType() { result = "Gradio untrusted input" }
25+
26+
}
27+
28+
class GradioInterface extends RemoteFlowSource::Range {
29+
GradioInterface() {
30+
exists(API::CallNode n |
31+
n = API::moduleImport("gradio").getMember("Interface").getACall() |
32+
this = n.getParameter(0, "fn").getParameter(_).asSource())
33+
}
34+
override string getSourceType() { result = "Gradio untrusted input" }
35+
36+
}
37+
38+
39+
40+
class OsSystemSink extends API::CallNode {
41+
OsSystemSink() {
42+
this = API::moduleImport("os").getMember("system").getACall()
43+
}
44+
}
45+
46+
private module MyConfig implements DataFlow::ConfigSig {
47+
predicate isSource(DataFlow::Node source) {
48+
source instanceof RemoteFlowSource
49+
}
50+
51+
predicate isSink(DataFlow::Node sink) {
52+
exists(OsSystemSink call |
53+
sink = call.getArg(0)
54+
)
55+
}
56+
}
57+
58+
module MyFlow = TaintTracking::Global<MyConfig>;
59+
60+
from MyFlow::PathNode source, MyFlow::PathNode sink
61+
where MyFlow::flowPath(source, sink)
62+
select sink.getNode(), source, sink, "Data Flow from a Gradio source to `os.system`"

4/vulnerable-code-snippets-db.zip

71.8 MB
Binary file not shown.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import gradio as gr
2+
import os
3+
4+
def execute_cmd(folder, logs):
5+
cmd = f"python caption.py --dir={folder} --logs={logs}"
6+
os.system(cmd)
7+
return f"Command: {cmd}"
8+
9+
10+
folder = gr.Textbox(placeholder="Directory to caption")
11+
logs = gr.Checkbox(label="Save verbose logs")
12+
output = gr.Textbox()
13+
14+
demo = gr.Interface(
15+
fn=execute_cmd,
16+
inputs=[folder, logs],
17+
outputs=output)
18+
19+
if __name__ == "__main__":
20+
demo.launch(debug=True)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import gradio as gr
2+
import os
3+
4+
def execute_cmd(folder):
5+
cmd = f"python caption.py --dir={folder}"
6+
os.system(cmd)
7+
return f"Command: {cmd}"
8+
9+
10+
folder = gr.Textbox(placeholder="Directory to caption")
11+
output = gr.Textbox()
12+
13+
demo = gr.Interface(
14+
execute_cmd,
15+
folder,
16+
output)
17+
18+
if __name__ == "__main__":
19+
demo.launch(debug=True)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import gradio as gr
2+
import os
3+
4+
def execute_cmd(folder, logs):
5+
cmd = f"python caption.py --dir={folder} --logs={logs}"
6+
os.system(cmd)
7+
return f"Command: {cmd}"
8+
9+
10+
with gr.Blocks() as demo:
11+
gr.Markdown("Create caption files for images in a directory")
12+
with gr.Row():
13+
folder = gr.Textbox(placeholder="Directory to caption")
14+
logs = gr.Checkbox(label="Save verbose logs")
15+
output = gr.Textbox()
16+
17+
btn = gr.Button("Run")
18+
btn.click(
19+
fn=execute_cmd,
20+
inputs=[folder, logs],
21+
outputs=output)
22+
23+
24+
if __name__ == "__main__":
25+
demo.launch(debug=True)

4/vulnerable-code-snippets/cmdi.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import gradio as gr
2+
import os
3+
4+
def execute_cmd(folder):
5+
cmd = f"python caption.py --dir={folder}"
6+
os.system(cmd)
7+
return f"Command: {cmd}"
8+
9+
10+
with gr.Blocks() as demo:
11+
gr.Markdown("Create caption files for images in a directory")
12+
with gr.Row():
13+
folder = gr.Textbox(placeholder="Directory to caption")
14+
output = gr.Textbox()
15+
16+
btn = gr.Button("Run")
17+
btn.click(
18+
execute_cmd,
19+
folder,
20+
output)
21+
22+
23+
if __name__ == "__main__":
24+
demo.launch(debug=True)

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
This repository contains challenges for the CodeQL Zero to Hero blog post series.
44

5-
- Link to the first blog post—[CodeQL zero to hero part 1: the fundamentals of static analysis for vulnerability research](https://github.blog/2023-03-31-codeql-zero-to-hero-part-1-the-fundamentals-of-static-analysis-for-vulnerability-research/). The challenges accompanying the blog post are in [folder 1.](https://github.com/GitHubSecurityLab/codeql-zero-to-hero/tree/main/1)
6-
- Link to the second blog post—[CodeQL zero to hero part 2: getting started with CodeQL](https://github.blog/2023-06-15-codeql-zero-to-hero-part-2-getting-started-with-codeql/). The challenges accompanying the blog post are in [folder 2.](https://github.com/GitHubSecurityLab/codeql-zero-to-hero/tree/main/2)
7-
- Link to the third blog post—[CodeQL zero to hero part 3: security research](https://github.blog/2024-04-29-codeql-zero-to-hero-part-3-security-research-with-codeql/). The challenges accompanying the blog post are in [folder 3](https://github.com/GitHubSecurityLab/codeql-zero-to-hero/tree/main/3).
5+
- [CodeQL zero to hero part 1: the fundamentals of static analysis for vulnerability research](https://github.blog/2023-03-31-codeql-zero-to-hero-part-1-the-fundamentals-of-static-analysis-for-vulnerability-research/). The challenges accompanying the blog post are in [folder 1.](https://github.com/GitHubSecurityLab/codeql-zero-to-hero/tree/main/1)
6+
- [CodeQL zero to hero part 2: getting started with CodeQL](https://github.blog/2023-06-15-codeql-zero-to-hero-part-2-getting-started-with-codeql/). The challenges accompanying the blog post are in [folder 2.](https://github.com/GitHubSecurityLab/codeql-zero-to-hero/tree/main/2)
7+
- [CodeQL zero to hero part 3: security research](https://github.blog/2024-04-29-codeql-zero-to-hero-part-3-security-research-with-codeql/). The challenges accompanying the blog post are in [folder 3](https://github.com/GitHubSecurityLab/codeql-zero-to-hero/tree/main/3).
8+
- [CodeQL zero to hero part 4: Gradio case study](). The challenges accompanying the blog post are in [folder 3](https://github.com/GitHubSecurityLab/codeql-zero-to-hero/tree/main/3).

codeql-pack.lock.yml

Lines changed: 0 additions & 22 deletions
This file was deleted.

codeql-pack.yml

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)