uri santitation fixes deal with single dot update attack.sh

Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
Andy Green 2013-11-11 06:14:52 +08:00
parent b1a9e508cd
commit 6f42910987
3 changed files with 100 additions and 9 deletions

View file

@ -250,7 +250,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
}
wsi->u.hdr.esc_stash = c;
wsi->u.hdr.ues = URIES_SEEN_PERCENT_H1;
break;
goto swallow;
case URIES_SEEN_PERCENT_H1:
if (char_to_hex(c) < 0) {
@ -265,12 +265,14 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
}
c = (char_to_hex(wsi->u.hdr.esc_stash) << 4) |
char_to_hex(c);
wsi->u.hdr.ues = URIES_IDLE;
break;
}
/*
* special URI processing...
* convert /.. or /... etc to /
* convert /.. or /... or /../ etc to /
* convert /./ to /
* convert // or /// etc to /
* leave /.dir or whatever alone
*/
@ -298,6 +300,11 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT_DOT;
goto swallow;
}
/* change /./ to / */
if (c == '/') {
wsi->u.hdr.ups = URIPS_SEEN_SLASH;
goto swallow;
}
/* it was like /.dir ... regurgitate the . */
wsi->u.hdr.ups = URIPS_IDLE;
issue_char(wsi, '.');
@ -307,6 +314,9 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
/* swallow prior .. chars and any subsequent . */
if (c == '.')
goto swallow;
/* last issued was /, so another / == // */
if (c == '/')
goto swallow;
else /* last we issued was / so SEEN_SLASH */
wsi->u.hdr.ups = URIPS_SEEN_SLASH;
break;

View file

@ -125,16 +125,28 @@ echo -e "GET blah HTTP/1.1\x0d\x0a\x0d\x0aILLEGAL-PAYLOAD.......................
"......................................................................................................................." \
| nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
check
diff /tmp/lwscap /usr/share/libwebsockets-test-server/test.html > /dev/null
if [ $? -ne 0 ] ; then
echo "FAIL: got something other than test.html back"
size=`stat /tmp/lwscap | grep Size: | tr -s ' ' | cut -d' ' -f3`
if [ $size -ne 0 ] ; then
echo "FAIL: got something back when should have hung up"
cat /tmp/lwscap
exit 1
fi
echo
echo "---- directory attack"
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
echo -e "GET /../../../../etc/passwd HTTP/1.1\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
check
size=`stat /tmp/lwscap | grep Size: | tr -s ' ' | cut -d' ' -f3`
if [ $size -ne 0 ] ; then
echo "FAIL: got something back when should have hung up"
exit 1
fi
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
diff /tmp/lwscap /usr/share/libwebsockets-test-server/test.html > /dev/null
if [ $? -ne 0 ] ; then
@ -142,6 +154,73 @@ if [ $? -ne 0 ] ; then
exit 1
fi
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
diff /tmp/lwscap /usr/share/libwebsockets-test-server/test.html > /dev/null
if [ $? -ne 0 ] ; then
echo "FAIL: got something other than test.html back"
exit 1
fi
echo
echo "---- directory attack 4 (/blah/.. should be /blah/)"
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
size=`stat /tmp/lwscap | grep Size: | tr -s ' ' | cut -d' ' -f3`
if [ $size -ne 0 ] ; then
echo "FAIL: got something back when should have hung up"
exit 1
fi
echo
echo "---- directory attack 5 (/blah/../ should be /blah/)"
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
size=`stat /tmp/lwscap | grep Size: | tr -s ' ' | cut -d' ' -f3`
if [ $size -ne 0 ] ; then
echo "FAIL: got something back when should have hung up"
exit 1
fi
echo
echo "---- directory attack 6 (/blah/../. should be /blah/)"
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
size=`stat /tmp/lwscap | grep Size: | tr -s ' ' | cut -d' ' -f3`
if [ $size -ne 0 ] ; then
echo "FAIL: got something back when should have hung up"
exit 1
fi
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
size=`stat /tmp/lwscap | grep Size: | tr -s ' ' | cut -d' ' -f3`
if [ $size -ne 0 ] ; then
echo "FAIL: got something back when should have hung up"
exit 1
fi
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
size=`stat /tmp/lwscap | grep Size: | tr -s ' ' | cut -d' ' -f3`
if [ $size -ne 0 ] ; then
echo "FAIL: got something back when should have hung up"
exit 1
fi
echo
echo "--- survived"
kill -2 $CPID

View file

@ -210,9 +210,11 @@ static int callback_http(struct libwebsocket_context *context,
/* if not, send a file the easy way */
strcpy(buf, resource_path);
if (strcmp(in, "/"))
if (strcmp(in, "/")) {
if (*((const char *)in) != '/')
strcat(buf, "/");
strncat(buf, in, sizeof(buf) - strlen(resource_path));
else /* default file to serve */
} else /* default file to serve */
strcat(buf, "/test.html");
buf[sizeof(buf) - 1] = '\0';
mimetype = get_mimetype(buf);