T09 · Insecure Skill Coding Practices
- Location
scripts/db_readonly.sh:25- Finding
Read-Only SQL Policy Bypass Through Stacked Statements and Incomplete Keyword Filtering
- Content
View full analysis
&2 exit 2 fi if ! printf '%s' "$LOWER_SQL" | grep -Eq '^\s*(select|with|explain)\b'; then echo "Blocked: only SELECT/WITH/EXPLAIN statements are allowed." >&2 exit 2 fi ``` The validated SQL is subsequently passed in full to the database clients: ```bash run_postgres() { local psql_cmd=(psql -v ON_ERROR_STOP=1 -X) case "$FORMAT" in table) psql_cmd+=( -P pager=off -c "$SQL" ) ;; csv) psql_cmd+=( -P pager=off -c "\\copy ($SQL) TO STDOUT WITH CSV HEADER" ) ;; tsv) psql_cmd+=( -P pager=off -F $'\t' -A -c "$SQL" ) ;; json) psql_cmd+=( -P pager=off -t -A -c "SELECT json_agg(t) FROM ($SQL) t;" ) ;; *) echo "Unsupported format: $FORMAT" >&2; exit 1 ;; esac ``` ```bash local query="$SQL" if [ "$FORMAT" = "json" ]; then query="SELECT JSON_ARRAYAGG(j) FROM (SELECT * FROM ($SQL) s) j;" fi if [ -n "$OUT" ]; then "${mysql_cmd[@]}" -e "$query" > "$OUT" echo "Saved to $OUT" else "${mysql_cmd[@]}" -e "$query" fi ``` ### Technical Analysis The script treats SQL as read-only when it starts with `SELECT`, `WITH`, or `EXPLAIN` and does not contain one of a limited set of denied keywords. This is not equivalent to parsing SQL or enforcing a single read-only statement. The validation has two fundamental weaknesses: 1. It does not reject statement separators or ensure that the input contains exactly one SQL statement. 2. Its denylist is incomplete ...[truncated 2399 chars]- Remediation
View remediation
