Securing chrome extension API Calls with tokens - google-chrome-extension

I'm trying to secure API calls from my chrome extension to my website hosted on AWS. The SO posts I've so far were quite dated & not effective ways. The most recent & best tutorial I've found so far is from Very Good Software where it requires for user's google OAuth access token via:
Background.js:
chrome.identity.getAuthToken({ 'interactive': true }, function(token) {
if (token){alert('token is ' + token)}
else{alert('token not present')}
});
manifest.json
{
"manifest_version": 2,
"name": "To be named",
"description": "This extension helps...",
"version": "0.1.0",
"browser_action":{
"default_popup":"popup.html"
},
"permissions": [
"storage",
"identity",
"identity.email",
"http://127.0.0.1:5000/Time"
],
"oauth2":{
"client_id":"1097711......apps.googleusercontent.com",
"scopes":["https://www.googleapis.com/auth/userinfo.profile"]
},
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [{
"matches": ["https://www.blank.org/"],
"js": ["content.js"],
"css": ["styles.css"]
}]
}
where the access_token gets passed to your server for you server to decrypt via:
#blueprint.route('/verification')
def verification():
from firebase_admin import auth, credentials
import firebase_admin
cred = credentials.Certificate("Firebase.json")
firebase_admin.initialize_app(cred)
decoded_token = auth.verify_id_token("ya29.a0AfH6...AY")
uid = decoded_token['uid']
print(uid)
return str(uid)
While the token gets generated, I realized the firebase-sdk requires a verify_id & not access token. Therefore, I'd like to know if this way can be corrected to use for protecting API calls with chrome extension?
if not what's the most recent & best way to protect API calls from chrome extension as of now? Given that the source code can be viewed.
Also, I don't think I can POST the access token & see if it matches my server login access token of User, as I believe they change everytime.
Also, rate limiting doesn't really help at all with my problem, as the service is personal and can't be shared and if attacker were to break in, it only needs few calls anyway to lunch a malicious attack.

Related

Chrome extension "fails" to register service worker in citrix

While developing a chrome extension and delivering to users via GPO, for some reason after the installation of the extension on chrome the service worker do not register on chrome in Citrix environment. That seems to be a problem only with Manifest V3.
Things to note:
Installation is successful on chrome, I can see the icon on chrome://extensions/, but the service worker appears "Inactive".
This particular extension is hosted on private web server.
After restarting chrome, sometimes the service worker is successfully registered.
To see if the service worker was registered, I checked on chrome://serviceworker-internals/.
What I have tried so far:
When the installation is successful, on the service worker I used this approach:
chrome.runtime.onInstalled.addListener(function (value) {
if (value.reason == 'install') {
setTimeout(function () {
chrome.runtime.reload();
console.log('Reload!');
}, 2000)
}
})
But since the service worker keeps "Inactive" and not registered on chrome://serviceworker-internals/, it didn't work.
I checked that the problem only happens in Citrix environment with non-permanent images, meaning that the extension will install in every user logon via GPO.
This extension does not have a default popup, it's supposed to work entirely on service workers, without a user interface.
I checked that with manifest V2 extensions, on the same environment, everything works fine.
If I add a popup, sometimes when the user clicks on the popup, the registration of the worker starts. Same behavior as restarting chrome.
I did not find any mention to this problem anywhere, since it's so specific.
Note: I can't share any part of the service worker since it's a private extension, but I'll share the manifest below, but keep in mind that the installation works fine as I mentioned before.
So, I'm looking for any idea on what is going on before sending an issue on chrome.
manifest.json:
{
"manifest_version": 3,
"name": "",
"description": "",
"version": "1.0",
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": [ "<all_urls>" ],
"css": [ "logic.js" ]
}
],
"permissions": [ "storage", "declarativeContent", "activeTab", "scripting", "tabs", "webNavigation", "nativeMessaging" ],
"host_permissions": [ "https://*/*" ],
"action": {
"default_icon": {
"16": "/images/logo16.png",
"32": "/images/logo32.png",
"48": "/images/logo48.png",
"128": "/images/logo128.png"
}
},
"icons": {
"16": "/images/logo16.png",
"32": "/images/logo32.png",
"48": "/images/logo48.png",
"128": "/images/logo128.png"
}
}

Chrome Extension Rejection "Use of Permissions" All URLs

Hello Stack Overflow Team, I am hoping you can help.
The Google Chrome webstore as of 3/1/2020 is rejecting all my extensions that have activeTab permissions specifically <all_urls> requests. Below is the email I get AFTER my extensions are reviewed.
Your item did not comply with the following section of our Program Policies:
"User Data Privacy"
Your product violates the "Use of Permissions" section of the policy, which requires that you:
Request access to the narrowest permissions necessary to implement your product’s features or services.
If more than one permission could be used to implement a feature, you must request those with the least access to data or functionality.
Don't attempt to "future proof" your product by requesting a permission that might benefit services or features that have not yet been implemented.
This is a HUGE problem because not only are all our recent apps being rejected, but so are the updates to our existing apps that are using the EXACT same permission set.
Our extensions connects business phone systems to Chrome and one of the features we offer is click to call. In order for click to call to work we need <all_urls> permissions so we can find phone number and make them clickable. Below is a sample of our code.
What changes do I need to make in order for Google Chrome to STOP rejecting our extensions?
{
"update_url": "https://clients2.google.com/service/update2/crx",
"name": "abc extension",
"description": "abc company click to call",
"short_name": "abc click to call",
"version": "0.00.01",
"manifest_version": 2,
"permissions": [
"storage",
"notifications",
"tabs",
"contextMenus",
"<all_urls>"
],
"browser_action": {
"default_icon": {
"19": "images/icon.png"
}
},
"content_security_policy": "script-src 'self' https://maxcdn.bootstrapcdn.com; object-src 'self'",
"default_locale": "en",
"content_scripts": [
{
"matches":["<all_urls>"],
"css": [ "css/content.css" ],
"js": ["js/jquery.min.js","js/content.js"],
"run_at": "document_end"
}
],
"background": {
"scripts": ["js/jquery.min.js","js/background.js"]
},
"web_accessible_resources":["images/*.png","html/login.html","html/dashboard.html"],
"icons": {
"16": "images/icon.png",
"48": "images/icon.png"
}

Why does my chrome extension ask for history permissions?

In my manifest.json file, I have nothing explicitly listed for reading a user's history, however, this warning comes up when you try to install the extension.
Here is my manifest file:
{
"manifest_version": 2,
"name": "QueueTube for YouTube!",
"short_name": "QueueTube",
"description": "Search YouTube without stopping the video, and make your own playlists!",
"version": "1.5",
"author": "Dara Javaherian",
"permissions": ["tabs", "*://*.youtube.com/*"],
"background": {
"persistent":true,
"scripts": [
"bg/socket.io.js",
"bg/background.js"
]
},
"icons": {
"128": "icons/youtube-128.png"
},
"browser_action": {
"default_icon": "icons/icon.png",
"default_popup": "popup/popup.html"
},
"web_accessible_resources": [
"spinner.gif"
],
"content_scripts" : [{
"matches" :
["https://www.youtube.com/*",
"http://www.youtube.com/*"],
"js" : [
"js/jquery.js",
"js/inject.js"],
"css" : ["styles/styles.css"]
}]
}
Does anyone know why this permission is showing up?
This is the standard warning for the "tabs" permission.
It allows you to query, and be notified of changes, to URLs of all tabs. This allows you to spy on the user's history in real time - even if you don't have access to the browser's own history log.
Note that "tabs" permission is not required in most cases. Providing access to URLs is basically the only reason to include it. You can use most of the tabs API without it, and can get access to current tab without warning using the "activeTab" permission.
Warnings and their triggers
It can be surprising when adding a permission such as "tabs" results
in the seemingly unrelated warning that the extension can access your
browsing activity. The reason for the warning is that although the
chrome.tabs API might be used only to open new tabs, it can also be
used to see the URL that's associated with every newly opened tab
(using their tabs.Tab objects)
Source: https://developer.chrome.com/extensions/permission_warnings

chrome.identity.getAuthToken not working

I am working with Chrome Identity API, to provide users with a Google Authentication on my Chrome Extension.
I followed the official tutorial of Google : link Chrome Identity API
i added permissions to manifest.json and Client ID and Scopes
to trigger the Authentification i added this code in my Background.js
chrome.identity.getAuthToken
The problem is when i execute the extension i am redirected to this login page
chrome://chrome-signin/?source=5
but after a successfull authentication i am redirected another time to the login page
what is the problem ?
Manifest.json
{
"name": "My Extension",
"short_name": "Ex App",
"version": "0.1",
"description": "description",
"manifest_version": 2,
"icons": { "128": "ICONE.png", "48": "ICONE1.png" },
"permissions": ["contextMenus", "identity", "cookies", "http://*/*", "https://*/*", "<all_urls>", "unlimitedStorage"],
"browser_action": {
"default_title": "Title",
"default_icon": "imgIcone.png"
},
"oauth2": {
"client_id": "xxxxxxx",
"scopes": [
"https://www.googleapis.com/auth/userinfo.email"
]
},
"background": {
"scripts": ["background.js"]
},
"content_scripts" : [
{
"matches": ["*://*.google.com/*"],
"js": ["gadget/js/jquery.js","gadget/js/contactcard.js"],
"css": ["gadget/css/contactcard.css"],
"all_frames": true
}],
"content_security_policy": "script-src 'self' 'unsafe-eval' https://apis.google.com/; object-src 'self'",
"web_accessible_resources": ["img.png","gadget/css/contactcard.css","gadget/img/extension/crec.png"]
}
Background.js:
chrome.identity.getAuthToken({ 'interactive': true }, function(token) {
// Use the token.
console.log(token);
});
Problem Resolved !
the app ID of my Chrome extension does not match with my app ID in Google Console Developpers
To avoid this upload first your Extension then copy the ID from Chrome and set it in the Google Console Developpers !
you must update it in Google console everytime you change it in Google Chrome
The accepted answer is incorrect. You can upload it to the webstore, publish it, then install it from the webstore. After installing, find the installed extension app dir (~/Library/Application\ Support/Google/Chrome/Default/Extensions/<ext id> on a mac), and copy the key key from the installed manifest.json into your source code manifest.json. After adding the key field to your manifest.json, your app id will not change during local development.
Source: https://developer.chrome.com/apps/app_identity#copy_key
For other user, who might face the problem that chrome.identify.getauthtoken is not firing or you log in and nothing happens.
Check your manifest and reduce it to the bare minimum. For example the
"oauth2": { "client.id": "alongstring" , "scopes": ["bla","openid", "bla"]}. Having openid in the array, the callback simply did not fire, no alert, no nothing.
Having openid inside my scopes inside oauth2 blocked in someway the callback from being fired.
If the callback in chrome.identity.getAuthToken is not firing at all for you, make sure you are using "browser_action" in your manifest.json and not "page_action".

Download url chrome extension

I am trying to download a url by writing code for chrome extension. Here is the myscript.js file:
chrome.downloads.download(
{url: 'http://www.iana.org/_img/iana-logo-pageheader.png',
saveAs: true
},
function(res){alert(res);});
and here is my manifest.json
{
"name": "My extension",
"version": "1.0",
"manifest_version":2,
"background_page": "background.html",
"browser_action": {
"name": "Manipulate DOM",
"icons": ["icon.png"],
"default_icon": "icon.png"
},
"permissions": ["downloads",
"tabs", "http://*/*","https://*/*"
],
"content_scripts": [
{
"matches": [ "http://*/*", "https://*/*"],
"js": ["jquery.js","d3.v2.js","myscript.js"],
"run_at": "document_end"
}
]
}
but the console is showing the error "Cannot call method 'download' of undefined".
Please help me.
The documentation for chrome.downloads clearly states that the "API is still under development. It is only available for Chrome users on the dev early release channel." (emphasis mine, currently at Chrome 23).
To use the API, you need to get a dev or canary build of Chrome (see this page for download links).
Another way to solve the problem is by not using the chrome.downloads API. I've been using the following method to create downloads, and it works like a charm (it works anywhere: Content script / background page / popup / whatever):
var a = document.createElement('a');
a.href = 'http://www.iana.org/_img/iana-logo-pageheader.png';
a.download = 'iana-logo-pageheader.png'; // Filename
a.click(); // Trigger download
a.click() causes Chrome to follow the link.
The download attribute causes Chrome to download the target, and suggest the attribute's value as a file name in the Save As dialog.
This feature is not limited to Chrome extensions, you can also use it in an ordinary web page. Have a look at this demo: http://jsfiddle.net/dEeHF/.

Resources