You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by jc...@apache.org on 2010/05/05 21:51:32 UTC

svn commit: r941451 - in /couchdb/trunk: etc/couchdb/default.ini.tpl.in share/www/script/test/rewrite.js src/couchdb/couch_httpd_rewrite.erl

Author: jchris
Date: Wed May  5 19:51:32 2010
New Revision: 941451

URL: http://svn.apache.org/viewvc?rev=941451&view=rev
Log:
rewriter security to allow isolation of databases via subdomains

Modified:
    couchdb/trunk/etc/couchdb/default.ini.tpl.in
    couchdb/trunk/share/www/script/test/rewrite.js
    couchdb/trunk/src/couchdb/couch_httpd_rewrite.erl

Modified: couchdb/trunk/etc/couchdb/default.ini.tpl.in
URL: http://svn.apache.org/viewvc/couchdb/trunk/etc/couchdb/default.ini.tpl.in?rev=941451&r1=941450&r2=941451&view=diff
==============================================================================
--- couchdb/trunk/etc/couchdb/default.ini.tpl.in (original)
+++ couchdb/trunk/etc/couchdb/default.ini.tpl.in Wed May  5 19:51:32 2010
@@ -18,6 +18,7 @@ bind_address = 127.0.0.1
 max_connections = 2048
 authentication_handlers = {couch_httpd_oauth, oauth_authentication_handler}, {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}
 default_handler = {couch_httpd_db, handle_request}
+secure_rewrites = true
 
 [log]
 file = %localstatelogdir%/couch.log

Modified: couchdb/trunk/share/www/script/test/rewrite.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/rewrite.js?rev=941451&r1=941450&r2=941451&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/rewrite.js (original)
+++ couchdb/trunk/share/www/script/test/rewrite.js Wed May  5 19:51:32 2010
@@ -137,14 +137,7 @@ couchTests.rewrite = function(debug) {
               "query": {
                 "key": [":a", ":b"]
               }
-            },
-            
-            {
-              "from": "uuids",
-              "to": "../../../_uuids"
             }
-            
-            
           ],
           lists: {
             simpleForm: stringFun(function(head, req) {
@@ -339,12 +332,29 @@ couchTests.rewrite = function(debug) {
         T(/Value: doc 4/.test(xhr.responseText));
         
         // test path relative to server
+        designDoc.rewrites.push({
+           "from": "uuids",
+           "to": "../../../_uuids"
+        });
+        T(db.save(designDoc).ok);
         
         var xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/uuids");
-        T(xhr.status == 200);
+        T(xhr.status == 500);
         var result = JSON.parse(xhr.responseText);
-        T(result.uuids.length == 1);
-        var first = result.uuids[0];
+        T(result.error == "insecure_rewrite_rule");
+
+        run_on_modified_server(
+          [{section: "httpd",
+            key: "secure_rewrites",
+            value: "false"}],
+            function() {
+              var xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/uuids?cache=bust");
+              T(xhr.status == 200);
+              var result = JSON.parse(xhr.responseText);
+              T(result.uuids.length == 1);
+              var first = result.uuids[0];
+        });
+
   });
   
 }
\ No newline at end of file

Modified: couchdb/trunk/src/couchdb/couch_httpd_rewrite.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_rewrite.erl?rev=941451&r1=941450&r2=941451&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_rewrite.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_rewrite.erl Wed May  5 19:51:32 2010
@@ -366,24 +366,34 @@ make_rule(Rule) ->
 
 parse_path(Path) ->
     {ok, SlashRE} = re:compile(<<"\\/">>),
-    path_to_list(re:split(Path, SlashRE), []).
+    path_to_list(re:split(Path, SlashRE), [], 0).
 
 %% @doc convert a path rule (from or to) to an erlang list
 %% * and path variable starting by ":" are converted
 %% in erlang atom.
-path_to_list([], Acc) ->
+path_to_list([], Acc, _DotDotCount) ->
     lists:reverse(Acc);
-path_to_list([<<>>|R], Acc) ->
-    path_to_list(R, Acc);
-path_to_list([<<"*">>|R], Acc) ->
-    path_to_list(R, [?MATCH_ALL|Acc]);
-path_to_list([P|R], Acc) ->
+path_to_list([<<>>|R], Acc, DotDotCount) ->
+    path_to_list(R, Acc, DotDotCount);
+path_to_list([<<"*">>|R], Acc, DotDotCount) ->
+    path_to_list(R, [?MATCH_ALL|Acc], DotDotCount);
+path_to_list([<<"..">>|R], Acc, DotDotCount) when DotDotCount == 2 ->
+    case couch_config:get("httpd", "secure_rewrites", "true") of
+    "false" ->
+        path_to_list(R, [<<"..">>|Acc], DotDotCount+1);
+    Else ->
+        ?LOG_INFO("insecure_rewrite_rule ~p blocked", [lists:reverse(Acc) ++ [<<"..">>] ++ R]),
+        throw({insecure_rewrite_rule, "too many ../.. segments"})
+    end;
+path_to_list([<<"..">>|R], Acc, DotDotCount) ->
+    path_to_list(R, [<<"..">>|Acc], DotDotCount+1);
+path_to_list([P|R], Acc, DotDotCount) ->
     P1 = case P of
         <<":", Var/binary>> ->
             list_to_atom(binary_to_list(Var));
         _ -> P
     end,
-    path_to_list(R, [P1|Acc]).
+    path_to_list(R, [P1|Acc], DotDotCount).
 
 encode_query(Props) ->
     Props1 = lists:foldl(fun ({K, V}, Acc) ->