ftp: make the MDTM date parser stricter (again)

A previous refactor made the parser more lenient and this takes it back
to making sure only ascii digits are accepted.

Added test 1684 to verify

Follow-up to 304b5183fd

Pointed out by Codex Security

Closes #21041
This commit is contained in:
Daniel Stenberg 2026-03-20 23:27:55 +01:00
parent 96d5b5c688
commit 322db3efc0
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 60 additions and 11 deletions

View File

@ -2489,24 +2489,27 @@ static CURLcode ftp_state_port_resp(struct Curl_easy *data,
return result;
}
static int twodigit(const char *p)
/* return TRUE on error, FALSE on success */
static bool twodigit(const char *p, int *val)
{
return ((p[0] - '0') * 10) + (p[1] - '0');
if(!ISDIGIT(p[0]) || !ISDIGIT(p[1]))
return TRUE;
/* curlx_hexval() works fine here since we make sure it is decimal above */
*val = (curlx_hexval(p[0]) * 10) + curlx_hexval(p[1]);
return FALSE;
}
static bool ftp_213_date(const char *p, int *year, int *month, int *day,
int *hour, int *minute, int *second)
{
size_t len = strlen(p);
if(len < 14)
int century;
if((strlen(p) < 14) || twodigit(&p[0], &century) || twodigit(&p[2], year) ||
twodigit(&p[4], month) || twodigit(&p[6], day) ||
twodigit(&p[8], hour) || twodigit(&p[10], minute) ||
twodigit(&p[12], second))
return FALSE;
*year = (twodigit(&p[0]) * 100) + twodigit(&p[2]);
*month = twodigit(&p[4]);
*day = twodigit(&p[6]);
*hour = twodigit(&p[8]);
*minute = twodigit(&p[10]);
*second = twodigit(&p[12]);
*year += century * 100;
if((*month > 12) || (*day > 31) || (*hour > 23) || (*minute > 59) ||
(*second > 60))
return FALSE;

View File

@ -226,7 +226,7 @@ test1666 test1667 \
\
test1670 test1671 \
\
test1680 test1681 test1682 test1683 \
test1680 test1681 test1682 test1683 test1684 \
\
test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 \
test1708 test1709 test1710 test1711 test1712 test1713 \

46
tests/data/test1684 Normal file
View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="US-ASCII"?>
<testcase>
<info>
<keywords>
FTP
MDTM
</keywords>
</info>
<reply>
<data>
a joke
</data>
<mdtm>
213 2003040a102659
</mdtm>
</reply>
# Client-side
<client>
<server>
ftp
</server>
<name>
FTP with malformed MDTM response
</name>
<command>
ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -z "apr 1 2025 08:00:00"
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<protocol crlf="yes">
USER anonymous
PASS ftp@example.com
PWD
MDTM %TESTNUMBER
EPSV
TYPE I
SIZE %TESTNUMBER
RETR %TESTNUMBER
QUIT
</protocol>
</verify>
</testcase>