BEGIN; SET LOCAL client_min_messages = WARNING; CREATE EXTENSION IF NOT EXISTS pg_curl; END; -- embedded CR/LF must be rejected before it ever reaches the wire as a -- second, attacker-controlled protocol line (HTTP header/FTP command/ -- SMTP recipient injection) BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_header_append('X-Test', E'value1\r\nX-Injected: pwned'); ERROR: curl_header_append value must not contain CR or LF characters END; BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_header_append(E'X-Test\r\nX-Injected: pwned', 'value1'); ERROR: curl_header_append name must not contain CR or LF characters END; BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_quote_append(E'PWD\r\nDELE important.txt'); ERROR: curl_quote_append command must not contain CR or LF characters END; BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_prequote_append(E'PWD\r\nDELE important.txt'); ERROR: curl_prequote_append command must not contain CR or LF characters END; BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_postquote_append(E'PWD\r\nDELE important.txt'); ERROR: curl_postquote_append command must not contain CR or LF characters END; BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_recipient_append(E'a@example.com\r\nRCPT TO:'); ERROR: curl_recipient_append email must not contain CR or LF characters END; -- mime part name/file/type/head end up in the part's header lines BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_mime_data('x', head := E'X-Part: 1\r\nX-Injected: pwned'); ERROR: curl_mime_* head must not contain CR or LF characters END; BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_mime_data('x', type := E'text/plain\r\nX-Injected: pwned'); ERROR: curl_mime_* type must not contain CR or LF characters END; BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_mime_data('x', name := E'field\r\nX-Injected: pwned'); ERROR: curl_mime_* name must not contain CR or LF characters END; BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_mime_data('x', file := E'a.txt\r\nX-Injected: pwned'); ERROR: curl_mime_* file must not contain CR or LF characters END; -- sanity: legitimate values without CR/LF must keep working BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_header_append('X-Test', 'value1'); curl_header_append -------------------- t (1 row) select curl_quote_append('PWD'); curl_quote_append ------------------- t (1 row) select curl_prequote_append('PWD'); curl_prequote_append ---------------------- t (1 row) select curl_postquote_append('PWD'); curl_postquote_append ----------------------- t (1 row) select curl_recipient_append('a@example.com'); curl_recipient_append ----------------------- t (1 row) select curl_mime_data('x', name := 'field', file := 'a.txt', type := 'text/plain', head := 'X-Part: 1'); curl_mime_data ---------------- t (1 row) END;