Sitelet https://web.archive.org/web/20210622235229/https://github.com/github/codeql-go/pull/529
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CWE-1004: Sensitive cookie without HttpOnly #529

Merged
merged 27 commits into from Jun 17, 2021
Merged

CWE-1004: Sensitive cookie without HttpOnly #529

merged 27 commits into from Jun 17, 2021

Conversation

@edvraa
Copy link
Contributor

@edvraa edvraa commented Apr 25, 2021

No description provided.

@edvraa edvraa requested a review from github/codeql-go as a code owner Apr 25, 2021
@smowton
Copy link
Contributor

@smowton smowton commented Apr 26, 2021

Does / will this have a corresponding bounty application?

@edvraa
Copy link
Contributor Author

@edvraa edvraa commented Apr 26, 2021

Does / will this have a corresponding bounty application?

Yes, was planning if it is merged. Are there any differences? Does bounty application speeds up review?

@smowton
Copy link
Contributor

@smowton smowton commented Apr 26, 2021

No particular speed difference but it affects who does the work. In this case you should apply before merging, and you'll get accuracy comments from the security lab team.

@edvraa
Copy link
Contributor Author

@edvraa edvraa commented Apr 26, 2021

Sorry, didn't know that. Just created it.

@owen-mc owen-mc self-assigned this Apr 26, 2021
ql/src/experimental/CWE-1004/AuthCookie.qll Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/AuthCookie.qll Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/AuthCookie.qll Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/AuthCookie.qll Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/AuthCookie.qll Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/CookieWithoutHttpOnly.ql Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/CookieWithoutHttpOnly.ql Outdated Show resolved Hide resolved
HttpOnlyCookieTrackingConfiguration httpOnlyCfg, AuthCookieNameConfiguration cookieNameCfg,
SetCookieSink sink, DataFlow::Node source
|
httpOnlyCfg.hasFlow(source, sink) and
cookieNameCfg.hasFlow(source, sink) and
Comment on lines 20 to 24

This comment has been minimized.

@owen-mc

owen-mc Apr 28, 2021
Contributor

I don't think you really want to use two taint tracking configurations here. You are only really interested in one path. You should combine them, and make the source be the conjunction of the two current source predicates. It might be clearest if you make the two current source predicates into their own separate predicates.

ql/src/experimental/CWE-1004/CookieWithoutHttpOnly.ql Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/CookieWithoutHttpOnly.ql Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/CookieWithoutHttpOnly.ql Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/CookieWithoutHttpOnly.ql Outdated Show resolved Hide resolved
@edvraa
Copy link
Contributor Author

@edvraa edvraa commented Apr 30, 2021

Path tracking ended up as a big change, but let's think big - global flow tracking :) There is one odd thing though. A query like:

from BoolToGorillaSessionOptionsTrackingConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Cookie attribute 'HttpOnly' is not set to true."

gives me odd path:
image
image
The sink and the source are good, but the intermediate path is funny. Do I do something wrong?

@owen-mc
Copy link
Contributor

@owen-mc owen-mc commented Apr 30, 2021

No, you didn't do anything wrong. The first path is fine, though some steps are skipped that you might expect to see. The extra paths are a quirk of how to we track data flow. I think this was explained here.

@edvraa edvraa requested a review from owen-mc May 11, 2021
Copy link
Contributor

@owen-mc owen-mc left a comment

Great - it's so much easier to read with the comments! I understand a lot better what's going on now. I only had time to do a partial review. Most of my comments are about slightly better ways of doing things, e.g. using data flow nodes instead of exprs, but they will make things a lot more readable.

ql/src/experimental/CWE-1004/AuthCookie.qll Outdated Show resolved Hide resolved
exists(NameToNetHttpCookieTrackingConfiguration cfg, DataFlow::Node nameArg |
cfg.hasFlow(_, nameArg) and
sink.asExpr() = nameArg.asExpr()
)
Comment on lines 66 to 69

This comment has been minimized.

@owen-mc

owen-mc May 11, 2021
Contributor

I think this logic should move into the definition of SetCookieSink. You only really care about calls to SetCookie which have a sensitive name. This will restrict the number of sinks for two configurations, and for performance reasons it's always good to restrict the number of sources and sinks for configurations.

This comment has been minimized.

@owen-mc

owen-mc May 14, 2021
Contributor

I still think this would be an improvement - make it part of the definition of SetCookieSink that a sensitive name flows to it (and maybe change its name to reflect that). This would improve performance and wouldn't change the results at all.

ql/src/experimental/CWE-1004/CookieWithoutHttpOnly.ql Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/CookieWithoutHttpOnly.ql Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/AuthCookie.qll Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/AuthCookie.qll Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/AuthCookie.qll Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/CookieWithoutHttpOnly.ql Outdated Show resolved Hide resolved
@owen-mc
Copy link
Contributor

@owen-mc owen-mc commented May 11, 2021

Oh, and I forgot to mention that you need to regenerate the .expected file because you reformatted the .go file and that change the line numbers. (This isn't a problem for tests that use InlineExpectations, as you put comments in the code to indicate where results are expected, so they move with the reformatting.)

@edvraa edvraa requested a review from owen-mc May 13, 2021
Copy link
Contributor

@owen-mc owen-mc left a comment

Looking good. A few more comments.

Also, I should say that this advice about staying at the level of DataFlow::Nodes is specific to the CodeQL libraries for Go. If you write a query for another language then it will be different.

ql/src/experimental/CWE-1004/AuthCookie.qll Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/AuthCookie.qll Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/AuthCookie.qll Outdated Show resolved Hide resolved
ql/src/experimental/CWE-1004/CookieWithoutHttpOnly.ql Outdated Show resolved Hide resolved
@owen-mc
Copy link
Contributor

@owen-mc owen-mc commented May 14, 2021

Oh, and my unresolved comment about changing the definition of SetCookieSink from the previous review still applies.

@edvraa
Copy link
Contributor Author

@edvraa edvraa commented May 24, 2021

Oh, and my unresolved comment about changing the definition of SetCookieSink from the previous review still applies.

Do you mean this one?
I tried something like that:

private class SetCookieSink extends DataFlow::Node {
  SetCookieSink() {
    exists(DataFlow::CallNode cn |
      cn.getTarget().hasQualifiedName(package("net/http", ""), "SetCookie") and
      this = cn.getArgument(1) and
      exists(NameToNetHttpCookieTrackingConfiguration cfg, DataFlow::Node source |
        cfg.hasFlow(source, this)
      )
    )
  }
}

class NameToNetHttpCookieTrackingConfiguration extends TaintTracking2::Configuration {
  NameToNetHttpCookieTrackingConfiguration() { this = "NameToNetHttpCookieTrackingConfiguration" }

  override predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) }

  override predicate isSink(DataFlow::Node sink) { sink instanceof DataFlow::Node }

  override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
    exists(StructLit sl |
      sl.getType() instanceof NetHttpCookieType and
      getValueForFieldWrite(sl, "Name") = pred and
      sl = succ.asExpr()
    )
  }
}

The sink predicate becomes odd, otherwise it is non monotonic recursion...
This gives PathNode is not compatible with PathNode. If I change TaintTracking2 to TaintTracking it is again non monotonic.
I use NameToNetHttpCookieTrackingConfiguration separately in isNetHttpCookieFlow to the path from sensitive name to sink in case no boolean is assigned.

Copy link
Contributor

@owen-mc owen-mc left a comment

Hmm, it seems that comment doesn't make sense any more. Oh well.

@owen-mc owen-mc dismissed their stale review Jun 8, 2021

Changes have been applied

@owen-mc owen-mc merged commit ac777d2 into github:main Jun 17, 2021
5 checks passed
5 checks passed
@github-actions
Test Linux (Ubuntu)
Details
@github-actions
Test MacOS
Details
@github-actions
Test Windows
Details
@lgtm-com
LGTM analysis: JavaScript No code changes detected
Details
@lgtm-com
LGTM analysis: Go No new or fixed alerts
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

3 participants