Possible command-injection or meta-command execution in `psql` input - Mailing list pgsql-docs
| From | PG Doc comments form |
|---|---|
| Subject | Possible command-injection or meta-command execution in `psql` input |
| Date | |
| Msg-id | 179041123000.1026192.10336293169834979882@wrigleys.postgresql.org Whole thread |
| Responses |
Re: Possible command-injection or meta-command execution in `psql` input
Re: Possible command-injection or meta-command execution in `psql` input Re: Possible command-injection or meta-command execution in `psql` input |
| List | pgsql-docs |
The following documentation comment has been logged on the website: Page: https://www.postgresql.org/docs/18/index.html Description: AI generated )) ## Summary The following SQL statement contains an unquoted regular-expression-like expression: ```sql db=# WITH products (id, name, price, action) AS ( VALUES (1, 'apple', 100, '...') , (2, 'banana', 200, '...') , (3, 'orange', 150, '...') , (4, 'potato', 80, '...') , (5, 'tomato', 120, '...') ) SELECT p.id , p.name , p.price , p.action FROM products AS p WHERE regexp_like(p.action, ((?<!-)\d+)) ; ``` The observed output is: ```text List of relations Schema | Name | Type | Owner | Persistence | Access method | Size | Description --------+----------------+-------+----------+-------------+---------------+------------+------------- public | inventory_item | table | postgres | permanent | heap | 16 kB | public | mytab | table | postgres | permanent | heap | 16 kB | public | on_hand | table | postgres | permanent | heap | 16 kB | public | suppliers | table | postgres | permanent | heap | 8192 bytes | public | test_table | table | postgres | permanent | heap | 16 kB | public | users | table | postgres | permanent | heap | 16 kB | (6 rows) db(# ``` The expected result of the SQL query would be either: ```text ERROR: invalid regular expression: parentheses () not balanced ``` or a normal result set from the `SELECT`. Instead, the output contains a relation listing followed by the continuation prompt: ```text db(# ``` ## Security concern The relation listing resembles the output of a `psql` meta-command such as: ```psql \d ``` or: ```psql \dt ``` The displayed output is not a normal result of the `SELECT` statement shown above. The query does not select from the system catalog and does not contain any statement that would produce a `List of relations` table. This raises the following questions: 1. Why does the input produce `psql` meta-command output? 2. Was a `psql` backslash command such as `\d` or `\dt` executed during processing? 3. Is the regular-expression text being interpreted as `psql` input or as SQL text? 4. Can other `psql` meta-commands be injected or executed in the same context? 5. Are the SQL parser, the `psql` client parser, and the regular-expression parser processing the input in the expected order? 6. Are there any restrictions on which backslash commands can be executed? 7. Can this behavior expose database metadata or execute other client-side commands? The concern is not limited to the meaning of `\d+` inside a regular expression. If the observed relation listing was actually generated while processing this input, then the behavior may indicate that input intended to be a regular expression is reaching the `psql` command interpreter or another command-processing layer. In that case, it should be verified whether other `psql` meta-commands can also be executed. ## Reproduction query ```sql WITH products (id, name, price, action) AS ( VALUES (1, 'apple', 100, '...') , (2, 'banana', 200, '...') , (3, 'orange', 150, '...') , (4, 'potato', 80, '...') , (5, 'tomato', 120, '...') ) SELECT p.id , p.name , p.price , p.action FROM products AS p WHERE regexp_like(p.action, ((?<!-)\d+)) ; ``` ## Control query When the regular expression is passed as a proper SQL string literal, the query should be parsed normally: ```sql WITH products (id, name, price, action) AS ( VALUES (1, 'apple', 100, '...') , (2, 'banana', 200, '...') , (3, 'orange', 150, '...') , (4, 'potato', 80, '...') , (5, 'tomato', 120, '...') ) SELECT p.id , p.name , p.price , p.action FROM products AS p WHERE regexp_like(p.action, $$((?<!-)\d+)$$); ``` or: ```sql WHERE regexp_like(p.action, '((?<!-)\d+)'); ``` These control queries do not contain any `psql` meta-command and should not produce a `List of relations` output. ## Additional observation The prompt: ```text db(# ``` indicates that `psql` is waiting for additional input because it considers the current command incomplete. The following output: ```text List of relations ``` does not appear to be generated by the `SELECT` statement itself. It is normally associated with a `psql` inspection command such as `\d` or `\dt`. Therefore, the full behavior should be investigated as a possible issue in command parsing, input sanitization, or interaction between the SQL parser and the `psql` client parser. ## Expected behavior The input should be handled consistently as one of the following: 1. A SQL syntax error should be returned because the regular-expression argument is not a valid SQL string literal; or 2. The expression should be passed to the regular-expression parser and produce a regular-expression error. It should not execute or display the result of an unrelated `psql` meta-command.
pgsql-docs by date: