Skip to content

Commit dd82937

Browse files
committed
initial commit
1 parent a03a5db commit dd82937

7 files changed

Lines changed: 40 additions & 31 deletions

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ By the end of the mandatory track you will have: detected hardcoded secrets with
7373

7474
| Feature | Description |
7575
|---------|-------------|
76-
| **Secret Scanning (`#secret-scanning`)** | Scans code for exposed credentials using GitHub's detection patterns |
76+
| **Secret Scanning (`plugins`)** | Scans code for exposed credentials using GitHub's detection patterns |
7777
| **VS Code Code Review** | Reviews a selection or uncommitted changes with inline suggestions and one-click fixes |
7878
| **Copilot Agent (Inline `Ctrl+I`)** | Applies fix patterns across entire files in one agentic step |
7979
| **Copilot CLI `/review`** | Agentic CLI code review of git changes — no browser required |
@@ -85,12 +85,12 @@ By the end of the mandatory track you will have: detected hardcoded secrets with
8585

8686
## Getting Started
8787

88-
1. Select use this template to create a new repository
89-
1. clone and open it in VS Code
88+
1. Select **use this template** to create a new repository
89+
1. Clone the repository and open it in VS Code
9090
1. Ensure **GitHub Copilot** and **GitHub Copilot Chat** extensions are installed and signed in
9191
1. Open the Copilot Chat panel (`Ctrl+Alt+I`)
9292
1. Start with [Exercise 01](workshop/exercise-01-setup.md)
9393

9494
---
9595

96-
> **Instructor Note**: Each exercise has `<!-- Instructor Guide -->` comments visible only in markdown source. Exercises are designed so attendees never need to copy code — they copy **prompts** and let Copilot generate the output. The [`securetrails-vulnerable/VULNERABILITIES.md`](securetrails-vulnerable/VULNERABILITIES.md) file contains exact file paths and line numbers — do not share with attendees before they attempt the exercises.
96+
> **Instructor Note**: Each exercise has `<!-- Instructor Guide -->` comments visible only in markdown source. Exercises are designed so attendees never need to copy code — they copy **prompts** and let Copilot generate the output.

workshop/exercise-01-setup.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ This workshop secures **SecureTrails**, a deliberately vulnerable Flask trail-bo
1414

1515
## Step 1 — Verify Tools
1616

17+
Open a terminal and run:
18+
1719
```bash
18-
code --version
20+
1921
python --version
2022
git --version
2123
gh --version
@@ -56,8 +58,9 @@ gh auth status # expected: Logged in to github.com as <your-username>
5658

5759
```bash
5860
cd securetrails-vulnerable
59-
python database.py # initialises database.db
6061
code .
62+
python database.py # initialises database.db
63+
6164
```
6265

6366
In VS Code press `Ctrl+Alt+I` to open Copilot Chat. Confirm it is signed in.

workshop/exercise-02-discover-review.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@ These are different from Copilot Chat: they use specialised models focused on su
1717
---
1818

1919
## Step 1 — Scan for Hardcoded Secrets
20+
Open copilot chat (`Ctrl+Alt+I`) and use the `/plugin`, from marketplace select `advanced-security` to activate the secret scanning skill.
2021

2122
Open `config.py` in VS Code. In Copilot Chat (`Ctrl+Alt+I`), type `#secret-scanning` to activate the skill, then paste the prompt below:
2223

2324
```
2425
Scan config.py for any hardcoded secrets, API keys, passwords, tokens, or credentials. Use the secret scanning skill to check each value against known secret patterns. List every finding with: variable name | value type | risk level | recommended fix.
2526
```
2627

27-
Then repeat for `app.py`:
28+
Then repeat for `app.py` (optional):
2829

2930
```
3031
Scan app.py for hardcoded secrets, JWT tokens, and API keys. List every finding with file, variable name, line number, and the os.environ.get() replacement needed.
@@ -34,7 +35,7 @@ Scan app.py for hardcoded secrets, JWT tokens, and API keys. List every finding
3435

3536
## Step 2 — Review a Function with VS Code Code Review (Selection Mode)
3637

37-
Open `app.py`. Select the entire `login()` function (lines 23–40).
38+
Open `app.py`. Select the entire `login()` function (lines 24–41).
3839

3940
**Right-click** the selection → **Copilot****Review and Comment**.
4041

@@ -70,9 +71,10 @@ Do not commit any changes yet — you will fix them properly in Exercises 03 and
7071

7172
## Step 5 — Customise Reviews with OWASP Instructions *(Optional)*
7273

73-
To focus every future review on OWASP Top 10 checks, add to `.github/copilot-instructions.md`:
74+
To focus every future review on OWASP Top 10 checks, create `.github/copilot-instructions.md`, select it as context in chat and then use `/create-instruction` with the following prompt:
7475

7576
```markdown
77+
Update the copilot-instructions.md file with the following content:
7678
When performing a code review, apply the OWASP Top 10 2021 checklist.
7779
Focus on: A01 Broken Access Control, A02 Cryptographic Failures, A03 Injection, A05 Security Misconfiguration.
7880
Flag any user input that reaches a database query, file path, or HTML output without sanitisation.
@@ -86,12 +88,13 @@ Flag any user input that reaches a database query, file path, or HTML output wit
8688
- [ ] Selection review on `login()` flagged the SQL injection f-string
8789
- [ ] Uncommitted changes review generated inline comments across changed files
8890
- [ ] You understand the difference between selection review and uncommitted changes review
91+
- [ ] You understand how to create copilot-instructions for customising reviews
8992

9093
---
9194

9295
## Key Takeaway
9396

94-
> Secret scanning finds committed credentials using GitHub's detection engine; VS Code Code Review surfaces broader code quality and security issues inline — both without leaving the editor.
97+
> Secret scanning finds committed credentials using GitHub's detection engine; VS Code Code Review surfaces broader code quality and security issues inline — both without leaving the editor; Copilot instructions allow you to customise the review focus.
9598
9699
---
97100

workshop/exercise-03-fix-core.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
## Background
1010

1111
These are the most dangerous vulnerabilities in SecureTrails:
12-
- **SQL Injection** (OWASP A03) — user input is directly concatenated into SQL strings at `app.py` lines 30, 52, 132. Fix: parameterized queries.
13-
- **Broken Authentication** (OWASP A01) — the `/admin` route accepts any URL parameter as `user_id` with no role check (lines 43–46). Fix: session role validation.
14-
- **IDOR** (OWASP A01) — `/trail/<trail_id>` has no ownership check and a second SQL injection (line 52). Fix: parameterized query + auth check.
12+
- **SQL Injection** (OWASP A03) — user input is directly concatenated into SQL strings at `app.py`. Fix: parameterized queries.
13+
- **Broken Authentication** (OWASP A01) — the `/admin` route accepts any URL parameter as `user_id` with no role check. Fix: session role validation.
14+
- **IDOR** (OWASP A01) — `/trail/<trail_id>` has no ownership check and a second SQL injection. Fix: parameterized query + auth check.
1515

1616
---
1717

@@ -24,7 +24,7 @@ Find every place in app.py where user input from request.args, request.form, or
2424
List each as: function name | line number | the vulnerable line of code.
2525
```
2626

27-
Expected findings: `login()` line 30, `view_trail()` line 52, `search()` line 132.
27+
Expected findings: `login()` line 30, `view_trail()` line 53, `search()` line 107.
2828

2929
---
3030

@@ -56,7 +56,7 @@ Rewrite the admin() function so it:
5656
Show the corrected function.
5757
```
5858

59-
Apply the suggested code with `Ctrl+I` on the `admin()` function.
59+
Apply the suggested code with `Ctrl+enter` on the `admin()` function.
6060

6161
---
6262

@@ -72,7 +72,7 @@ Rewrite it to:
7272
Return 403 if not authenticated.
7373
```
7474

75-
Apply with `Ctrl+I`.
75+
Apply with `Ctrl+enter`.
7676

7777
---
7878

@@ -88,7 +88,7 @@ Replace it so it:
8888
Show the corrected block.
8989
```
9090

91-
Apply with `Ctrl+I`.
91+
Apply with `Ctrl+enter`.
9292

9393
---
9494

@@ -103,15 +103,15 @@ Review the updated app.py. Confirm:
103103
3. The /trail/<id> route requires authentication
104104
List any remaining issues.
105105
```
106-
107-
Commit:
106+
All these 3 issues are now fixed.
107+
<!---Commit:
108108
109109
```bash
110110
git add app.py
111111
git commit -m "fix(security): parameterized queries (SQLi x3), admin role check, IDOR auth"
112112
git push
113113
```
114-
114+
--->
115115
---
116116

117117
## Verify

workshop/exercise-04-fix-remaining.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010

1111
After fixing SQL injection and auth in Exercise 03, these vulnerabilities remain:
1212

13-
| Vulnerability | OWASP | File | Line(s) |
14-
|---------------|-------|------|---------|
15-
| XSS — unescaped Jinja2 output | A03 | trails.html L12, L13, L17, login.html L11 | |
16-
| DOM-based XSS — `innerHTML` | A03 | js/app.js L11, trails.html L34 | |
17-
| `eval()` usage | A03 | js/app.js L2 | |
18-
| Hardcoded `SECRET_KEY` + `JWT_SECRET` | A02 | app.py L10–11 | |
19-
| Hardcoded credentials in config | A02 | config.py L6, L12, L17 | |
20-
| MD5 password hashing | A02 | app.py L63–64 | |
21-
| Debug mode always on + `/debug` endpoint | A05 | app.py L81 (DEBUG flag), L84–91 (/debug route) | |
22-
| CORS wildcard `*` | A05 | app.py L14 | |
13+
| Vulnerability | OWASP | File |
14+
|---------------|-------|------|
15+
| XSS — unescaped Jinja2 output | A03 | trails.html, login.html |
16+
| DOM-based XSS — `innerHTML` | A03 | js/app.js, trails.html |
17+
| `eval()` usage | A03 | js/app.js |
18+
| Hardcoded `SECRET_KEY` + `JWT_SECRET` | A02 | app.py|
19+
| Hardcoded credentials in config | A02 | config.py |
20+
| MD5 password hashing | A02 | app.py |
21+
| Debug mode always on + `/debug` endpoint | A05 | app.py |
22+
| CORS wildcard `*` | A05 | app.py |
2323

2424
---
2525

@@ -32,6 +32,7 @@ The Flask app initialises without explicit autoescaping. Show me how to:
3232
1. Enable Jinja2 autoescaping for all .html templates in the Flask() constructor call.
3333
2. Find and remove any {{ variable | safe }} filters in the templates that bypass autoescaping for user-controlled data.
3434
If autoescape is not set, provide the corrected constructor and list any unsafe | safe usages.
35+
3536
```
3637

3738
Apply with `Ctrl+I` on the `app = Flask(__name__)` line.

workshop/exercise-05-cli-review-agents.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
After applying IDE fixes in Exercises 03–04, the CLI provides a second verification layer:
1212
- **`/review`** — Copilot's built-in `code-review` agent analyses changes directly in the terminal, without a browser tab
13+
14+
!note:"Ensure there are local uncommitted changes before running /review; make a small test edit first if needed."
1315
- **Custom agents**`.agent.md` files in `.github/agents/` package specialist security expertise that any developer can invoke by name, reducing dependency on dedicated security team members
1416

1517
---

workshop/exercise-06-optional-cli-analysis.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ CLI interactive mode gives you a security consultant in your terminal. Unlike on
1818

1919
```bash
2020
cd securetrails-vulnerable
21-
gh copilot chat
21+
copilot
2222
```
2323

2424
---

0 commit comments

Comments
 (0)