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

Add models for the read side of golang.org/x/net/html#373

Merged
smowton merged 5 commits intogithub:mainfrom
smowton:smowton/feature/golang-x-net-html
Nov 6, 2020
Merged

Add models for the read side of golang.org/x/net/html#373
smowton merged 5 commits intogithub:mainfrom
smowton:smowton/feature/golang-x-net-html

Conversation

@smowton
Copy link
Contributor

@smowton smowton commented Oct 12, 2020

This covers cases where an HTML document is retrieved and then parts of its structure are output without proper escaping.

@smowton smowton requested a review from a team October 12, 2020 11:24
@smowton smowton force-pushed the smowton/feature/golang-x-net-html branch from 607f4b3 to f8b4734 Compare October 12, 2020 11:29
@smowton
Copy link
Contributor Author

smowton commented Oct 14, 2020

Expanded this a little to cover the Render method and to generally allow modelled functions to be seen as writing to an http.Response. Benchmarks on this so far show no new results, but will test that generalisation of Http::ResponseBody now.

@smowton smowton force-pushed the smowton/feature/golang-x-net-html branch from 8d1f35a to 014a734 Compare October 14, 2020 10:38
@smowton
Copy link
Contributor Author

smowton commented Oct 14, 2020

The generalisation finds us 23 new true positives on LGTM, mostly due to use of other fmt functions, ioutil.Copy or ioutil.TeeCopy to write to the ResponseWriter, which we didn't spot before.

The base net/html stuff still doesn't find any results, but I'm inclined to keep it as generally useful and reasonably small.

@@ -0,0 +1,2 @@
lgtm,codescanning
* Added partial support for the `golang.org/x/net/html` package, modelling tainted data flow from a retrieved HTML document to its attributes and other data.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* Added partial support for the `golang.org/x/net/html` package, modelling tainted data flow from a retrieved HTML document to its attributes and other data.
* Added partial support for the `golang.org/x/net/html` package, modeling tainted data flow from a retrieved HTML document to its attributes and other data.

As far as I know QL uses American English.

Copy link
Contributor

Choose a reason for hiding this comment

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

Same below.

@smowton smowton force-pushed the smowton/feature/golang-x-net-html branch from 014a734 to d4ab06a Compare October 19, 2020 12:11
Copy link
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.

Sorry for the slow review, I've vaguely been waiting for you to address comments but I suppose it makes more sense for you to wait for all the reviews before making changes...

@@ -0,0 +1,2 @@
lgtm,codescanning
* Added partial support for the `golang.org/x/net/html` package, modelling tainted data flow from a retrieved HTML document to its attributes and other data.
Copy link
Contributor

Choose a reason for hiding this comment

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

Same below.

/** Gets the package name `golang.org/x/net/html`. */
string packagePath() { result = "golang.org/x/net/html" }

private class EscapeString extends HtmlEscapeFunction, TaintTracking::FunctionModel {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be good to have EscapeFunction extend FunctionModel and then have its output for be exposed on it so that its specific output so that escape functions that don't return the escaped result can be modeled, but that should probably be separate from this PR.

override predicate hasTaintFlow(DataFlow::FunctionInput input, DataFlow::FunctionOutput output) {
getName() = ["Buffered", "Raw", "Text", "Token"] and input.isReceiver() and output.isResult(0)
or
getName() = "TagAttr" and input.isReceiver() and output.isResult(1)
Copy link
Contributor

Choose a reason for hiding this comment

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

Also TagName?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I skipped TagName along with attribute keys guessing that the charset restrictions on tag and attribute names would render them sanitary for most purposes

Copy link
Contributor

Choose a reason for hiding this comment

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

Fair enough. I don't see these functions being much use in taint flow anyway. Maybe add a comment, though?

@smowton smowton force-pushed the smowton/feature/golang-x-net-html branch from d4ab06a to b1bdc8a Compare October 26, 2020 11:10
@smowton
Copy link
Contributor Author

smowton commented Oct 26, 2020

Applied Sauyon's comments; will merge once passing CI

@smowton smowton force-pushed the smowton/feature/golang-x-net-html branch from b1bdc8a to d28c3bb Compare October 26, 2020 14:35
@smowton
Copy link
Contributor Author

smowton commented Oct 26, 2020

So this proved difficult -- the FunctionOutput gives me a postUpdateNode, which doesn't match up with the ResponseBody.getANode() logic. I've worked around this by adding a little utility method enabling jumping between a FunctionInput and its corresponding output and asking for the input node (i.e., the use) (note this is not the same as FunctionOutput.getEntryNode). @sauyon please re-review and let me know if you can see a better way to distangle this!

@sauyon
Copy link
Contributor

sauyon commented Oct 29, 2020

Hm, I feel like getANode should be fixed to include PostUpdateNodes that come from a variable.

@smowton
Copy link
Contributor Author

smowton commented Oct 29, 2020

I thought walking having the model take us to the post-update node, then reversing that in getANode (even though we're identifying an input here -- the response writer that was written) was messier than asking for the input to begin with. Do you feel strongly against the current solution? Shall we get a third opinion?

@sauyon
Copy link
Contributor

sauyon commented Oct 29, 2020

Well, I think that .getANode not getting PostUpdateNodes is a bug we should fix. I don't find that backtracking from the PostUpdateNode is messy, since the .getANode logic is really only there because we're modeling ResponseWriters as variables, and it's an easy way to associate a use of the ResponseWriter to the concept.

@smowton smowton force-pushed the smowton/feature/golang-x-net-html branch from d28c3bb to 2acee74 Compare November 5, 2020 15:31
@smowton
Copy link
Contributor Author

smowton commented Nov 5, 2020

@sauyon ok, I've gone for the reversing-from-post-update-node approach.

Copy link
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.

LGTM. I'll put up a PR fixing .getANode.

@sauyon
Copy link
Contributor

sauyon commented Nov 6, 2020

I hadn't realised that getANode was part of the ResponseWriter API; I've opened smowton#1 to discuss what I had in mind.

smowton and others added 5 commits November 6, 2020 11:04
This covers cases where an HTML document is retrieved and then parts of its structure are output without proper escaping.
This covers cases where an HTML document is retrieved and then parts of its structure are output without proper escaping.
This entails generalising Http::ResponseBody to account for any modelled function writing to a ResponseWriter.
@smowton smowton force-pushed the smowton/feature/golang-x-net-html branch from 2acee74 to a78c35b Compare November 6, 2020 11:19
@smowton
Copy link
Contributor Author

smowton commented Nov 6, 2020

Pushed Sauyon's changes here, will merge on green

@smowton smowton merged commit 0938437 into github:main Nov 6, 2020
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