diff --git a/lib/parsers.c b/lib/parsers.c
index bfda32d0..c5142519 100644
--- a/lib/parsers.c
+++ b/lib/parsers.c
@@ -297,6 +297,20 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
case URIPS_SEEN_SLASH_DOT:
/* swallow second . */
if (c == '.') {
+ /*
+ * back up one dir level if possible
+ * safe against header fragmentation because
+ * the method URI can only be in 1 fragment
+ */
+ if (wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len > 2) {
+ wsi->u.hdr.ah->pos--;
+ wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len--;
+ do {
+ wsi->u.hdr.ah->pos--;
+ wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len--;
+ } while (wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len > 1 &&
+ wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos] != '/');
+ }
wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT_DOT;
goto swallow;
}
diff --git a/test-server/attack.sh b/test-server/attack.sh
index c1279077..e6f10be1 100755
--- a/test-server/attack.sh
+++ b/test-server/attack.sh
@@ -164,32 +164,35 @@ if [ $? -ne 0 ] ; then
fi
echo
-echo "---- directory attack 4 (/blah/.. should be /blah/)"
+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
-if [ -z "`grep '
403 Forbidden
' /tmp/lwscap`" ] ; then
- echo "FAIL: should have told forbidden (test server has no dirs)"
+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 5 (/blah/../ should be /blah/)"
+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
-if [ -z "`grep '403 Forbidden
' /tmp/lwscap`" ] ; then
- echo "FAIL: should have told forbidden (test server has no dirs)"
+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 6 (/blah/../. should be /blah/)"
+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
-if [ -z "`grep '403 Forbidden
' /tmp/lwscap`" ] ; then
- echo "FAIL: should have told forbidden (test server has no dirs)"
+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