Chrome Extension View Optional Permission Warnings Locally - google-chrome-extension

I want to add optional permissions to my extension and would like to test the warning messages (locally) prior to publishing.
I followed this article, and created the packed .crx file.
However when I upload it (via drag and drop), I get:
This extension is not listed in the Chrome Web Store and may have been added without your knowledge. Learn More
...but, my extension IS listed in the Chrome Webstore.
Am I missing something, or did Chrome permanently disable .crx uploads?
Seems like there is no solution to this online.
Is it possible that my "updated" manifest is causing this issue as it is now using v3 whereas the published extension is v2?

As a workaround, you can use chrome.management.getPermissionWarningsByManifest.
It can be ran from any extension (without the "management" permission, and not necessarily the extension you're testing for warnings) and takes a valid extension manifest file as a string, returning an array of warnings in callback.
An example using the manifest of the extension as linked in your question:
const m = `
{
"update_url": "https://clients2.google.com/service/update2/crx",
"manifest_version": 2,
"version": "2.0.0",
(..skipped..)
"permissions": [
"tabs",
"contextMenus",
"storage",
"alarms",
"downloads",
"downloads.shelf"
],
(..skipped..)
}`;
chrome.management.getPermissionWarningsByManifest(
m,
warnings => { for (let warning of warnings) console.log(warning); }
);
// Prints:
// Read your browsing history
// Manage your downloads

Related

how can i get the local file in chrome extension v3 [duplicate]

I have a Chrome extension that can (if you allow access to file URLs) grab your local pdf file that you have open in chrome and send it on to our API for processing. This is done by fetching the pdf with XMLHttpRequest to file:///Users/user/whatever/testfile.pdf from the background script.
When migrating to manifest v3 for a Chrome extension the background script becomes a service worker. In a service worker only fetch is available, not XMLHttpRequest. Problem is, fetch only supports http and https, not file:// urls. So how can I make the same feature of having the Chrome extension fetching/getting the local file?
EDIT: Things I also tried:
Making the XMLHttpRequest from injected iframe as suggested by answer.
This gives error net:ERR_UNKNOWN_URL_SCHEME when making the request
Making the XMLHttpRequest from injected content script.
This gives error Access to XMLHttpRequest at 'file:///.../testfile1.docx.pdf' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.
From what I can understand from a lot of research access to file:// is in general blocked and Chrome extension background scripts used to be an exception to this. Seems to me it was never allowed from content scripts or action popups.
My manifest.json for reference:
{
"manifest_version": 3,
"name": "..",
"version": "0.1",
"icons": {
"16": "assets/icon-16x16.png",
"48": "assets/icon-48x48.png",
"128": "assets/icon-128x128.png"
},
"action": {
"default_title": ".."
},
"background": {
"service_worker": "background.js"
},
"permissions": [
"webRequest",
"activeTab",
"scripting",
"storage",
"unlimitedStorage",
"identity",
"pageCapture"
],
"host_permissions": [
"<all_urls>"
],
"web_accessible_resources": [{
"resources": ["iframe.html"],
"matches": [],
"extension_ids": []
}]
}
The content script is injected programmatically (using webextension-polyfill for promise support)
browser.action.onClicked.addListener(async (tab: Tab) => {
await browser.scripting.executeScript({files: [ "inject.js" ], target: {tabId: tab.id}});
});
Chrome 98 and older can't do it in the background service worker for the reasons you mentioned.
There was also a bug that prevented doing it in a normal visible chrome-extension:// page or iframe. It's fixed in Chrome 91.
Solution
Use fetch in Chrome 99 and newer.
In older versions use the following workarounds.
Workaround 1: File System API, Chrome 86+
A ManifestV3 extension can use the new File System API to read the contents of the file, for example inside the iframe exposed via web_accessible_resources.
Workaround 2. Extension frame, Chrome 91+
Use a content script that runs in the tab with that pdf:
matches in manifest.json should contain <all_urls> or file://*/* and file access should be enabled by the user in
chrome://extensions UI for your extension. Alternatively you can use
activeTab permission and programmatic injection when the user
clicks your extension's icon or invokes it through the context menu.
The content script adds an invisible iframe that points to iframe.html file exposed in web_accessible_resources
The iframe.html loads iframe.js which uses XMLHttpRequest as usual. Since the iframe has chrome-extension:// URL its environment
is the same as your old background script so you can do everything
you did before right there.
Workaround 3. Extension window/tab, Chrome 91+
An alternative solution is to use any other visible page of your
extension like the action popup or options page or any other
chrome-extension:// page belonging to your extension as they can
access the file:// URL via XMLHttpRequest same as before.
Notes
File access should be enabled in chrome://extensions page for this extension.

Chrome Extension failing to upload in Chrome Web Store developer dashboard

Long time listener, first time caller...
I apologize if this has been answered, but I haven't been able to find it.
I'm having a grand ole' time trying to work with Chrome's developer dashboard. The lovely error messages are so vague that they give me just about no insight at all into the cause of the problem.
I just updated my extension 2 days ago - yes, I had a frustrating time of it, but it worked eventually. Well I overlooked a bug, which I quickly fixed, and now I'm trying to upload the new file. I followed the same procedure that worked before, which I found here: http://www.adambarth.com/experimental/crx/docs/packaging.html under "Uploading a previously packaged extension to the Chrome Web Store"
So my process is to: Pack the new extension files(including the manifest.json), add the .crx file to a folder, add the "key.pem" file to that same folder, compress said folder, and upload to the Chrome dashboard.
I'm aware that this process puts the manifest.json file in the packed .crx file and not in the root of the zipped folder that I'm trying to upload. Again, the above process worked before, and I've been trying in vain to repeat it today with no success.
The ONLY change made to my manifest file is the increment of the "version" number, as required.
I'm repeatedly getting the following:
An error occurred: Failed to process your item.
No manifest found in package. Please make sure to put manifest.json at
the root directory of the zip package.
My manifest.json, for whom it may concern...
{
"name": "AppName",
"version": "0.0.4",
"description": "App description - information was changed for stackoverflow post",
"manifest_version": 2,
"browser_action": {
"default_icon": {
"48": "img/pictureFile.png"
}
},
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [{
"matches": ["*://linksRemovedForBrevity*"],
"js": ["content.js", "other-content.js"]
}],
"permissions": [
"activeTab",
"storage",
"tabs"
],
"web_accessible_resources": [
"styles.css",
"img/icon48.png"
]
}
I should mention that I'm a noob and don't know much of what I'm doing. Any and all help is greatly appreciated.
Cheers!
#wOxxOm got it. The extension doesn't need to be packed to be zipped and uploaded.

Why the extension with specific key declared can access chrome:// pages?

As we know, by default chrome extensions doesn't have access to chrome:// pages such as chrome://extensions and chrome://settings. ( Of course we can change chrome://flags/#extensions-on-chrome-urls flags however the following question is based on that we didn't change the default flags).
Recently I happen to find ChromeVox (offered by chrome.google.com) can work well in all pages including chrome:// pages. I checked the source code for this extension and find as long as we add the following line in manifest.json for any extension, the extension can work well in chrome:// pages.
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEGBi/oD7Yl/Y16w3+gee/95/EUpRZ2U6c+8orV5ei+3CRsBsoXI/DPGBauZ3rWQ47aQnfoG00sXigFdJA2NhNK9OgmRA2evnsRRbjYm2BG1twpaLsgQPPus3PyczbDCvhFu8k24wzFyEtxLrfxAGBseBPb9QrCz7B4k2QgxD/CwIDAQAB"
So it looks like chrome has something like whitelist to allow specific extensions to break the default restrictions. Am I right? Is there official guide to clarify this behavior?
Appendix:
The following is a sample extension, you will find with the key, console will output test even in chrome://extensions pages; however once removing the key, nothing happens.
manifest.json:
{
"manifest_version": 2,
"name": "Test",
"version": "1.0",
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"content.js"
]
}
],
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEGBi/oD7Yl/Y16w3+gee/95/EUpRZ2U6c+8orV5ei+3CRsBsoXI/DPGBauZ3rWQ47aQnfoG00sXigFdJA2NhNK9OgmRA2evnsRRbjYm2BG1twpaLsgQPPus3PyczbDCvhFu8k24wzFyEtxLrfxAGBseBPb9QrCz7B4k2QgxD/CwIDAQAB"
}
content.js:
console.log('test');
"key" property in manifest.json uniquely defines the extension's ID in encrypted form.
Some Google extensions are unfairly(?) whitelisted by ID in the source code of chromium.
In this case, ChromeVox:
scripting_whitelist_.push_back(extension_misc::kChromeVoxExtensionId);
And then this whitelist is checked to see whether an extension can run everywhere in PermissionsData::CanExecuteScriptEverywhere, which is accessed in CheckRestrictedUrls where we can see restricted schemes: chrome://, chrome-extension://, chrome-debugger://

What message is generated by the chrome "permissions" property in an extension manifest?

Given a manifest containing the following "permissions" array, what message can a user expect to see when installing an extension with this permission in Chrome?
{
"name": "My extension",
...
"permissions": [
"http://www.google.com/"
],
...
}
Visit chrome://extensions, search for your extension and click on "Details" ("Permissions" in Chrome 40 and earlier). That will display a screen with the permission warnings that you'd see if the user installs the extension.
You can also use the chrome.management.getPermissionWarningsByManifest method to get a list of permission warnings for a given string that contains the contents of the manifest file.

Chrome extension doesn't work in Linux (works in windows)

Okay, this is weird.
This is my extension, and it works flawlessly in Windows (atleast on two win7 machines), but when I tested it on linux (CentOS6 and Fedora18) it failed to do anything when its icon was clicked (it should, at the very least, display an alert).
The options page still works, and saves data properly.
After enabling developer mode in chrome://extensions/ you can click _generated_background_page.html for the extension to see the JS console for the addon.
That's where I saw the following error:
Error during tabs.executeScript: Cannot access contents of url "https://www.google.com.au/". Extension manifest must request permission to access this host.
actual url in error is not relevant, does it to all sites
Thing is, the windows machines showed no such error, shouldn't this be platform independent?
The manifests are obviously the same, so how come the addon hasn't the required permissions only on linux machines?
Mac is untested, if someone could try that for me, it might be useful
FURTHER INFORMATION
The error message above was given with the following information;
Located in the function chromeHidden.handleResponse on line 22 of the script sendRequest
The "activeTab" permission was added in Chrome 26. Make sure that you've installed Chrome/Chromium 26+.
If you want to make your extension compatible with older browsers in the Chrome Web Store, add host permissions to the manifest file, plus the minimum_chrome_version key:
First upload an extension with the following manifest file:
{
"name": "Name of extension",
"version": "1.0",
"manifest_version": 2,
"permissions": [
"<all_urls>"
]
}
Then bump the version, change "<all_urls>" to "activeTab", add the "minimum_chrome_version" field and upload it again to the Chrome Web Store:
{
"name": "Name of extension",
"version": "1.0.1",
"manifest_version": 2,
"permissions": [
"activeTab"
],
"minimum_chrome_version": "26.0.0.0"
}

Resources