-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfix-sql-parameterize.sh
More file actions
executable file
·107 lines (90 loc) · 4.18 KB
/
fix-sql-parameterize.sh
File metadata and controls
executable file
·107 lines (90 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/usr/bin/env bash
# SPDX-License-Identifier: PMPL-1.0-or-later
#
# fix-sql-parameterize.sh — Replace string-interpolated SQL with parameterized queries
#
# Fixes PA012 SQLInjection findings.
# Adds warning annotations and performs safe mechanical replacements where possible.
#
# Usage: fix-sql-parameterize.sh <repo-path> <finding-json>
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/lib/third-party-excludes.sh" 2>/dev/null || true
REPO_PATH="${1:?Usage: $0 <repo-path> <finding-json>}"
FINDING_JSON="${2:?Missing finding JSON file}"
echo "=== SQL Parameterization Fix ==="
echo " Repo: $REPO_PATH"
FIXED_COUNT=0
# --- Elixir: Ecto raw SQL with string interpolation ---
while IFS= read -r -d '' file; do
rel_path="${file#$REPO_PATH/}"
changed=false
# Pattern: Ecto.Adapters.SQL.query(repo, "SELECT ... #{var} ...")
# Fix: Add warning comment
if grep -qP 'SQL\.(query|query!)\(.*, ".*#\{' "$file" 2>/dev/null; then
if ! grep -q 'SECURITY: parameterize SQL' "$file" 2>/dev/null; then
sed -i '/SQL\.\(query\|query!\)(.*".*#\{/i\ # SECURITY: parameterize SQL — use $1 placeholders instead of interpolation' "$file" 2>/dev/null || true
changed=true
fi
fi
# Pattern: Repo.query("... #{var} ...")
if grep -qP 'Repo\.\w+\(.*".*#\{' "$file" 2>/dev/null; then
if ! grep -q 'SECURITY: parameterize' "$file" 2>/dev/null; then
sed -i '/Repo\.\w\+(.*".*#\{/i\ # SECURITY: parameterize SQL — use Ecto.Query or $1 placeholders' "$file" 2>/dev/null || true
changed=true
fi
fi
if [[ "$changed" == "true" ]]; then
echo " FIXED $rel_path — added SQL parameterization warnings"
((FIXED_COUNT++)) || true
fi
done < <(find "$REPO_PATH" -type f \( -name "*.ex" -o -name "*.exs" \) \
-not -path "*/.git/*" "${FIND_THIRD_PARTY_EXCLUDES[@]}" -print0 2>/dev/null)
# --- Python: string formatting in SQL ---
while IFS= read -r -d '' file; do
rel_path="${file#$REPO_PATH/}"
changed=false
# Pattern: cursor.execute("SELECT ... %s" % var) → cursor.execute("SELECT ... %s", (var,))
# Pattern: cursor.execute(f"SELECT ... {var}") → add warning
if grep -qP 'execute\(f["\x27]' "$file" 2>/dev/null; then
if ! grep -q 'SECURITY: parameterize SQL' "$file" 2>/dev/null; then
sed -i '/execute(f["\x27]/i\ # SECURITY: parameterize SQL — use placeholder parameters instead of f-strings' "$file" 2>/dev/null || true
changed=true
fi
fi
# Pattern: execute("..." % (var)) → add warning
if grep -qP 'execute\(".*"\s*%' "$file" 2>/dev/null; then
if ! grep -q 'SECURITY: parameterize SQL' "$file" 2>/dev/null; then
sed -i '/execute(".*"\s*%/i\ # SECURITY: parameterize SQL — use ? or %s with parameter tuple' "$file" 2>/dev/null || true
changed=true
fi
fi
if [[ "$changed" == "true" ]]; then
echo " FIXED $rel_path — added SQL parameterization warnings"
((FIXED_COUNT++)) || true
fi
done < <(find "$REPO_PATH" -type f -name "*.py" \
-not -path "*/.git/*" "${FIND_THIRD_PARTY_EXCLUDES[@]}" -not -path "*/venv/*" -print0 2>/dev/null)
# --- JavaScript: string concatenation in SQL ---
while IFS= read -r -d '' file; do
rel_path="${file#$REPO_PATH/}"
changed=false
# Pattern: query("SELECT ... " + var) or query(`SELECT ... ${var}`)
if grep -qP 'query\(`.*\$\{' "$file" 2>/dev/null; then
if ! grep -q 'SECURITY: parameterize SQL' "$file" 2>/dev/null; then
sed -i '/query(`.*\$\{/i\ // SECURITY: parameterize SQL — use prepared statements with ? placeholders' "$file" 2>/dev/null || true
changed=true
fi
fi
if [[ "$changed" == "true" ]]; then
echo " FIXED $rel_path — added SQL parameterization warnings"
((FIXED_COUNT++)) || true
fi
done < <(find "$REPO_PATH" -type f \( -name "*.js" -o -name "*.mjs" \) \
-not -path "*/.git/*" "${FIND_THIRD_PARTY_EXCLUDES[@]}" -print0 2>/dev/null)
echo ""
if [[ "$FIXED_COUNT" -gt 0 ]]; then
echo "Annotated $FIXED_COUNT file(s) with SQL parameterization warnings"
else
echo "No SQL injection patterns found"
fi