# node labs/security/python-security-lab/python-security-lab.mjs, 2026-11-06 10:36 UTC SDS Security Lab · python-security-lab · four common Python mistakes Python 3.14.7 · 2026-11-06 10:36 UTC · throwaway data, this Mac only == 1. 再現 REPRODUCE: attack inputs against the unsafe version unsafe code: SQL in an f-string, pickle.loads on client bytes, subprocess shell=True, open(base / name) REPRODUCED SQL lookup (rows returned): x' OR '1'='1 -> 3 REPRODUCED Load a saved session (code ran on load): pickle bytes from the client -> true REPRODUCED ls on a user file name (extra command ran): hello.txt; touch /shell-ran.txt -> true REPRODUCED File download (file reachable): ../secret.env -> true == 2. 実験 EXPERIMENT: attack and normal inputs, both versions test input unsafe fixed SQL lookup (rows returned) (normal) a@example.test 1 1 SQL lookup (rows returned) (attack) x' OR '1'='1 3 0 Load a saved session (code ran on load) (att pickle bytes from the client true false ls on a user file name (extra command ran) ( hello.txt; touch /shell-ran.txt true false File download (file reachable) (normal) hello.txt true true File download (file reachable) (attack) ../secret.env true false == 3. 対策 FIX + db.execute("... WHERE email = ?", (email,)) + json.loads instead of pickle for anything a client sends + subprocess.run(["ls", path]) with a list, no shell + (base / name).resolve().is_relative_to(base) BLOCKED SQL lookup (rows returned): x' OR '1'='1 -> 0 BLOCKED Load a saved session (code ran on load): pickle bytes from the client -> false BLOCKED ls on a user file name (extra command ran): hello.txt; touch /shell-ran.txt -> false BLOCKED File download (file reachable): ../secret.env -> false == 4. レポート REPORT reproduced on unsafe version : 4/4 blocked by the fix : 4/4 normal inputs unchanged : 2/2 RESULT: FIX WORKS: every attack input reproduced on the unsafe version and was blocked by the fix; normal inputs unchanged