You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ei...@apache.org on 2016/04/13 04:19:40 UTC

chttpd commit: updated refs/heads/master to 02202d3

Repository: couchdb-chttpd
Updated Branches:
  refs/heads/master 4c0564fc3 -> 02202d326


Reject incorrectly encoded urls

COUCHDB-2748


Project: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/commit/02202d32
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/02202d32
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/02202d32

Branch: refs/heads/master
Commit: 02202d326ba551baddec256cb558be2fb09d6f6c
Parents: 4c0564f
Author: Eric Avdey <ei...@eiri.ca>
Authored: Tue Apr 12 15:39:29 2016 -0300
Committer: Eric Avdey <ei...@eiri.ca>
Committed: Tue Apr 12 23:07:30 2016 -0300

----------------------------------------------------------------------
 include/chttpd.hrl |  6 +++++
 src/chttpd.erl     | 67 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/02202d32/include/chttpd.hrl
----------------------------------------------------------------------
diff --git a/include/chttpd.hrl b/include/chttpd.hrl
index 9d3bd97..a7f9aaa 100644
--- a/include/chttpd.hrl
+++ b/include/chttpd.hrl
@@ -20,3 +20,9 @@
     should_log = true,
     reason
 }).
+
+-define(is_hex(C), (
+    (C >= $0 andalso C =< $9) orelse
+    (C >= $a andalso C =< $f) orelse
+    (C >= $A andalso C =< $F)
+)).

http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/02202d32/src/chttpd.erl
----------------------------------------------------------------------
diff --git a/src/chttpd.erl b/src/chttpd.erl
index 8400b35..3d2f3d9 100644
--- a/src/chttpd.erl
+++ b/src/chttpd.erl
@@ -281,6 +281,7 @@ process_request(#httpd{mochi_req = MochiReq} = HttpReq) ->
     try
         couch_httpd:validate_host(HttpReq),
         check_request_uri_length(RawUri),
+        check_url_encoding(RawUri),
         case chttpd_cors:maybe_handle_preflight_request(HttpReq) of
         not_preflight ->
             case chttpd_auth:authenticate(HttpReq, fun authenticate_request/1) of
@@ -406,6 +407,15 @@ check_request_uri_length(Uri, MaxUriLen) when is_list(MaxUriLen) ->
             ok
     end.
 
+check_url_encoding([]) ->
+    ok;
+check_url_encoding([$%, A, B | Rest]) when ?is_hex(A), ?is_hex(B) ->
+    check_url_encoding(Rest);
+check_url_encoding([$% | _]) ->
+    throw({bad_request, invalid_url_encoding});
+check_url_encoding([_ | Rest]) ->
+    check_url_encoding(Rest).
+
 fix_uri(Req, Props, Type) ->
     case replication_uri(Type, Props) of
     undefined ->
@@ -1074,3 +1084,60 @@ respond_(#httpd{mochi_req = MochiReq}, Code, Headers, _Args, start_response) ->
     MochiReq:start_response({Code, Headers});
 respond_(#httpd{mochi_req = MochiReq}, Code, Headers, Args, Type) ->
     MochiReq:Type({Code, Headers, Args}).
+
+
+-ifdef(TEST).
+
+-include_lib("eunit/include/eunit.hrl").
+
+check_url_encoding_pass_test_() ->
+    [
+        ?_assertEqual(ok, check_url_encoding("/dbname")),
+        ?_assertEqual(ok, check_url_encoding("/dbname/doc_id")),
+        ?_assertEqual(ok, check_url_encoding("/dbname/doc_id?rev=1-abcdefgh")),
+        ?_assertEqual(ok, check_url_encoding("/dbname%25")),
+        ?_assertEqual(ok, check_url_encoding("/dbname/doc_id%25")),
+        ?_assertEqual(ok, check_url_encoding("/dbname%25%3a")),
+        ?_assertEqual(ok, check_url_encoding("/dbname/doc_id%25%3a")),
+        ?_assertEqual(ok, check_url_encoding("/user%2Fdbname")),
+        ?_assertEqual(ok, check_url_encoding("/user%2Fdbname/doc_id")),
+        ?_assertEqual(ok, check_url_encoding("/dbname/escaped%25doc_id")),
+        ?_assertEqual(ok, check_url_encoding("/dbname/doc%2eid")),
+        ?_assertEqual(ok, check_url_encoding("/dbname/doc%2Eid")),
+        ?_assertEqual(ok, check_url_encoding("/dbname-with-dash")),
+        ?_assertEqual(ok, check_url_encoding("/dbname/doc_id-with-dash"))
+    ].
+
+check_url_encoding_fail_test_() ->
+    [
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/dbname%")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/dbname/doc_id%")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/dbname/doc_id%?rev=1-abcdefgh")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/dbname%2")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/dbname/doc_id%2")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/user%2Fdbname%")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/user%2Fdbname/doc_id%")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("%")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/%")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/%2")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/dbname%2%3A")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/dbname%%3Ae")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/dbname%2g")),
+        ?_assertThrow({bad_request, invalid_url_encoding},
+            check_url_encoding("/dbname%g2"))
+    ].
+
+-endif.