SIGN IN SIGN UP

fix: Prevent OS command injection in Import/Export query export (CWE-78) (#9899)

User-supplied input was interpolated directly into a psql \copy
metacommand template without sanitization. An authenticated pgAdmin
user could inject ") TO PROGRAM 'cmd'" to achieve RCE on the pgAdmin
server, or ") TO '/path'" for arbitrary file write, by breaking out
of the \copy (...) context.

Add _is_query_parens_balanced() which tracks parenthesis depth in the
query, modeled on psql's strtokx tokenizer used by parse_slash_copy.
Only single-quoted strings ('...' with '' and \' escaping) and
double-quoted identifiers ("..." with "" escaping) are recognized;
line/block comments and dollar-quoting are deliberately NOT skipped
because psql's \copy parser does not recognize them either, so any
unbalanced ')' inside those constructs must remain visible to the
validator.

Whitelist-validate format, on_error, and log_verbosity which were
also raw-interpolated, and write the normalized lowercase value back
to data so downstream template equality checks (e.g. data.format ==
'csv') match regardless of input case.

Reject queries containing null bytes (which could cause a C-string
truncation mismatch between Python validation and psql execution)
and normalize \r\n / \r / \n to spaces (required for Windows; also
prevents psql metacommand termination).

Type-check 'query' before string operations so malformed payloads
return a clean 400 instead of a 500. Tighten is_query_export gating
to 'is True' in both update_data_for_import_export and the validation
block so a client cannot exploit a truthy-but-not-True value to
bypass one check while satisfying the other.

Add unit tests covering the parens parser (balanced cases, RCE
attempts, escape edge cases) and route-level tests asserting
BatchProcess is not invoked for malicious payloads.

Reported-by: chungkn (Chung Kim), OneMount Group <kimngocchung.k2a@gmail.com>
A
Ashesh Vashi committed
13badc62c3ac985cdd0f9764af60686cdd574ac5
Parent: cf53953