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

Remove Greaselion dependency from Rewards service (v2) #25949

Merged
merged 1 commit into from
Oct 25, 2024

Conversation

zenparsing
Copy link
Collaborator

@zenparsing zenparsing commented Oct 11, 2024

Resolves brave/brave-browser#34237

Overview

Currently, Brave Creator "pages" are detected on some social media sites (on desktop) by using a combination of the persistent Brave extension and Greaselion extension content scripts. For performance reasons, we must migrate away from using a persistent background page, and for maintainability reasons (and to allow the feature to work cross-platform in the future) we must migrate away from Greaselion.

With this change, the Rewards service no longer uses Greaselion. Instead, scripts are injected by the RewardsTabHelper into the "Brave internal" isolated world (using a new CreatorDetectionScriptInjector class). The scripts are individually compiled and bundled for each site from TypeScript using our current TypeScript bundling process. They are executed in the "Brave internal" isolated world. In the future, the scripts can be moved out of brave-core and delivered via ComponentUpdater.

Submitter Checklist:

  • I confirm that no security/privacy review is needed and no other type of reviews are needed, or that I have requested them
  • There is a ticket for my issue
  • Used Github auto-closing keywords in the PR description above
  • Wrote a good PR/commit description
  • Squashed any review feedback or "fixup" commits before merge, so that history is a record of what happened in the repo, not your PR
  • 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 wiki
    • npm run presubmit wiki, 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:

@zenparsing zenparsing requested review from a team as code owners October 11, 2024 13:56
@github-actions github-actions bot added CI/storybook-url Deploy storybook and provide a unique URL for each build CI/run-upstream-tests Run upstream unit and browser tests on Linux and Windows (otherwise only on Linux) labels Oct 11, 2024
@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

@zenparsing zenparsing force-pushed the ksmith-gl-dodo-2 branch 2 times, most recently from fb5cc24 to a3c13cd Compare October 11, 2024 17:32
@zenparsing zenparsing force-pushed the ksmith-gl-dodo-2 branch 2 times, most recently from 805281a to 442ee26 Compare October 16, 2024 14:58
visit->provider = *platform;
}

rewards_service_->GetPublisherActivityFromUrl(visit->Clone());
Copy link
Collaborator

@bridiver bridiver Oct 17, 2024

Choose a reason for hiding this comment

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

this should really be encapsulated in something like RewardsService::UpdateCreatorForTab. I have no idea what is going on in these three calls and this also makes it hard to test vs unit testing a single method on RewardsService. We really shouldn't be exposing these kinds of low level calls in the service.

Copy link
Collaborator

Choose a reason for hiding this comment

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

side note: why is this called GetPublisherActivityFromUrl if it doesn't actually return anything? Also it doesn't take a URL as a param which is confusing. Separately from this PR this method name should probably change.

Copy link
Collaborator

Choose a reason for hiding this comment

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

oh, I guess an overloaded version of GetPublisherActivityFromUrl was added in this PR so the name should at least change to GetPublisherActivityFromVisitData and then change GetPublisherActivityFrom for both in a separate PR

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes - these methods are pretty ancient and the names reflect that. I've updated the new method name as suggested, and I'll add an issue to fix the names up more generally.

Copy link
Collaborator

Choose a reason for hiding this comment

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

what about my comment about wrapping these three method calls in a single call to the service? If multiple actions need to be taken in response to something it's best for the service to handle that, not the caller. Although this is not a user action, it should still follow the same principle of having a single call to the service for a given event that occurs outside the component

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not suggesting refactoring the entire class, but we can certainly simplify this specific case, no? Just because other code is problematic doesn't mean we should keep doing the same thing when we could at least wrap these calls. It's only adding a couple of methods to RewardsService to move the details inside of it

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Filed a follow-up issue here: brave/brave-browser#41832 to address the RewardsService AC-related API issues. It will be more clear what the API should be after the upcoming AC changes have been finalized.

Copy link
Collaborator

Choose a reason for hiding this comment

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

fyi I made a similar comment in this PR to make things more unit testable https://github.com/brave/brave-core/pull/26082/files#r1813441440

Copy link
Collaborator

Choose a reason for hiding this comment

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

unit testing tab helpers is not very practical, but unit testing the service is

Copy link
Collaborator

Choose a reason for hiding this comment

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

I won't block on this as long as we have good test coverage for everything that gets called here, but given that this is new code being added I'm struggling with why we can't just add a new method to the service to wrap these three calls so we can unit test it.

@zenparsing zenparsing force-pushed the ksmith-gl-dodo-2 branch 2 times, most recently from f019ae7 to 445543d Compare October 24, 2024 12:56
creator_detection_.DetectCreator(
navigation_handle->GetRenderFrameHost(),
base::BindOnce(&RewardsTabHelper::OnCreatorDetected,
base::Unretained(this), detection_navigation_id_));
Copy link
Contributor

Choose a reason for hiding this comment

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

reported by reviewdog 🐶
[semgrep] base::Unretained is most of the time unrequited, and a weak reference is better suited for secure coding.
Consider swapping Unretained for a weak reference.
base::Unretained usage may be acceptable when a callback owner is guaranteed
to be destroyed with the object base::Unretained is pointing to, for example:

- PrefChangeRegistrar
- base::*Timer
- mojo::Receiver
- any other class member destroyed when the class is deallocated


Source: https://github.com/brave/security-action/blob/main/assets/semgrep_rules/client/chromium-uaf.yaml


Cc @thypon @goodov @iefremov

injector_->RequestAsyncExecuteScript(
ISOLATED_WORLD_ID_BRAVE_INTERNAL, base::UTF8ToUTF16(script),
blink::mojom::UserActivationOption::kDoNotActivate,
blink::mojom::PromiseResultOption::kAwait, std::move(callback));
Copy link
Contributor

Choose a reason for hiding this comment

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

reported by reviewdog 🐶
[semgrep] RequestAsyncExecuteScript usages should be vet by the security-team.

References:
- https://github.com/brave/brave-browser/wiki/Security-reviews (point 13)


Source: https://github.com/brave/security-action/blob/main/assets/semgrep_rules/client/brave-execute-script.yaml


Cc @thypon @diracdeltas @bridiver

}

export function urlPath(url: string) {
try { return new URL(url, location.href).pathname }
Copy link
Contributor

Choose a reason for hiding this comment

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

reported by reviewdog 🐶
[semgrep] Are you using the URL(url, base) constructor as a security control to limit the origin with base location.href? The base is ignored whenever url looks like an absolute URL, e.g. when it begins protocol://. \\\\ or //x.y. Verify that the URL's origin is as expected rather than relying on the URL constructor.

Source: https://github.com/brave/security-action/blob/main/assets/semgrep_rules/services/url-constructor-base.yaml


Cc @thypon @kdenhartog

}

export function absoluteURL(url: string) {
try { return new URL(url, location.href).toString() }
Copy link
Contributor

Choose a reason for hiding this comment

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

reported by reviewdog 🐶
[semgrep] Are you using the URL(url, base) constructor as a security control to limit the origin with base location.href? The base is ignored whenever url looks like an absolute URL, e.g. when it begins protocol://. \\\\ or //x.y. Verify that the URL's origin is as expected rather than relying on the URL constructor.

Source: https://github.com/brave/security-action/blob/main/assets/semgrep_rules/services/url-constructor-base.yaml


Cc @thypon @kdenhartog

ExecuteScriptCallback callback) {
CHECK(injector_.is_bound());
injector_->RequestAsyncExecuteScript(
ISOLATED_WORLD_ID_BRAVE_INTERNAL, base::UTF8ToUTF16(script),
Copy link
Contributor

Choose a reason for hiding this comment

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

reported by reviewdog 🐶
[semgrep] Security hotspot found (ISOLATED_WORLD). A security-team member should analyze the code security for possible vulnerabilities.

Source: https://github.com/brave/security-action/blob/main/assets/semgrep_rules/client/brave-isolated-world.yaml


Cc @thypon @diracdeltas @bridiver

Copy link
Contributor

[puLL-Merge] - brave/brave-core@25949

Description

This pull request introduces a new feature for detecting Brave Creators on media platform sites. It removes the existing Greaselion-based implementation and replaces it with a new, more efficient system that uses JavaScript injection to detect creators directly on supported platforms.

Changes

Changes

  1. browser/about_flags.cc:

    • Added a new feature flag for the platform creator detection feature.
  2. browser/brave_rewards/BUILD.gn:

    • Updated dependencies and added new source files for the creator detection feature.
  3. browser/brave_rewards/creator_detection_script_injector.cc and creator_detection_script_injector.h:

    • Introduced new files for injecting and managing creator detection scripts.
  4. browser/brave_rewards/rewards_service_factory.cc:

    • Removed Greaselion-related dependencies and initialization.
  5. browser/brave_rewards/rewards_tab_helper.cc and rewards_tab_helper.h:

    • Updated to use the new creator detection system instead of Greaselion.
  6. browser/extensions/api/brave_rewards_api.cc and brave_rewards_api.h:

    • Removed several deprecated API methods related to the old publisher detection system.
  7. browser/extensions/brave_component_loader.cc:

    • Removed Brave Rewards-related preference change handling.
  8. browser/greaselion/:

    • Removed Greaselion-related files and tests.
  9. common/extensions/api/brave_rewards.json:

    • Removed deprecated API methods related to the old publisher detection system.
  10. components/brave_extension/extension/brave_extension/background/greaselion.ts:

    • Removed this file as it's no longer needed.
  11. components/brave_rewards/:

    • Moved publisher utility functions from browser/ to common/.
    • Added new creator detection scripts for various platforms (GitHub, Reddit, Twitch, Twitter, Vimeo, YouTube).
    • Updated various files to use the new creator detection system.
  12. test/BUILD.gn:

    • Removed Greaselion-related test dependencies.

Possible Issues

  1. The removal of Greaselion might affect other parts of the system that were relying on it. Thorough testing across different scenarios is recommended.
  2. The new creator detection scripts may need fine-tuning for edge cases on each platform.

Security Hotspots

  1. browser/brave_rewards/creator_detection_script_injector.cc:
    • The script injection mechanism should be carefully reviewed to ensure it doesn't introduce any security vulnerabilities.
  2. components/brave_rewards/resources/creator_detection/:
    • The platform-specific detection scripts should be audited to ensure they don't expose sensitive information or introduce potential XSS vulnerabilities.

@zenparsing zenparsing merged commit dc4430d into master Oct 25, 2024
17 checks passed
@zenparsing zenparsing deleted the ksmith-gl-dodo-2 branch October 25, 2024 18:14
@github-actions github-actions bot added this to the 1.73.x - Nightly milestone Oct 25, 2024
@brave-builds
Copy link
Collaborator

Released in v1.73.50

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI/run-upstream-tests Run upstream unit and browser tests on Linux and Windows (otherwise only on Linux) CI/storybook-url Deploy storybook and provide a unique URL for each build needs-security-review puLL-Merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Migrate Rewards Publisher ID / Creator detection content scripts out of Greaselion
10 participants