CORS security: set Access-Control-Allow-Origin to the beginning in the request header

I'm not sure about the intricacies of security regarding Access-Control-Allow-Origin and cookies, etc.

I was trying to create an API that allowed authentication from any site. So I needed to install:

Access-Control-Allow-Origin

before *

and

Access-Control-Allow-Credentials

before true

This is prohibited due to security restrictions.

However, what would be the problem with setting the response header Access-Control-Allow-Origin

to the value of the Origin

request header ? Is this a massive security hole ?!

eg. (node)

// CORS
app.all('*', function (req, res, next) {
    res.header('Access-Control-Allow-Origin', req.headers.origin);
    res.header('Access-Control-Allow-Headers', 'origin, content-type, accept');
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

    if (req.method == 'OPTIONS') {
        res.status(200).end();
    }

    next();
});

      

+3


source to share


2 answers


What is the problem with setting the Access-Control-Allow-Origin response header to the Origin header value of the request?

Exactly how to resolve the beginning *

and does not require any additional effort from anyone who will attack. However, you should be able to solve it in a similar way. If you have a pre-approved list of domains that you want to allow access, you can check the domain from the submitted header Origin

, and if it matches the allowed one, you can mirror Origin

inside Access-Control-Allow-Origin

.

A security risk with *

is that it will allow any site to read content that may contain personal user data.

Since you are allowing any domain to communicate with your API with credentials (effectively Access-Control-Allow-Origin: *

and Access-Control-Allow-Credentials: true

), you are also allowing other domains to possibly capture the data.

For example, while your victim is registering with your API, the attacker forges an email to your victim to navigate to a funny video in the attacker's domain www.evil.com

. While the video of the cat is playing, the attacker domain makes an AJAX request to your API in www.example.com/Get_User_Profile_Details

and reads user data, including DOB, home address, phone number, and other data. Implied Access-Control-Allow-Origin: *

and Access-Control-Allow-Credentials: true

will allow this CORS data to be retrieved when it would normally be blocked by the Same Origin Policy .



Therefore, to protect against this, you must output a header Access-Control-Allow-Credentials

for approved domains.

I was trying to create an API that allowed authentication from any site.

If you really need access from any website, then you need to be careful. You can keep the Origin

original authentication request (i.e. the user entering their username and password) against the session ID. For each request, you will need to check Origin

and see if it matches the one Origin

stored in the server side session. If so, you output the title Access-Control-Allow-Origin: https://www.foo.com

(assuming that www.foo.com

is where the user logged in), and if you don't output Access-Control-Allow-Origin

at all.

You may also find this post interesting .

+5


source


I do not understand these things ...

I would suggest little more than just "*" in principle, since it would take some effort for the caller to insert whatever he wants.

I would suggest that if you really wanted to link things (approved users [API?]) Would need to keep the origin in the config and check every time?



As I said, I am not an expert.

For the record, Greg is sitting across from me at work .. I could talk to him about my point of view, but I wanted SO points :-)

0


source







All Articles