Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Add query to detect CORS misconfiguration#542

Merged
smowton merged 14 commits intogithub:mainfrom
gagliardetto:cors-misconfig
Jul 16, 2021
Merged

Add query to detect CORS misconfiguration#542
smowton merged 14 commits intogithub:mainfrom
gagliardetto:cors-misconfig

Conversation

@gagliardetto
Copy link
Copy Markdown
Contributor

This PR add a new experimental query that looks for misconfigured CORS headers that are too widely permissive on the accepted origins (i.e. set the Access-Control-Allow-Origin to unsafe values) while also allowing the inclusion of cookies on the request (i.e. Access-Control-Allow-Credentials: true).

CWE-942: Permissive Cross-domain Policy with Untrusted Domains

@gagliardetto gagliardetto requested a review from a team as a code owner May 22, 2021 16:18
@gagliardetto
Copy link
Copy Markdown
Contributor Author

I'm running a scan on lgtm.com to see how many FPs there are because of checks on the user-provided values (scenarios like if isValidOrigin(origin)); will then update the query.

@smowton
Copy link
Copy Markdown
Contributor

smowton commented May 27, 2021

Are you done updating this?

@smowton
Copy link
Copy Markdown
Contributor

smowton commented May 27, 2021

Also I note we already have CORS-related queries for JavaScript and Java; is this intended as a port of either one, or was it written from scratch?

@gagliardetto
Copy link
Copy Markdown
Contributor Author

gagliardetto commented May 27, 2021 via email

@gagliardetto
Copy link
Copy Markdown
Contributor Author

gagliardetto commented Jun 3, 2021

I scanned 3.743 projects, and got 39 results.

Some of them were false positives, so I added a flag check that helps get rid of them.

Some of the rest of the 39 are technically true positives, but do not lead to a security vulnerability scenario.

@smowton
Copy link
Copy Markdown
Contributor

smowton commented Jun 3, 2021

Are you declaring this ready to review?

@gagliardetto
Copy link
Copy Markdown
Contributor Author

Yes, I am.

PR ready for review.

@gagliardetto
Copy link
Copy Markdown
Contributor Author

I'll write today the issue for https://github.com/github/securitylab

@smowton
Copy link
Copy Markdown
Contributor

smowton commented Jun 3, 2021

Aha, excellent -- in that case know that the seclab now do the early review stages (though I imagine since this is a well-known vuln category and produces good results, it'll come back to us in short order). I'll review once they're done commenting.

@gagliardetto
Copy link
Copy Markdown
Contributor Author

Will they run the query on all go projects?

@JarLob
Copy link
Copy Markdown

JarLob commented Jun 9, 2021

Hi @gagliardetto,
There is a safety catch for

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

Browsers won't allow credentials in this case. You need to fix your tests in several places.

Regarding the Example:,
We encourage security researchers to responsibly report all found 0days and accept old CVEs and past vulnerable source revisions if they are detected by submitted queries.
In this case it can be a TP if a custom authentication header is not always required, but also can be a FP. Did you try to contact the maintainers?
Also you may consider filtering the cases like this to reduce FP rate.

@gagliardetto
Copy link
Copy Markdown
Contributor Author

Hi @gagliardetto,
There is a safety catch for

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

Browsers won't allow credentials in this case. You need to fix your tests in several places.

Thanks! I somehow managed to forget that part...

@gagliardetto
Copy link
Copy Markdown
Contributor Author

Regarding the Example:,
We encourage security researchers to responsibly report all found 0days and accept old CVEs and past vulnerable source revisions if they are detected by submitted queries.
In this case it can be a TP if a custom authentication header is not always required, but also can be a FP. Did you try to contact the maintainers?
Also you may consider filtering the cases like this to reduce FP rate.

Can we put that in the all-for-one.md Issue template, suggesting a clear alternative method for researchers to communicate the one useful result found by your query to the seclab? I found dozens of results, but I don't have the time or resources to go after them (otherwise I would have opened a Bug Slayer ticket instead of the All For One.)

I tried to pick the most ambiguous and difficult result to exploit. Still, the query is public and can be run by anyone, so that doesn't really "protect" from disclosure. But I do understand that making things extra easy is not really a good thing.

@JarLob
Copy link
Copy Markdown

JarLob commented Jun 10, 2021

Great, I saw you have created github/securitylab#382

Imho, we expect people to provide some recent CVE (not too old, it still has to be relevant 😅), that could have been found with the query. That's why it can be a source snapshot from the past. Usual path is to look for advisories and say hey, my query would find the vuln in that revision before the fix. Finding a vuln in existing project is OK too, but you have to at least try to do a coordinated disclosure before dropping it publicly. It boils down to: is it real vulnerability that happens in real apps (proof) or just a made up assumption like if you pass untrusted input to CompileAndRun it may lead to RCE (but it doesn't really happen).
Just my Imho.

@gagliardetto
Copy link
Copy Markdown
Contributor Author

provide some recent CVE [...] that could have been found with the query

Oh, I always thought that I had to provide CVEs that I had found and created thanks to the query.

@JarLob
Copy link
Copy Markdown

JarLob commented Jun 10, 2021

If you find at least 4 your name is Bug Slayer :D

@gagliardetto
Copy link
Copy Markdown
Contributor Author

is it real vulnerability that happens in real apps (proof) or just a made up assumption

I like that phrasing; I'll add that.

@gagliardetto
Copy link
Copy Markdown
Contributor Author

Finding a vuln in existing project is OK too, but you have to at least try to do a coordinated disclosure before dropping it publicly.

You are absolutely right.

Daily realities sometimes diverge from the rightful and ideal path.

I want to make sure the security lab can still catch them.


override predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource }

override predicate isSink(DataFlow::Node sink) { any() }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be very expensive. Instead of computing flow to absolutely any expression then filtering in isGuardedByCheckOnUntrusted, do your filtering here (i.e., first find if-conditions that control header writes, then enumerate interesting descendents of those if-conditions, which are either string-suffix checks or map-membership checks or equality test operands), then check for untrusted flow.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make more sense with how I updated it now? @smowton

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, much better

Comment on lines +148 to +150
operand = child or
operand = child.(LorExpr).getAnOperand() or
operand = child.(LandExpr).getAnOperand()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely getAChildExpr() applied one more time takes care of cases 2 and 3?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow what you mean here..

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, you already use getAChildExpr*(), so why do you need to special-case LorExpr and LandExpr?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, it work without them.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, actually it doesn't

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, my bad. Removed too much. It's all good.

@gagliardetto
Copy link
Copy Markdown
Contributor Author

gagliardetto commented Jul 9, 2021 via email

@gagliardetto
Copy link
Copy Markdown
Contributor Author

All good now? @smowton

Comment thread ql/src/experimental/CWE-942/CorsMisconfiguration.ql Outdated
Comment thread ql/src/experimental/CWE-942/CorsMisconfiguration.ql Outdated
/**
* Holds if the provided `dst` is also destination of a `UntrustedFlowSource`.
*/
predicate flowsToGuardedByCheckOnUntrusted(HTTP::HeaderWrite allowOriginHW) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Define a class for HeaderWrites that use the allow-origin key, and use that type for every allowOriginHW variable. Perhaps similarly allow-credentials HeaderWrites.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh that's a lot more elegant. Love it.

Comment thread ql/src/experimental/CWE-942/CorsMisconfiguration.ql Outdated
Comment thread ql/src/experimental/CWE-942/CorsMisconfiguration.ql Outdated
@gagliardetto
Copy link
Copy Markdown
Contributor Author

Is this good to go?

@smowton smowton merged commit b03513b into github:main Jul 16, 2021
@gagliardetto
Copy link
Copy Markdown
Contributor Author

Thank you @smowton !

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants