You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2015/09/04 13:41:05 UTC
couch commit: updated refs/heads/master to d1dd5d6
Repository: couchdb-couch
Updated Branches:
refs/heads/master a431e6571 -> d1dd5d67e
Restrict CSRF check to specific mime types
COUCHDB-2797
Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/d1dd5d67
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/d1dd5d67
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/d1dd5d67
Branch: refs/heads/master
Commit: d1dd5d67e25d4190c96f88507fb1ed0c4225baff
Parents: a431e65
Author: Robert Newson <rn...@apache.org>
Authored: Thu Sep 3 21:42:47 2015 +0100
Committer: Robert Newson <rn...@apache.org>
Committed: Thu Sep 3 21:42:47 2015 +0100
----------------------------------------------------------------------
src/couch_httpd_csrf.erl | 37 +++++++++++++++++++++++++++++++------
1 file changed, 31 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/d1dd5d67/src/couch_httpd_csrf.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_csrf.erl b/src/couch_httpd_csrf.erl
index e765a4d..10bb175 100644
--- a/src/couch_httpd_csrf.erl
+++ b/src/couch_httpd_csrf.erl
@@ -41,16 +41,19 @@ validate(#httpd{method = 'OPTIONS'}) ->
validate(#httpd{} = Req) ->
Cookie = csrf_from_req(Req),
Header = couch_httpd:header_value(Req, "X-CouchDB-CSRF"),
- case {Cookie, Header} of
- {undefined, undefined} ->
+ Validate = lists:member(get_content_type(Req), csrf_mime_types()),
+ case {Validate, Cookie, Header} of
+ {false, _, _} ->
+ ok; % mime type is not in the list
+ {true, undefined, undefined} ->
throw_if_mandatory(Req);
- {undefined, "true"} ->
+ {true, undefined, "true"} ->
throw_if_mandatory(Req);
- {"deleted", "true"} ->
+ {true, "deleted", "true"} ->
throw_if_mandatory(Req);
- {undefined, _} ->
+ {true, undefined, _} ->
throw({forbidden, <<"CSRF header sent without Cookie">>});
- {Csrf, Csrf} ->
+ {true, Csrf, Csrf} ->
ok = validate(Csrf);
_ ->
throw({forbidden, <<"CSRF Cookie/Header mismatch">>})
@@ -196,3 +199,25 @@ timestamp() ->
csrf_mandatory() ->
config:get_boolean("csrf", "mandatory", false).
+
+get_content_type(#httpd{} = Req) ->
+ case couch_httpd:header_value(Req, "Content-Type") of
+ undefined ->
+ undefined;
+ ReqCtype ->
+ case string:tokens(ReqCtype, ";") of
+ [Ctype] -> Ctype;
+ [Ctype | _Rest] -> Ctype
+ end
+ end.
+
+csrf_mime_types() ->
+ Default =
+ "application/x-www-form-urlencoded,"
+ "multipart/form-data,"
+ "text/plain",
+ MimeTypes = config:get("csrf", "mime_types", Default),
+ split(MimeTypes).
+
+split(CSV) ->
+ re:split(CSV, "\\s*,\\s*", [trim, {return, list}]).