From 366b6ec28bc939a5f68a828b581ca05a240aa1af Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 13 Jul 2026 23:07:30 +0200 Subject: [PATCH 1/2] tool_getparam: reject argument to options using CRLF Unless explcitly allowed, like for -w. To reduce the risk that users get funny and unexpected results. Verify in test 2016 --- src/tool_getparam.c | 17 ++++++++++++++++- src/tool_getparam.h | 1 + tests/data/Makefile.am | 2 +- tests/data/test2016 | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 tests/data/test2016 diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 9d34ffad20..a845332a19 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -369,7 +369,7 @@ static const struct LongShort aliases[] = { #ifdef USE_WATT32 {"wdebug", ARG_BOOL, ' ', C_WDEBUG}, #endif - {"write-out", ARG_STRG, 'w', C_WRITE_OUT}, + {"write-out", ARG_STRG|ARG_CRLF, 'w', C_WRITE_OUT}, {"xattr", ARG_BOOL, ' ', C_XATTR}, }; @@ -2899,6 +2899,16 @@ static bool has_leading_unicode(const unsigned char *arg) return (arg[0] == 0xe2) && (arg[1] == 0x80) && (arg[2] & 0x80); } +static bool has_crlf(const char *arg) +{ + while(*arg) { + if(ISNEWLINE(*arg)) + return TRUE; + arg++; + } + return FALSE; +} + /* the longest command line option, excluding the leading -- */ #define MAX_OPTION_LEN 26 @@ -3034,6 +3044,11 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ break; } + if(!(a->desc & ARG_CRLF) && has_crlf(nextarg)) { + errorf("Argument contains CR or LF"); + err = PARAM_BAD_USE; + break; + } if(has_leading_unicode((const unsigned char *)nextarg)) { warnf("The argument '%s' starts with a Unicode character. " "Maybe ASCII was intended?", nextarg); diff --git a/src/tool_getparam.h b/src/tool_getparam.h index 32476d3776..cafbaab857 100644 --- a/src/tool_getparam.h +++ b/src/tool_getparam.h @@ -324,6 +324,7 @@ typedef enum { #define ARG_TYPEMASK 0x07 #define ARGTYPE(x) ((x) & ARG_TYPEMASK) +#define ARG_CRLF 0x08 /* allow CR and LF in argument */ #define ARG_DEPR 0x10 /* deprecated option */ #define ARG_CLEAR 0x20 /* clear cmdline argument */ #define ARG_TLS 0x40 /* requires TLS support */ diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 45df544649..4f5167bb3d 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -242,7 +242,7 @@ test1979 test1980 test1981 test1982 test1983 test1984 \ \ test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \ test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \ -\ +test2016 \ test2023 \ test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \ test2032 test2033 test2034 test2035 test2036 test2037 test2038 test2039 \ diff --git a/tests/data/test2016 b/tests/data/test2016 new file mode 100644 index 0000000000..b392713fea --- /dev/null +++ b/tests/data/test2016 @@ -0,0 +1,32 @@ + + + + +HTTP + + + +# Server-side + + + +# Client-side + + +http + + +Attempt sending a carriage return in a HTTP header + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER -H 'A: %CR' + + + +# Verify data after the test has been "shot" + + +2 + + + From 1ac3975fcd0a44c0735dbb380d32d5689c160e35 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 15 Jul 2026 14:07:35 +0200 Subject: [PATCH 2/2] add exceptions to the --data* options --- src/tool_getparam.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tool_getparam.c b/src/tool_getparam.c index a845332a19..3ad753eb22 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -103,11 +103,11 @@ static const struct LongShort aliases[] = { {"crlf", ARG_BOOL, ' ', C_CRLF}, {"crlfile", ARG_FILE|ARG_TLS, ' ', C_CRLFILE}, {"curves", ARG_STRG|ARG_TLS, ' ', C_CURVES}, - {"data", ARG_STRG, 'd', C_DATA}, - {"data-ascii", ARG_STRG, ' ', C_DATA_ASCII}, - {"data-binary", ARG_STRG, ' ', C_DATA_BINARY}, - {"data-raw", ARG_STRG, ' ', C_DATA_RAW}, - {"data-urlencode", ARG_STRG, ' ', C_DATA_URLENCODE}, + {"data", ARG_STRG|ARG_CRLF, 'd', C_DATA}, + {"data-ascii", ARG_STRG|ARG_CRLF, ' ', C_DATA_ASCII}, + {"data-binary", ARG_STRG|ARG_CRLF, ' ', C_DATA_BINARY}, + {"data-raw", ARG_STRG|ARG_CRLF, ' ', C_DATA_RAW}, + {"data-urlencode", ARG_STRG|ARG_CRLF, ' ', C_DATA_URLENCODE}, {"delegation", ARG_STRG, ' ', C_DELEGATION}, {"digest", ARG_BOOL, ' ', C_DIGEST}, {"disable", ARG_BOOL, 'q', C_DISABLE},