Skip to content

Swift: Add summaries for tainted URL fields#10774

Merged
atorralba merged 5 commits intogithub:mainfrom
atorralba:atorralba/swift/url-field-summaries
Oct 18, 2022
Merged

Swift: Add summaries for tainted URL fields#10774
atorralba merged 5 commits intogithub:mainfrom
atorralba:atorralba/swift/url-field-summaries

Conversation

@atorralba
Copy link
Copy Markdown
Contributor

@atorralba atorralba commented Oct 11, 2022

If a URL is tainted, so are its fields.

@atorralba atorralba requested a review from a team as a code owner October 11, 2022 13:36
@github-actions github-actions Bot added the Swift label Oct 11, 2022
@atorralba atorralba force-pushed the atorralba/swift/url-field-summaries branch from 2eaaa78 to 8525db5 Compare October 11, 2022 15:24
geoffw0
geoffw0 previously approved these changes Oct 12, 2022
Copy link
Copy Markdown
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

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

LGTM, two very minor suggestions.

";URL;true;init(string:relativeTo:);(String,URL?);;Argument[0,1];ReturnValue.Field[standardized];taint",
";URL;true;init(string:relativeTo:);(String,URL?);;Argument[0,1];ReturnValue.Field[standardizedFileURL];taint",
";URL;true;init(string:relativeTo:);(String,URL?);;Argument[0,1];ReturnValue.Field[user];taint",
";URL;true;init(string:relativeTo:);(String,URL?);;Argument[0,1];ReturnValue.Field[password];taint",
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.

It would be good to have a couple of comments explaining what blocks of these rows do.
Something like your PR description:

If a URL is tainted, so are its fields.

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.

Good suggestion, applied in 1e48500, thanks!

sink(arg: URL(string: tainted, relativeTo: nil)!) // $ tainted=57
sink(arg: URL(string: clean, relativeTo: urlClean)!)
sink(arg: URL(string: clean, relativeTo: urlTainted)!) // $ tainted=39
sink(arg: URL(string: clean, relativeTo: urlTainted)!) // $ tainted=57
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 think we could do with at least one test for a field after init(string:relativeTo:).

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.

This actually made me think more detailedly about this constructor, and after testing it, the conclusion is:

  • if the string: argument is an absolute URL, basically it acts as the 1-argument constructor and relativeTo: is ignored (but baseURL is tainted by it).
  • if the string: argument is a relative path:
    • the path, query, and fragment related fields are tainted by it.
    • all the other fields are tainted by relativeTo:.

I adjusted the CSV rows to model this behavior as closely as possible, but of course the conditional logic is not handled. If we wanted more precise models we would need to switch to regular CodeQL instead, and apply some heuristics to the first argument to determine whether it's an absolute URL or a relative path.

What's your opinion about that?

@atorralba atorralba force-pushed the atorralba/swift/url-field-summaries branch from 0f2469a to e0346b0 Compare October 18, 2022 10:16
@atorralba
Copy link
Copy Markdown
Contributor Author

atorralba commented Oct 18, 2022

@geoffw0 I decided to handle this with TaintInheritingContent in the end: it introduces some spurious flow (marked as such in the tests), but simplifies the implementation and handles a generally tainted URL correctly (i.e. taints its fields too). In case we want more precision in the future (if we start seeing FPs because of this), I think we should apply the heuristics I mentioned in my previous comment. But the current approach should be good enough for the moment.

@atorralba atorralba force-pushed the atorralba/swift/url-field-summaries branch from e0346b0 to d7c75d5 Compare October 18, 2022 10:21
@atorralba atorralba force-pushed the atorralba/swift/url-field-summaries branch from d7c75d5 to 0eeaf71 Compare October 18, 2022 10:36
Copy link
Copy Markdown
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

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

I decided to handle this with TaintInheritingContent in the end: it introduces some spurious flow (marked as such in the tests)

This seems fine to me. I can't really imagine someone constructing a part-tainted, part-clean URL and then depending on that for correct safe behaviour afterwards.

sink(arg: urlTainted) // $ tainted=57
sink(arg: urlTainted.absoluteURL) // $ tainted=57
sink(arg: urlTainted.baseURL) // $ tainted=57
sink(arg: urlTainted.baseURL) // $ Safe
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.

Ah that's interesting, so if I'm understanding correctly URL("http://example.com/abc") and URL("abc", URL("http://example.com/")) are not two ways of constructing exactly the same thing - because the latter has a baseURL (amongst other visible differences).

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.

Correct. It seems that if the first argument is a relative path it only overrides the path, query, and fragment parts of the relativeTo URL, but then the original is saved as baseURL. With the one-argument constructor baseURL is apparently never populated.

@atorralba atorralba merged commit 1d745a6 into github:main Oct 18, 2022
@atorralba atorralba deleted the atorralba/swift/url-field-summaries branch October 18, 2022 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants