Ethical › Module 15 › Lesson 4
Lab — Rewrite a Unsafe Query You Wrote
Take a fictional concatenating snippet and write a parameterized version.
Visual · sqli_rewrite_lab
Fictional concatenating snippet on YOUR disk. You rewrite it with sqlite3 placeholders. Local catalog.db only. sqli-fix-lab.txt chmod 600. NEVER a live foreign DB.
Opening
The lab is a rewrite you author against sqlite YOU created — not a payload you fire, not sqlmap, not someone else’s database.
Lessons 1–3 gave you the grammar story, the report words, and THE fix. This lab is the artifact later quizzes will assume you have: a parameterized lookup you wrote, plus $HOME/cyberlium-lab/sqli-fix-lab.txt locked mode 600. You will read a fictional concatenating snippet (catalog SKU lookup). You will write lookup_sku.py that uses sqlite3 placeholders. You will create catalog.db as a local file under cyberlium-lab. You will run the safe lookup — including a SKU that contains a quote — to show the quote stayed data. You will not improve the unsafe snippet with extra clauses. You will not connect to a hosted URL. You will not point sqlmap at anything. This is original Cyberlium teaching mapped to the CEH v13 SQL-injection domain — not official EC-Council training, not a certification, not exam dumps. Topic 10 goes deeper in Cyberlium labs on apps you own. This lab does not unlock live SQLi. It unlocks a mode-600 file and a bind you can explain. Next is Quiz — SQL Injection, then Module 16 names SSID, encryption, and guest networks — still your home lab only. NEVER point this rewrite at a live foreign DB.
1. Lab surface: fictional glue, local sqlite file, bind tuple — no foreign DSN
unsafe_concat_snippet.py is inspect-only fiction. It shows SELECT name FROM catalog_items WHERE sku = '" + sku + "'. It must refuse to run against anything that is not a local path under cyberlium-lab, and this course tells you not to use it as a probe tool at all. Your job is lookup_sku.py: sql = "SELECT name FROM catalog_items WHERE sku = ?" then cur.execute(sql, (sku,)). HOST/path is a Path under Path.home() / "cyberlium-lab" / "catalog.db" — hardcoded, not argv, not a postgres:// URL, not a classmate’s RDS. If the path is anything else, raise SystemExit. That refusal is part of the lab, the same idea as Module 10’s HOST = "127.0.0.1".
You will seed three harmless rows (WID-100, WID-200, WID-300) in a table you created. You will look up WID-100. You will look up a SKU string that includes a quote (for example WID-100' extra) and record that the parameterized call returned no row (or only a literal match) without throwing a SQL syntax error from a broken statement. That is the mechanism proof: the quote did not finish the sentence. It is not an attack against a shop. It is not OR 1=1. Do not add UNION clauses to either file. Windows: py lookup_sku.py in PowerShell after the bash block, or run the block in WSL/Git Bash.
Command guide
Local sqlite only — WHAT/WHY (no foreign DSN)
═══ INSTALL ═══
Linux (Debian/Ubuntu):
Command — copy this
sudo apt install sqlmap sudo apt install python3
macOS:
Command — copy this
brew install sqlmap brew install python3
Windows:
Command — copy this
pip install sqlmap
Download https://python.org/downloads/
═══ COMMANDS ═══
Command — copy this
python3 - << 'PY'
from pathlib import Path
import sqlite3
p = Path.home()/'cyberlium-lab'/'catalog-lab.sqlite'
p.parent.mkdir(parents=True, exist_ok=True)
conn = sqlite3.connect(p)
conn.execute('CREATE TABLE IF NOT EXISTS catalog_items(sku TEXT, name TEXT)')
conn.execute('INSERT OR IGNORE INTO catalog_items VALUES (?,?)', ('WIDGET','Demo'))
conn.commit(); conn.close()
print('local_db', p)
print('REFUSE: foreign DSN, sqlmap, UNION cheat sheet')
PY2. Rewrite rules the checker will enforce — placeholders, not plus signs
lookup_sku.py must contain a question-mark placeholder in the SELECT, must call execute with a tuple, must not concatenate sku into the SQL with +, f-strings, .format, or percent-format, and must not import or invoke sqlmap. The checker reads YOUR source. It does not send traffic. If you left execute("SELECT ... '" + sku) in the rewrite, FAIL even if sqlite happened to return a row. If you pointed connect() at a network URL, FAIL. If sqli-fix-lab.txt still has parenthetical placeholders, FAIL. Replace every parenthetical in the notes with YOUR words.
Required notes keys: DISCLAIMER, SNIPPET (what the fictional glue did), REWRITE (placeholder + tuple in your words), PROOF (quoted SKU stayed data on local catalog.db), PATH (cyberlium-lab/catalog.db), NEVER, TOPIC10, ETHICS. DISCLAIMER must say this is original Cyberlium teaching mapped to the CEH v13 SQL-injection domain, not official EC-Council training, not a cert, not exam dumps. NEVER must forbid live foreign DBs, UNION cheat sheets, and sqlmap against strangers. TOPIC10 must say Topic 10 goes deeper.
3. What the commands do: seed local sqlite, rewrite, check source, lock mode
mkdir -p creates cyberlium-lab. Python creates catalog.db, writes the inspect-only snippet, writes lookup_sku.py, seeds rows, runs two lookups, writes sqli-fix-lab.txt template, then check_sqli_fix_lab.py reads notes plus lookup_sku.py. chmod 600 restricts the notes, the rewrite, the snippet, the checker, and the sqlite file on Unix-like systems. Windows: WSL or Git Bash for chmod, or tighten NTFS permissions on your user profile. There is no requests.get to a shop. There is no sqlmap. If you added those, you left the lab.
Rerun the checker after you edit parentheticals. A PASS that still says “then I sqlmap the café Wi-Fi portal” is an ethics fail you catch with your eyes. The confirmation checkbox is you asserting you used your eyes. Do not gist catalog.db. Do not commit production passwords. Sibling notes (sqli-string, sqli-blind-inband, sqli-parameterized) stay; they are not substitutes for sqli-fix-lab.txt.
4. Ethics line: rewrite fiction on YOUR disk — never a live foreign database
Authorized lab only: files under $HOME/cyberlium-lab. Do not attack others. Do not treat this PASS as permission to test a vendor’s search box. Do not title the folder “Official CEH v13 SQLi lab.” If you already sent a quote to a site you do not own, this lab does not launder that. Stop. Delete probe drafts. This file is a forward-looking rewrite, not an indulgence. Module 14’s bug-bounty sentence still requires a policy you actually read; this module’s default remains YOUR local sqlite file.
Keep chmod 600 on the SQLi note set. Empty any file that still contains a connection string you pasted by mistake. Topic 10 is where Cyberlium goes deeper on authorized local web labs — still not strangers, still not sqlmap-against-the-internet.
5. Wrong vs right: sqlmap / UNION against a shop vs a local bind you wrote
Worked failure — same word “lab,” opposite target. Right never needs a foreign database to prove a placeholder works.
Wrong
Point connect() at a hosted URL. Fire the concatenating snippet at a shop. Add UNION SELECT. Run sqlmap. Skip chmod. Leave parentheticals. Gist catalog.db. Check the mission box on an empty rewrite. Claim PASS grants CEH or live SQLi rights.
Right
Rewrite with sqlite3 ? and execute(sql, (sku,)). Local catalog.db only. Quoted SKU stays data. Fill sqli-fix-lab.txt, pass the checker, chmod 600. NEVER a live foreign DB. Next: Quiz — SQL Injection. Still not a CEH grant. Topic 10 goes deeper.
6. Hands-on: rewrite, local sqlite, sqli-fix-lab.txt, chmod 600
Run the block on a machine you own. Edit parentheticals in sqli-fix-lab.txt. Re-run python until PASS. Then chmod 600. Do not add network clients. Do not aim anything at a classmate.
Command guide
Seed, rewrite, check, lock — WHAT/WHY
═══ COMMANDS ═══
Command — copy this
ls -l "$HOME/cyberlium-lab/catalog-lab.sqlite" || echo "seed in heading 1 first"; chmod 600 "$NOTES"
Mission: $HOME/cyberlium-lab/sqli-fix-lab.txt (mode 600)
1) Rewrite the fictional concatenating snippet as lookup_sku.py with sqlite3 placeholders against local catalog.db only. 2) Fill DISCLAIMER, SNIPPET, REWRITE, PROOF, PATH, NEVER, TOPIC10, ETHICS in your own words; run the checker so it PASSes; chmod 600. 3) NEVER point at a live foreign DB. No UNION cheat sheet. No sqlmap. Topic 10 goes deeper. Not official EC-Council training.
Stuck? Ask Cyberlium AI Mentor
If “a real SQLi lab has to dump a live table” still feels true, ask for a hint — not a payload. Try: "Hint only: how lookup_sku.py should call execute(sql, (sku,)) with ?, why catalog.db must stay under $HOME/cyberlium-lab, why a SKU with a quote is mechanism proof rather than an attack, why NEVER must forbid a live foreign DB, why Topic 10 goes deeper, and why this is not official EC-Council training?" You still fill the file. No sqlmap. No UNION list.
You now have a parameterized rewrite this module can point at: local sqlite, locked notes, no practicing on foreign databases, no fake certification claim. Next — Quiz — SQL Injection — ten APPLY items on mechanism and parameterized queries. After the quiz, SSID, Encryption, and Guest Networks begins Module 16, still original Cyberlium, still not a CEH exam dump, still your home lab SSID only.
Knowledge Check
APPLY: check_sqli_fix_lab.py prints PASS. NEVER still says you will sqlmap a shop “so the rewrite feels real.” What did you demonstrate, and what is this lab not?
Multiple choice
Knowledge Check
APPLY: True or False: Because this lab maps to a CEH v13 domain, sqli-fix-lab.txt is official EC-Council training, grants CEH when chmod 600, and pointing lookup_sku.py at a live foreign DB is required.
True or False
Knowledge Check
APPLY: Where does the lab live, what is THE fix, and what comes next?
Multiple choice
Knowledge Check
APPLY: curl of http://192.168.0.1/ shows a home router login (TP-Link / Netgear / Huawei / "Router Admin"). Is that DEMO in scope as a hacking target?
Multiple choice