mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-16 00:00:07 +01:00
Subject: [PATCH] uri parsing: improve dot-dot handling
https://github.com/warmcat/libwebsockets/issues/481 - don't treat .../ or ..dir/ like ../ - fix handling of GET /folder/../other/ Signed-off-by: Denis Osvald <denis.osvald@sartura.hr>
This commit is contained in:
parent
513580d1bd
commit
b6cce7d8a3
2 changed files with 22 additions and 10 deletions
|
@ -693,20 +693,22 @@ lws_parse(struct lws *wsi, unsigned char c)
|
||||||
case URIPS_SEEN_SLASH_DOT:
|
case URIPS_SEEN_SLASH_DOT:
|
||||||
/* swallow second . */
|
/* swallow second . */
|
||||||
if (c == '.') {
|
if (c == '.') {
|
||||||
|
/* stash pos in case /..dir */
|
||||||
|
wsi->u.hdr.slashdotdot_pos_stash = ah->pos;
|
||||||
/*
|
/*
|
||||||
* back up one dir level if possible
|
* back up one dir level if possible
|
||||||
* safe against header fragmentation because
|
* safe against header fragmentation because
|
||||||
* the method URI can only be in 1 fragment
|
* the method URI can only be in 1 fragment
|
||||||
*/
|
*/
|
||||||
if (ah->frags[ah->nfrag].len > 2) {
|
if (ah->frags[ah->nfrag].len > 2) {
|
||||||
ah->pos--;
|
|
||||||
ah->frags[ah->nfrag].len--;
|
|
||||||
do {
|
do {
|
||||||
ah->pos--;
|
ah->pos--;
|
||||||
ah->frags[ah->nfrag].len--;
|
ah->frags[ah->nfrag].len--;
|
||||||
} while (ah->frags[ah->nfrag].len > 1 &&
|
} while (ah->frags[ah->nfrag].len > 1 &&
|
||||||
ah->data[ah->pos] != '/');
|
ah->data[ah->pos-1] != '/');
|
||||||
}
|
}
|
||||||
|
lwsl_parser("URIPS: ../ : backed up '%.*s'\n",
|
||||||
|
wsi->u.hdr.slashdotdot_pos_stash - ah->pos, ah->data + ah->pos);
|
||||||
wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT_DOT;
|
wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT_DOT;
|
||||||
goto swallow;
|
goto swallow;
|
||||||
}
|
}
|
||||||
|
@ -722,14 +724,22 @@ lws_parse(struct lws *wsi, unsigned char c)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case URIPS_SEEN_SLASH_DOT_DOT:
|
case URIPS_SEEN_SLASH_DOT_DOT:
|
||||||
/* swallow prior .. chars and any subsequent . */
|
/* back up one dir level */
|
||||||
if (c == '.')
|
if (c == '/') {
|
||||||
goto swallow;
|
/* we kept last slash, mark it SEEN */
|
||||||
/* last issued was /, so another / == // */
|
|
||||||
if (c == '/')
|
|
||||||
goto swallow;
|
|
||||||
/* last we issued was / so SEEN_SLASH */
|
|
||||||
wsi->u.hdr.ups = URIPS_SEEN_SLASH;
|
wsi->u.hdr.ups = URIPS_SEEN_SLASH;
|
||||||
|
goto swallow;
|
||||||
|
}
|
||||||
|
/* it was like /..dir ... restore prev dir and regurgitate the .. */
|
||||||
|
lwsl_parser("URIPS: ../ : restore '%.*s'\n",
|
||||||
|
wsi->u.hdr.slashdotdot_pos_stash - ah->pos, ah->data + ah->pos);
|
||||||
|
ah->frags[ah->nfrag].len += wsi->u.hdr.slashdotdot_pos_stash - ah->pos;
|
||||||
|
ah->pos = wsi->u.hdr.slashdotdot_pos_stash;
|
||||||
|
if (issue_char(wsi, '.') < 0)
|
||||||
|
return -1;
|
||||||
|
if (issue_char(wsi, '.') < 0)
|
||||||
|
return -1;
|
||||||
|
wsi->u.hdr.ups = URIPS_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -893,6 +893,8 @@ struct _lws_header_related {
|
||||||
#ifndef LWS_NO_CLIENT
|
#ifndef LWS_NO_CLIENT
|
||||||
unsigned short c_port;
|
unsigned short c_port;
|
||||||
#endif
|
#endif
|
||||||
|
unsigned short slashdotdot_pos_stash;
|
||||||
|
|
||||||
char esc_stash;
|
char esc_stash;
|
||||||
char post_literal_equal;
|
char post_literal_equal;
|
||||||
unsigned char parser_state; /* enum lws_token_indexes */
|
unsigned char parser_state; /* enum lws_token_indexes */
|
||||||
|
|
Loading…
Add table
Reference in a new issue