mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
http uri arguments process in fragments
This makes the URI argument processing split each parameter into a "fragment". Processing header content as fragments already exists in lws, because it's legal to deliver header content by repeating the header. Now there's an api to access individual fragments, also add the code to the test server to print each URI argument separately. Adapt attack.sh to parse the fragments. Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
parent
f35801b19d
commit
4eb36373d7
4 changed files with 75 additions and 19 deletions
|
@ -24,9 +24,6 @@
|
|||
|
||||
const unsigned char *lws_token_to_string(enum lws_token_indexes token)
|
||||
{
|
||||
if (token == WSI_TOKEN_HTTP_URI_ARGS)
|
||||
return (unsigned char *)"Uri-Args:";
|
||||
|
||||
if ((unsigned int)token >= ARRAY_SIZE(set))
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -323,8 +323,24 @@ int lws_parse(struct lws *wsi, unsigned char c)
|
|||
|
||||
switch (wsi->u.hdr.ups) {
|
||||
case URIPS_IDLE:
|
||||
/* genuine delimiter */
|
||||
if (c == '&' && !enc) {
|
||||
issue_char(wsi, c);
|
||||
/* swallow the terminator */
|
||||
ah->frags[ah->nfrag].len--;
|
||||
/* link to next fragment */
|
||||
ah->frags[ah->nfrag].nfrag = ah->nfrag + 1;
|
||||
ah->nfrag++;
|
||||
if (ah->nfrag >= ARRAY_SIZE(ah->frags))
|
||||
goto excessive;
|
||||
/* start next fragment after the & */
|
||||
ah->frags[ah->nfrag].offset = ah->pos;
|
||||
ah->frags[ah->nfrag].len = 0;
|
||||
ah->frags[ah->nfrag].nfrag = 0;
|
||||
goto swallow;
|
||||
}
|
||||
/* issue the first / always */
|
||||
if (c == '/')
|
||||
if (c == '/' && !ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS])
|
||||
wsi->u.hdr.ups = URIPS_SEEN_SLASH;
|
||||
break;
|
||||
case URIPS_SEEN_SLASH:
|
||||
|
@ -365,7 +381,8 @@ int lws_parse(struct lws *wsi, unsigned char c)
|
|||
}
|
||||
/* it was like /.dir ... regurgitate the . */
|
||||
wsi->u.hdr.ups = URIPS_IDLE;
|
||||
issue_char(wsi, '.');
|
||||
if (issue_char(wsi, '.') < 0)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case URIPS_SEEN_SLASH_DOT_DOT:
|
||||
|
@ -380,19 +397,20 @@ int lws_parse(struct lws *wsi, unsigned char c)
|
|||
break;
|
||||
}
|
||||
|
||||
if (c == '?' && !enc) { /* start of URI arguments */
|
||||
if (c == '?' && !enc &&
|
||||
!ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS]) { /* start of URI arguments */
|
||||
/* seal off uri header */
|
||||
ah->data[ah->pos++] = '\0';
|
||||
|
||||
/* move to using WSI_TOKEN_HTTP_URI_ARGS */
|
||||
ah->nfrag++;
|
||||
if (ah->nfrag >= ARRAY_SIZE(ah->frags))
|
||||
goto excessive;
|
||||
ah->frags[ah->nfrag].offset = ah->pos;
|
||||
ah->frags[ah->nfrag].len = 0;
|
||||
ah->frags[ah->nfrag].nfrag = 0;
|
||||
|
||||
ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS] = ah->nfrag;
|
||||
|
||||
/* defeat normal uri path processing */
|
||||
wsi->u.hdr.ups = URIPS_IDLE;
|
||||
goto swallow;
|
||||
}
|
||||
|
@ -501,6 +519,7 @@ swallow:
|
|||
|
||||
start_fragment:
|
||||
ah->nfrag++;
|
||||
excessive:
|
||||
if (ah->nfrag == ARRAY_SIZE(ah->frags)) {
|
||||
lwsl_warn("More hdr frags than we can deal with\n");
|
||||
return -1;
|
||||
|
|
|
@ -35,14 +35,32 @@ function check {
|
|||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" == "args" ] ; then
|
||||
a="`dd if=$LOG bs=1 skip=$LEN 2>/dev/null |grep Uri.Args\: | tr -s ' ' | cut -d' ' -f4-`"
|
||||
if [ "$1" == "1" ] ; then
|
||||
a="`dd if=$LOG bs=1 skip=$LEN 2>/dev/null |grep URI\ Arg\ 1\: | tr -s ' ' | cut -d' ' -f5-`"
|
||||
if [ "$a" != "$2" ] ; then
|
||||
echo "Args '$a' not $2"
|
||||
echo "Arg 1 '$a' not $2"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
LEN=`stat $LOG -c %s`
|
||||
|
||||
if [ "$1" == "2" ] ; then
|
||||
a="`dd if=$LOG bs=1 skip=$LEN 2>/dev/null |grep URI\ Arg\ 2\: | tr -s ' ' | cut -d' ' -f5-`"
|
||||
if [ "$a" != "$2" ] ; then
|
||||
echo "Arg 2 '$a' not $2"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ "$1" == "3" ] ; then
|
||||
a="`dd if=$LOG bs=1 skip=$LEN 2>/dev/null |grep URI\ Arg\ 3\: | tr -s ' ' | cut -d' ' -f5-`"
|
||||
if [ "$a" != "$2" ] ; then
|
||||
echo "Arg 3 '$a' not $2"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$1" ] ; then
|
||||
LEN=`stat $LOG -c %s`
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,22 +78,24 @@ echo
|
|||
echo "---- /cgi-bin/settingsjs?UPDATE_SETTINGS=1&Root_Channels_1_Channel_name_http_post=%3F&Root_Channels_1_Channel_location_http_post=%3F"
|
||||
rm -f /tmp/lwscap
|
||||
echo -e "GET /cgi-bin/settingsjs?UPDATE_SETTINGS=1&Root_Channels_1_Channel_name_http_post=%3F&Root_Channels_1_Channel_location_http_post=%3F HTTP/1.1\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
|
||||
check args "UPDATE_SETTINGS=1&Root_Channels_1_Channel_name_http_post=?&Root_Channels_1_Channel_location_http_post=?"
|
||||
|
||||
|
||||
check 1 "UPDATE_SETTINGS=1"
|
||||
check 2 "Root_Channels_1_Channel_name_http_post=?"
|
||||
check 3 "Root_Channels_1_Channel_location_http_post=?"
|
||||
check
|
||||
|
||||
echo
|
||||
echo "---- ? processing (%2f%2e%2e%2f%2e./test.html?arg=1)"
|
||||
rm -f /tmp/lwscap
|
||||
echo -e "GET %2f%2e%2e%2f%2e./test.html?arg=1 HTTP/1.1\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
|
||||
check args "arg=1"
|
||||
check 1 "arg=1"
|
||||
check
|
||||
|
||||
echo
|
||||
echo "---- ? processing (%2f%2e%2e%2f%2e./test.html?arg=/../.)"
|
||||
rm -f /tmp/lwscap
|
||||
echo -e "GET %2f%2e%2e%2f%2e./test.html?arg=/../. HTTP/1.1\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
|
||||
check args "arg=/../."
|
||||
|
||||
check 1 "arg=/../."
|
||||
check
|
||||
|
||||
echo
|
||||
echo "---- spam enough crap to not be GET"
|
||||
|
@ -172,55 +192,63 @@ echo -e "GET /test.html HTTP/1.1\x0d\x0a\x0d\x0aILLEGAL-PAYLOAD.................
|
|||
"......................................................................................................................." \
|
||||
| nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
|
||||
check default
|
||||
check
|
||||
|
||||
echo
|
||||
echo "---- directory attack 1 (/../../../../etc/passwd should be /etc/passswd)"
|
||||
rm -f /tmp/lwscap
|
||||
echo -e "GET /../../../../etc/passwd HTTP/1.1\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
|
||||
check forbidden
|
||||
check
|
||||
|
||||
echo
|
||||
echo "---- directory attack 2 (/../ should be /)"
|
||||
rm -f /tmp/lwscap
|
||||
echo -e "GET /../ HTTP/1.1\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
|
||||
check default
|
||||
check
|
||||
|
||||
echo
|
||||
echo "---- directory attack 3 (/./ should be /)"
|
||||
rm -f /tmp/lwscap
|
||||
echo -e "GET /./ HTTP/1.1\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
|
||||
check default
|
||||
check
|
||||
|
||||
echo
|
||||
echo "---- directory attack 4 (/blah/.. should be /)"
|
||||
rm -f /tmp/lwscap
|
||||
echo -e "GET /blah/.. HTTP/1.1\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
|
||||
check default
|
||||
check
|
||||
|
||||
echo
|
||||
echo "---- directory attack 5 (/blah/../ should be /)"
|
||||
rm -f /tmp/lwscap
|
||||
echo -e "GET /blah/../ HTTP/1.1\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
|
||||
check default
|
||||
check
|
||||
|
||||
echo
|
||||
echo "---- directory attack 6 (/blah/../. should be /)"
|
||||
rm -f /tmp/lwscap
|
||||
echo -e "GET /blah/../. HTTP/1.1\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
|
||||
check default
|
||||
check
|
||||
|
||||
echo
|
||||
echo "---- directory attack 7 (/%2e%2e%2f../../../etc/passwd should be /etc/passswd)"
|
||||
rm -f /tmp/lwscap
|
||||
echo -e "GET /%2e%2e%2f../../../etc/passwd HTTP/1.1\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
|
||||
check forbidden
|
||||
check
|
||||
|
||||
echo
|
||||
echo "---- directory attack 7 (%2f%2e%2e%2f%2e./.%2e/.%2e%2fetc/passwd should be /etc/passswd)"
|
||||
rm -f /tmp/lwscap
|
||||
echo -e "GET %2f%2e%2e%2f%2e./.%2e/.%2e%2fetc/passwd HTTP/1.1\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
|
||||
check forbidden
|
||||
|
||||
check
|
||||
|
||||
echo
|
||||
echo "--- survived OK ---"
|
||||
|
|
|
@ -137,6 +137,18 @@ int callback_http(struct lws_context *context, struct lws *wsi,
|
|||
|
||||
dump_handshake_info(wsi);
|
||||
|
||||
/* dump the individual URI Arg parameters */
|
||||
m = 1;
|
||||
n = 0;
|
||||
while (m > 0) {
|
||||
m = lws_hdr_copy_fragment(wsi, buf, sizeof(buf),
|
||||
WSI_TOKEN_HTTP_URI_ARGS, n);
|
||||
if (m < 0)
|
||||
continue;
|
||||
n++;
|
||||
lwsl_info("URI Arg %d: %s\n", n, buf);
|
||||
}
|
||||
|
||||
if (len < 1) {
|
||||
lws_return_http_status(context, wsi,
|
||||
HTTP_STATUS_BAD_REQUEST, NULL);
|
||||
|
|
Loading…
Add table
Reference in a new issue