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

Update adblock-rust with CSP rule support #8281

Merged
merged 4 commits into from
Apr 14, 2021
Merged

Conversation

antonok-edm
Copy link
Collaborator

@antonok-edm antonok-edm commented Mar 18, 2021

Resolves brave/brave-browser#14792

Security/privacy review at https://github.com/brave/security/issues/374

Submitter Checklist:

  • I confirm that no security/privacy review is needed, or that I have requested one
  • There is a ticket for my issue
  • Used Github auto-closing keywords in the PR description above
  • Wrote a good PR/commit description
  • Added appropriate labels (QA/Yes or QA/No; release-notes/include or release-notes/exclude; OS/...) to the associated issue
  • Checked the PR locally: npm run test -- brave_browser_tests, npm run test -- brave_unit_tests, npm run lint, npm run gn_check, npm run tslint
  • Ran git rebase master (if needed)

Reviewer Checklist:

  • A security review is not needed, or a link to one is included in the PR description
  • New files have MPL-2.0 license header
  • Adequate test coverage exists to prevent regressions
  • Major classes, functions and non-trivial code blocks are well-commented
  • Changes in component dependencies are properly reflected in gn
  • Code follows the style guide
  • Test plan is specified in PR before merging

After-merge Checklist:

Test Plan:

Visit http://pirateiro.com/. Refresh the page while the developer console is open, and check in the console to verify that the browser refused to load scripts violating the policy script-src 'self' 'unsafe-inline' https://hcaptcha.com *.hcaptcha.com.

On Android, it will be sufficient to observe 0 blocked items in the Shields panel rather than 5 (the requests are still blocked, but will not increment the counter).

@antonok-edm antonok-edm self-assigned this Mar 18, 2021
@antonok-edm antonok-edm force-pushed the csp-filter-rules branch 4 times, most recently from 1e99555 to 814ec95 Compare March 18, 2021 02:28
@antonok-edm
Copy link
Collaborator Author

There are currently some lint errors due to brave/brave-browser#14803.

I will get that sorted out first and rebase before merging, but this is ready for review otherwise.

@antonok-edm antonok-edm force-pushed the csp-filter-rules branch 2 times, most recently from 12dec05 to e475c29 Compare March 23, 2021 03:45
@antonok-edm antonok-edm force-pushed the csp-filter-rules branch 2 times, most recently from 30dc53d to 86154a9 Compare April 8, 2021 19:11
Comment on lines 310 to 316
// If the override_response_headers have already been populated, we should
// use those directly. Otherwise, we populate them from the original
// headers.
if (!*override_response_headers) {
*override_response_headers =
new net::HttpResponseHeaders(response_headers->raw_headers());
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@iefremov it was confusing to me at first that override_response_headers is not reset in between OnHeadersReceived callbacks. The other callbacks are written to override the headers directly from the original response headers, which is okay when they're the first/only callback but problematic for any further callbacks.

Based on how this is all set up, I would have expected BraveRequestHandler to update response_headers with any non-null override_response_headers in between each callback. Just wanted to point this out in case it's unintentional or needs further work.

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah this probably can be improved

@@ -16,6 +16,13 @@ int OnBeforeURLRequest_AdBlockTPPreWork(
const ResponseCallback& next_callback,
std::shared_ptr<BraveRequestInfo> ctx);

int OnHeadersReceived_AdBlockCspWork(
Copy link
Contributor

Choose a reason for hiding this comment

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

can we please move this to a separate file and also wrap with a base::Feature flag

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

FWIW I was modeling this off of ipfs_redirect_network_delegate_helper.h which has both the OnBeforeURLRequest and OnHeadersReceived callbacks in the same file.

@@ -21,6 +22,7 @@
#include "brave/common/pref_names.h"
#include "brave/components/brave_referrals/buildflags/buildflags.h"
#include "brave/components/brave_rewards/browser/buildflags/buildflags.h"
#include "brave/components/brave_shields/common/features.h"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Needs a dep in browser/net/BUILD.gn?

Copy link
Collaborator

@mkarolin mkarolin left a comment

Choose a reason for hiding this comment

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

chromium_src changes LGTM

@@ -25,6 +25,9 @@ std::vector<adblock::FilterList>::const_iterator FindAdBlockFilterListByLocale(
std::vector<adblock::FilterList> RegionalCatalogFromJSON(
const std::string& catalog_json);

void MergeCspDirectiveInto(base::Optional<std::string> from,
Copy link
Contributor

Choose a reason for hiding this comment

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

personally I don't see much sense in using Optional here and in the service (also CC recommends against it https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md#when-not-to-use).
IMO just (potentially, empty) strings would be more readable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think I disagree here. CSP is a security-sensitive topic, and it's important to make sure these directives are handled with appropriate care. Having the Optional enforces a stronger contract than just passing strings around, with a distinct semantic difference between "there is a directive here" and "no directive". I think it'd be tempting to bypass the merge function here altogether if working directly with strings; we have already run into some issues with incorrectly concatenated CSP directives in the past (e.g. brave/brave-browser#14752).

// a URL or origin and not a string to a host name.
bool is_third_party = !SameDomainOrHost(
url,
url::Origin::CreateFromNormalizedTuple("https", tab_host.c_str(), 80),
Copy link
Contributor

@iefremov iefremov Apr 13, 2021

Choose a reason for hiding this comment

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

  1. you should std::move(tab_host), as described in the CreateFromNormalizedTuple description

  2. why not pass the full URL or Origin there from the very beginning?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm just using the same implementation as ShouldStartRequest directly above; would be good to keep the same behavior between the two since I use both the same way in adblock-rust. I think it's worth addressing in a followup.

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, ok - could you file a follow-up to change tab_host from string to GURL in ShouldStartRequest ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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


(*override_response_headers)->RemoveHeader("Content-Security-Policy");

task_runner->PostTaskAndReplyWithResult(
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't really like the idea of adding new thread hops, but we probably can leave it for now until bigger refactoring. I think at some point we should allow querying certain things (e.g. csp rules) from the service on UI thread to avoid jumping between threads, since the jump adds more delay than the lookup

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for $csp filter rules
3 participants