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

Current permission system and API design forces developers to create inefficient extensions #250

Closed
bershanskiy opened this issue Aug 1, 2022 · 1 comment
Labels
discussion Needs further discussion

Comments

@bershanskiy
Copy link
Member

I'm an extension developer and I want to build performant, efficient extensions which run with the least permissions possible. Unfortunately, I often feel like I have to fight the current API to make extension more efficient and require fewer permissions. Below I will provide a list of issues with API and permission system which force developers to write inefficient extensions requesting excessive permissions.

Permission system:

  • tabs permission
    • Dedicated ticket: TBD
    • Issue: extensions may have limited host permissions, but may need to react to page URL changes only on these pages so need access to Tab.url
    • Possible solution: provide url, faviconUrl and other properties automatically if extension has host permission or activeTab permission for this tab. Chrome started on this path already, but there is no documentation yet.
    • Current workaround:
      • In Chromium 102+, Navigation API provides URL observability via navigation event.
      • Content scripts can listen for events that typically result in URL update (e.g., custom events on a page or in a framework), clicks on elements with href, etc. In general, this is not reliable.
      • Content scripts can attempt to shim History API methods. This might not be reliable.
      • Background can register a listener for tabs.onUpdated event (without tabs permission), then attempt to ping the content script and catch an error generated if extension does not have access to specified tab. Problems: inefficient, since frequent events effectively prevent background from going inactive.
  • downloads permission
    • Dedicated ticket: TBD
    • Issue: extensions need to initiate their own downloads (e.g., to export extension settings) and do not need to access user's downloads, but are forced to prompt user with permission to "Manage your downloads".
    • Possible solutions: introduce a new permission, say downloads.initiate. This permission would allow initiating of new downloads with downloads.downloads and would grant access to all downloads.* methods and events, but these methods and events would work for/provide data about downloads initiated by this extension and not other things (extensions or pages).
    • Current workaround: Attach a link to some document with data: URL and click() it.
  • permissions.request always requires user activation
    • Dedicated issue: TBA
    • Issue: calling permissions.request requires user activation even if browser will not prompt the user. Extensions can have hard time downgrading their host permissions. Also, extensions have no incentive to make lots of permissions optional, including "storage", "unlimitedStorage", "alarms", "contextMenus".
    • Possible solution: when called without user activation, permissions.request first evaluates if it would need to display a prompt and if not, grant the permission, throwing error only if prompt would be required but there was no user activation.
    • Current workaround: request these permissions just in case, even if you do not plan to ever use them.

API design

Many event listeners are run too often, preventing BG from sleeping. If extensions could specify that listener filters (like they can for webRequest) or that extensions want to be notified of only pages for which they have host permissions, browser could evaluate each event against these filters and activate BG only if needed.

  • storage.onChanged
    • Dedicated ticket: TBD
    • Issue: extension might store some frequently-changing data (e.g., tab-specific data used by content scripts) and rarely changing data (e.g., extension options used by background worker), but background can not ignore the tab-specific data changes and gets activated just to check that the data change is not relevant to it.
    • Current workaround:
      • simply avoid storage.onChanged listeners and write data via storage.*.set and then separately send it to receiver via a callback or runtime.sendMessage
      • check contents of storage (e.g., storage.managed) on an infrequent timer instead of listening for change events
  • action.set*
  • tabs events: tabs.onCreated, tabs.onRemoved, etc.
    • Dedicated issue: TBA
    • Issue: Same as above, but for tabs.*
    • Possible solution: add a way for extension to opt out of events coming from pages extension does not have access to
    • Current workaround: avoid these events entirely and inject a Content Script which would listen for the required events and notify background via runtime.sendMessage
@patrickkettner
Copy link
Contributor

After discussing as a group, given the age and lack of discussion here, we decided to close this out with the request that the individual topics are opened as unique issues. That way we can discuss them more easily as a group.

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

No branches or pull requests

3 participants