SAST với Semgrep — phân tích mã nguồn Python
🎯 Mục tiêu: Cài Semgrep, quét mã Python có lỗ hổng mẫu (SQL injection, hardcoded password), đọc report và fix.
🧰 Công cụ / nền tảng: Python 3.8+, pip, Semgrep CLI, VS Code, Git.
📦 Chuẩn bị: WSL2 hoặc Linux; Python + pip đã cài. Tài khoản GitHub (optional, cho CI).
▶️ Các bước (CLI):
# 1. Cài Semgrep
pip install semgrep
# 2. Tạo repo lab
mkdir devsecops-m25 && cd devsecops-m25
git init
# 3. Tạo file Python có lỗ hổng mẫu (intentionally vulnerable — dùng để học SAST)
cat > vuln_app.py << 'EOF'
import sqlite3
# Vulnerability 1: SQL injection — nối chuỗi trực tiếp vào query
def get_user(user_id):
conn = sqlite3.connect("users.db")
cursor = conn.cursor()
query = "SELECT * FROM users WHERE id = " + user_id # BAD
cursor.execute(query)
return cursor.fetchall()
# Vulnerability 2: Hardcoded credential
DB_PASSWORD = "SuperSecret123!"
# Vulnerability 3: subprocess với shell=True và input chưa được validate
import subprocess
def run_report(report_name):
# BAD: shell=True kết hợp input người dùng
subprocess.run("generate-report " + report_name, shell=True)
EOF
# 4. Chạy Semgrep với ruleset chuẩn cộng đồng
semgrep --config=p/python --config=p/secrets vuln_app.py
# 5. Xuất report JSON
semgrep --config=p/python --config=p/secrets vuln_app.py \
--json --output semgrep-report.json
# 6. Đọc tóm tắt findings
python3 -c "
import json
with open('semgrep-report.json') as f:
r = json.load(f)
findings = r.get('results', [])
print(f'Total findings: {len(findings)}')
for fi in findings:
sev = fi['extra']['severity']
rule = fi['check_id']
line = fi['start']['line']
print(f' [{sev}] {rule} @ line {line}')
"
# 7. Viết lại đúng bằng parameterized query (an toàn)
cat > fixed_app.py << 'EOF'
import sqlite3, subprocess, shlex
def get_user(user_id):
conn = sqlite3.connect("users.db")
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,)) # SAFE
return cursor.fetchall()
def run_report(report_name):
# SAFE: danh sách args, không dùng shell=True
subprocess.run(["generate-report", shlex.quote(report_name)], shell=False)
EOF
# 8. Xác nhận fixed_app.py qua sạch
semgrep --config=p/python fixed_app.py
echo "Semgrep exit code: $?"
✅ Kết quả mong đợi: Scan vuln_app.py phát hiện ≥ 3 findings (SQL injection, hardcoded secret, subprocess với shell=True). Scan fixed_app.py trả về 0 finding. File semgrep-report.json có field results với danh sách lỗi.
🧹 Cleanup: cd .. && rm -rf devsecops-m25 hoặc giữ lại cho LAB-122/123.