Skip to content

Commit ac90c6b

Browse files
weiclaude
andcommitted
fix(postgresql): guard accountProvision substitution against bash 5.2 patsub_replacement and escape SQL quotes
bash >= 5.2 enables patsub_replacement by default: in an unquoted pattern substitution replacement, & expands to the matched pattern and backslash escapes — a password containing either was silently rewritten (account created with a wrong password; verified 5.3 vs 3.2). Disable the shopt before substituting (no-op on older bash). Also close the SQL-literal boundary in the same block: escape embedded single quotes ('' escape, portable form via a quote variable — the backslash-escaped replacement form itself misbehaves on bash 3.2) so a quote in a user-supplied password can no longer break the statement, leak through psql's error context, or inject SQL in the superuser session. Per integrated-tree review: #3054 (comment) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 765ea97 commit ac90c6b

1 file changed

Lines changed: 16 additions & 4 deletions

File tree

addons/postgresql/templates/cmpd.yaml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,22 @@ spec:
257257
- -c
258258
- |
259259
# Expand the ${KB_ACCOUNT_NAME}/${KB_ACCOUNT_PASSWORD} placeholders
260-
# without eval: bash pattern substitution treats the replacement as
261-
# a literal, so credential values never go through a shell parse.
262-
statement="${KB_ACCOUNT_STATEMENT//\$\{KB_ACCOUNT_NAME\}/${KB_ACCOUNT_NAME}}"
263-
statement="${statement//\$\{KB_ACCOUNT_PASSWORD\}/${KB_ACCOUNT_PASSWORD}}"
260+
# without eval, so credential values never go through a shell parse.
261+
# bash >= 5.2 enables patsub_replacement by default, making `&` and
262+
# `\` special in the (unquoted) replacement — a password containing
263+
# them would be silently rewritten. Disable it explicitly; the shopt
264+
# is a no-op on older bash.
265+
shopt -u patsub_replacement 2>/dev/null || true
266+
# SQL-literal boundary: the statement embeds the values inside
267+
# single quotes, so escape embedded single quotes ('' is the SQL
268+
# escape) — otherwise a quote in a user-supplied password breaks
269+
# the statement, leaks the fragment via psql's error context, and
270+
# opens an injection path in a superuser session.
271+
sq="'"
272+
account_name="${KB_ACCOUNT_NAME//${sq}/${sq}${sq}}"
273+
account_password="${KB_ACCOUNT_PASSWORD//${sq}/${sq}${sq}}"
274+
statement="${KB_ACCOUNT_STATEMENT//\$\{KB_ACCOUNT_NAME\}/${account_name}}"
275+
statement="${statement//\$\{KB_ACCOUNT_PASSWORD\}/${account_password}}"
264276
psql -h 127.0.0.1 -c "${statement}"
265277
env:
266278
- name: PGUSER

0 commit comments

Comments
 (0)