Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a downside to always returning Access-Control-Allow-Credentials?

A weird CORS question...

I have code in my example.com server which returns the Access-Control-Allow-Origin response header for all POST & GET requests where the Origin request header is passed and it has a value of an example.com sub-domain (superman.example.com, batman.example.com, etc.).

I now need to be able to make AJAX calls passing cookies, so I need to be able to return the Access-Control-Allow-Credentials response header if the request includes cookies.

I could add an additional check to return the Access-Control-Allow-Credentials response header if I see the Cookie request header, but for simplicity, I'm wondering if there is any downside to always returning the Access-Control-Allow-Credentials response header for all GET/POST requests from my sub-domains, where the Origin request header is specified.

Here's my code (it's a Tcl iRule, FWIW):

when HTTP_REQUEST priority 200 {
    if { ( [HTTP::method] equals "OPTIONS" ) and
         ( [HTTP::host] ends_with "example.com"] ) and
         ( [HTTP::header exists "Access-Control-Request-Method"]) } {
        HTTP::respond 200 "Access-Control-Allow-Origin" [HTTP::header "Origin"] \
                          "Access-Control-Allow-Methods" "POST, GET, OPTIONS" \
                          "Access-Control-Allow-Headers" [HTTP::header "Access-Control-Request-Headers"] \
                          "Access-Control-Max-Age" "86400"       
    } elseif { ( [HTTP::host] ends_with "example.com"] ) and
               ( [HTTP::header exists "Origin"]) } {
        # CORS GET/POST requests - set cors_origin variable
        set cors_origin [HTTP::header "Origin"]
    }
}
when HTTP_RESPONSE {
    # CORS GET/POST response - check cors_origin variable set in request
    if { [info exists cors_origin] } {
        HTTP::header insert "Access-Control-Allow-Origin" $cors_origin
        HTTP::header insert "Access-Control-Allow-Credentials" "true"
    }
}

I am aware that if I return the Access-Control-Allow-Credentials response header, I have to specify a named (non-generic) Access-Control-Allow-Origin header (and that may have Vary header issues), but is there anything else I need to be aware of?

like image 926
roryhewitt Avatar asked Nov 21 '22 05:11

roryhewitt


1 Answers

If you take defence in depth into consideration, unconditionally including

Access-Control-Allow-Credentials: true

in responses is a bad idea. Your app may indeed be vulnerable to HTTP-header injection. Imagine a situation where the attacker is able to inject—perhaps via a query parameter in the URL—exactly one arbitrary HTTP header in the response. In that case, the attacker would effectively be able to force responses to contain the following headers,

Access-Control-Allow-Origin: https://attacker.com
Access-Control-Allow-Credentials: true

which would leave the content wide open to cross-origin attacks from https://attacker.com.

James Kettle mentions something similar in his AppSecUSA 2016 talk, entitled Exploiting CORS Misconfigurations for Bitcoins and Bounties:

It's quite common to find classic HTTP-header-injection vulnerabilities where, for whatever reason, you can't inject into the response content. You can't just inject malicious HTML; the only thing you can do is set HTTP headers. And CORS offers a brilliant way of exploiting this because you can just say

This content is open to everyone!

using CORS and then attackers can get hold of that [...]

like image 191
jub0bs Avatar answered Dec 21 '22 00:12

jub0bs