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}]).