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

Update HTTP.qll#95

Closed
gagliardetto wants to merge 3 commits into
github:masterfrom
gagliardetto:patch-2
Closed

Update HTTP.qll#95
gagliardetto wants to merge 3 commits into
github:masterfrom
gagliardetto:patch-2

Conversation

@gagliardetto
Copy link
Copy Markdown
Contributor

@gagliardetto gagliardetto commented Apr 13, 2020

Add more fields to UserControlledRequestField(), and more methods to UserControlledRequestMethod() on "net/http".Request.

Example server

package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("r.Host", r.Host)
		fmt.Println("r.Method", r.Method)
		fmt.Println("r.RequestURI", r.RequestURI)

		fmt.Println("r.BasicAuth()")
		user, password, _ := r.BasicAuth()
		fmt.Println(fmt.Sprintf("username %q, password %q", user, password))

		fmt.Println("---")
	})
	fmt.Println("running server on :8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

Example request

printf "H&&\$ /\$(echo\u00A0hello\u00A0world) HTTP/1.0\r\nHost: lite\$(echo;hello;world)).whatever.com\r\nAuthorization: Basic JChlY2hvIGhlbGxvIHdvcmxkKTokKGVjaG8gd29ybGQpCg==\r\n\r\n" | nc 127.0.0.1 8080

Server log of this request:

r.Host lite$(echo;hello;world)).whatever.com
r.Method H&&$
r.RequestURI /$(echo hello world)
r.BasicAuth()
username "$(echo hello world)", password "$(echo world)\n"
---

Add more fields to `UserControlledRequestField()`, and more methods to `UserControlledRequestMethod()` on `"net/http".Request`.
@max-schaefer max-schaefer requested a review from sauyon April 14, 2020 07:58
@max-schaefer
Copy link
Copy Markdown
Contributor

@sauyon, could you take a look at this? You've most recently been working in these parts.

@gagliardetto
Copy link
Copy Markdown
Contributor Author

I'm going to add all Golang web frameworks, one at a time; best starting point is net/http

Comment thread ql/src/semmle/go/frameworks/HTTP.qll
Comment thread ql/src/semmle/go/frameworks/HTTP.qll Outdated
fieldName = "URL"
fieldName = "URL" or
fieldName = "Host" or
fieldName = "Method" or
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.

While this one is technically under the attacker's control, it'll have to be a valid HTTP verb, so not too interesting from a taint-tracking perspective.

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.

HTTP verb validation is kind of out of net/http package scope; the verb will be validated only if the developer will add the validation (third party code).

Catch-all endpoints are not uncommon.

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.

(again, see example)

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.

When you say "see example", what are you referring to?

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.

I'm referring to my first comment in this PR.

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.

Oh, you mean the PR description. Could you turn that into a test, please?

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.

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.

Or you had another kind of test in mind?

Copy link
Copy Markdown
Contributor

@sauyon sauyon left a comment

Choose a reason for hiding this comment

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

Hey! Sorry about the delay, I've been running some tests because I'm somewhat worried about this causing false positives: while catch-all endpoints may be relatively common, we have no way of knowing whether the source is actually from a catch-all endpoint or not with the way the library is structured. That said, perhaps the pattern of using the host or request path in some sensitive way is rare enough that this is a non-issue.

Specifically for our open redirect query, though, an evaluation (internal link) shows a false positive on uber/cockroach, which represents a class of false positives I would like for you to fix; here's the result on LGTM (it's the one in pprofui/server.go).

That should just be a matter of modifying the UntrustedFlowAsSource class in (ql/src/semmle/go/https://github.com/github/codeql-go/blob/master/ql/src/semmle/go/security/OpenUrlRedirectCustomizations.qll)[https://github.com/github/codeql-go/blob/master/ql/src/semmle/go/security/OpenUrlRedirectCustomizations.qll].

methName = "Referer" or
methName = "UserAgent"
methName = "UserAgent" or
methName = "BasicAuth"
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.

Suggested change
methName = "BasicAuth"
methName = "BasicAuth"

@sauyon
Copy link
Copy Markdown
Contributor

sauyon commented Apr 15, 2020

Re: tests, copying your example server into the tests directory should work (you might have to tweak the name of the main function to get it to build).

Also, I'd like to see a test for the open URL redirect query as well.

@gagliardetto
Copy link
Copy Markdown
Contributor Author

Sorry for the delay!

while catch-all endpoints may be relatively common, we have no way of knowing whether the source is actually from a catch-all endpoint or not with the way the library is structured

You are right. While not creating much noise for flows to sinks such as command execution, Method can create much noise in other cases.

It's probably better to leave it out.

which represents a class of false positives I would like for you to fix

Do you mean adding RequestURI to the ignored fields list in

not exists(Field f, string fieldName |
f.hasQualifiedName("net/http", "Request", fieldName) and
this = f.getARead()
|
fieldName = "Body" or
fieldName = "GetBody" or
fieldName = "PostForm" or
fieldName = "MultipartForm" or
fieldName = "Header" or
fieldName = "Trailer"
?

I'd like to see a test for the open URL redirect query as well.

You mean adding field read examples here https://github.com/github/codeql-go/blob/master/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.go ?

Copy link
Copy Markdown

@ghost ghost left a comment

Choose a reason for hiding this comment

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

I think the Method,URI and Host fields should not be included by default. See my comment below.

Comment thread ql/src/semmle/go/frameworks/HTTP.qll
@@ -0,0 +1,22 @@
package main
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The fields here can be merged with main.go There's no need really to write the same boilerplate code here again.

@sauyon
Copy link
Copy Markdown
Contributor

sauyon commented Apr 29, 2020

Do you mean adding RequestURI to the ignored fields list in

not exists(Field f, string fieldName |
f.hasQualifiedName("net/http", "Request", fieldName) and
this = f.getARead()
|
fieldName = "Body" or
fieldName = "GetBody" or
fieldName = "PostForm" or
fieldName = "MultipartForm" or
fieldName = "Header" or
fieldName = "Trailer"

?

Yep 👍

I'd like to see a test for the open URL redirect query as well.

You mean adding field read examples here https://github.com/github/codeql-go/blob/master/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.go ?

Would like it here, specifically for the fields that you add to the above.

@gagliardetto gagliardetto marked this pull request as draft May 9, 2020 06:04
@max-schaefer
Copy link
Copy Markdown
Contributor

@gagliardetto, are you still working on this?

@gagliardetto
Copy link
Copy Markdown
Contributor Author

I'll reopen this in the future.

@max-schaefer
Copy link
Copy Markdown
Contributor

Sounds good.

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.

4 participants