summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Christopher Anderson <jchris@apache.org>2010-05-05 19:51:32 +0000
committerJohn Christopher Anderson <jchris@apache.org>2010-05-05 19:51:32 +0000
commit8aca45b45b116abaa9594fc7f065128b858613d2 (patch)
treebc0ffce8882c0ee8ea335906240f33702661ddab /src
parentd7d047f439880735377a4b8ea2ce2ef42921fff8 (diff)
rewriter security to allow isolation of databases via subdomains
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@941451 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/couchdb/couch_httpd_rewrite.erl26
1 files changed, 18 insertions, 8 deletions
diff --git a/src/couchdb/couch_httpd_rewrite.erl b/src/couchdb/couch_httpd_rewrite.erl
index 1e2a532f..c1869b5e 100644
--- a/src/couchdb/couch_httpd_rewrite.erl
+++ b/src/couchdb/couch_httpd_rewrite.erl
@@ -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) ->