javascript click function causes Content Security Policy error - google-chrome-extension

One of my chrome extension content scripts is executing a click function on an element like this
var currencySelectorLink = document.getElementById('switcher-info');
currencySelectorLink.click();
However the last line is causing the following error:
Refused to run the JavaScript URL because it violates the following Content Security Policy directive: "script-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution. Note that hashes do not apply to event handlers, style attributes and javascript: navigations unless the 'unsafe-hashes' keyword is present.
I've spend multiple hours now trying to figure this out, maybe some of you will have an idea how to fix it. I absolutely have to trigger this click event, there is no way around it
EDIT:
After some more investigation I found out that it happens, because the link has href attribute with inline javascript:
<a class="switcher-info notranslate" href="javascript:void(0)" id="switcher-info"></a>
anybody has any ideas how to bypass that? If I do this:
currencySelectorLink.href= '#' ;
then error is gone, but it breaks website functionality and not exactly expected behavior comes out of this click event

All that the <a href="javascript:void(0)" code does is to prevent following on the link. You can do the same more pretty way:
currencySelectorLink.href= '#' ;
currencySelectorLink.addEventListener("click", function(event) {
event.preventDefault(); // Prevent default action (a following a link)
}, false);
Note. Since you call click() you already have some event handler. You can insert event.preventDefault(); into it instead of add a second handler. And use:
<a class="switcher-info notranslate" href="#" id="switcher-info"></a>
without javascript:void(0).

Related

chrome extension new tab override but does not focus on input element [duplicate]

With Chrome 27, it seems that extensions that override Chrome's New Tab Page can't take focus away from Chrome's Omnibox like they used to in previous versions of Chrome.
Is there a new way to focus an input box in a New Tab Page, or has this functionality been disabled completely? :(
To test this, create an extension folder with three files:
1. manifest.json:
{
"name": "Focus Test",
"version": "0",
"minimum_chrome_version": "27",
"chrome_url_overrides": {
"newtab": "newTab.html"
},
"manifest_version": 2
}
2. focus.js:
document.getElementById('foo').focus();
3. newTab.html:
<html>
<body>
<input id="foo" type="text" />
<script type="text/javascript" src="focus.js"></script>
</body>
</html>
Then, when you load the extension and open a new tab, the input field does not get focused on the new tab page.
I have also tried adding the autofocus attribute to the input field, but no luck either. The extension's new tab page can't take focus away from Chrome's Omnibox.
Any ideas? Is this a bug or a new "feature"?
ManifestV3 update
This answer is adapted from https://stackoverflow.com/a/11348302/1754517.
This has been tested with both Manifest V2 and V3.
Tested in Google Chrome 99.0.4844.51 64-bit (Windows 10).
Replace the content of focus.js with:
if (location.search !== "?x") {
location.search = "?x";
throw new Error; // load everything on the next page;
// stop execution on this page
}
Add the autofocus attribute to the <input>.
Go to the Extensions page in Chrome and click the Load unpacked button. Choose the folder of your extension.
Open your new tab page. You might see a modal dialogue reading Change back to Google?. Click Keep it to keep your custom new tab page.
Inline Javascript - Manifest V2 only
If you're inlining the Javascript in the HTML file, then you'll need to take some extra steps:
After adding your inline Javascript to your HTML file, open DevTools (F12 key) and observe the error output in the Console. Example output you should see:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' blob: filesystem:".
Either the 'unsafe-inline' keyword, a hash ('sha256-MK0Gypb4mkZTI11eCOtWT+mGYcJNpN5zccvhfeaRb6E='), or a nonce ('nonce-...') is required to enable inline execution.
Select & copy this hash.
Add a line to manifest.json to allow the JS to run, pasting in the hash you just copied between the single-quotes. E.g.:
"content_security_policy": "script-src 'self' 'sha256-MK0Gypb4mkZTI11eCOtWT+mGYcJNpN5zccvhfeaRb6E='"
Go to the Extensions page again. Remove the extension, then re-add it using the Load unpacked button.
Open your new tab page. Your extension should now autofocus on the <input>.
Note inlining only works with Manifest V2; Manifest V3 returns a failure message when attempting to load the extension (even with a properly formed "content_security_policy" object in manifest.json, to replace the Manifest V2 "content_security_policy" string):
Failed to load extension
File C:\path\to\extension
Error 'content_security_policy.extension_pages': Insecure CSP value "'sha256-...'" in directive 'script-src'.
Could not load manifest.
As per the Chrome Extension Documentation,
Don't rely on the page having the keyboard focus.
The address bar always gets the focus first when the user creates a new tab.
See reference here: Override Pages
Here's the solution for Manifest v3
chrome.tabs.onCreated.addListener((tab) => {
if (tab.pendingUrl === 'chrome://newtab/') {
chrome.tabs.remove(tab.id)
chrome.tabs.create({
url: '/index.html',
})
}
})
I saw a pretty old blog which updates the new tab conditionally. However, simply updating the tab does not steal the focus. I had to close the pending tab and open a new one.
Cons: An ugly chrome-extension://akfdobdepdedlohhjdalbeadhkbelajj/index.html in the URL bar.
I have a cheap work around that allows stealing focus from address bar focus. It's not for everyone. I do actually do use this because I want to control a new tab focus just that bad in my own custom new tab solution:
<script>
alert('Use enter key to cancel this alert and then I will control your focus');
document.getElementById('...AckerAppleIsCrafty...').focus()
</script>
USE CASE: I built my own HTML chrome custom tab that has a search input that custom searches my history and bookmarks the way I like it too.
Cash me focusing outside how bout dat?

are there any chrome extension API to set focus in the web page content? [duplicate]

With Chrome 27, it seems that extensions that override Chrome's New Tab Page can't take focus away from Chrome's Omnibox like they used to in previous versions of Chrome.
Is there a new way to focus an input box in a New Tab Page, or has this functionality been disabled completely? :(
To test this, create an extension folder with three files:
1. manifest.json:
{
"name": "Focus Test",
"version": "0",
"minimum_chrome_version": "27",
"chrome_url_overrides": {
"newtab": "newTab.html"
},
"manifest_version": 2
}
2. focus.js:
document.getElementById('foo').focus();
3. newTab.html:
<html>
<body>
<input id="foo" type="text" />
<script type="text/javascript" src="focus.js"></script>
</body>
</html>
Then, when you load the extension and open a new tab, the input field does not get focused on the new tab page.
I have also tried adding the autofocus attribute to the input field, but no luck either. The extension's new tab page can't take focus away from Chrome's Omnibox.
Any ideas? Is this a bug or a new "feature"?
ManifestV3 update
This answer is adapted from https://stackoverflow.com/a/11348302/1754517.
This has been tested with both Manifest V2 and V3.
Tested in Google Chrome 99.0.4844.51 64-bit (Windows 10).
Replace the content of focus.js with:
if (location.search !== "?x") {
location.search = "?x";
throw new Error; // load everything on the next page;
// stop execution on this page
}
Add the autofocus attribute to the <input>.
Go to the Extensions page in Chrome and click the Load unpacked button. Choose the folder of your extension.
Open your new tab page. You might see a modal dialogue reading Change back to Google?. Click Keep it to keep your custom new tab page.
Inline Javascript - Manifest V2 only
If you're inlining the Javascript in the HTML file, then you'll need to take some extra steps:
After adding your inline Javascript to your HTML file, open DevTools (F12 key) and observe the error output in the Console. Example output you should see:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' blob: filesystem:".
Either the 'unsafe-inline' keyword, a hash ('sha256-MK0Gypb4mkZTI11eCOtWT+mGYcJNpN5zccvhfeaRb6E='), or a nonce ('nonce-...') is required to enable inline execution.
Select & copy this hash.
Add a line to manifest.json to allow the JS to run, pasting in the hash you just copied between the single-quotes. E.g.:
"content_security_policy": "script-src 'self' 'sha256-MK0Gypb4mkZTI11eCOtWT+mGYcJNpN5zccvhfeaRb6E='"
Go to the Extensions page again. Remove the extension, then re-add it using the Load unpacked button.
Open your new tab page. Your extension should now autofocus on the <input>.
Note inlining only works with Manifest V2; Manifest V3 returns a failure message when attempting to load the extension (even with a properly formed "content_security_policy" object in manifest.json, to replace the Manifest V2 "content_security_policy" string):
Failed to load extension
File C:\path\to\extension
Error 'content_security_policy.extension_pages': Insecure CSP value "'sha256-...'" in directive 'script-src'.
Could not load manifest.
As per the Chrome Extension Documentation,
Don't rely on the page having the keyboard focus.
The address bar always gets the focus first when the user creates a new tab.
See reference here: Override Pages
Here's the solution for Manifest v3
chrome.tabs.onCreated.addListener((tab) => {
if (tab.pendingUrl === 'chrome://newtab/') {
chrome.tabs.remove(tab.id)
chrome.tabs.create({
url: '/index.html',
})
}
})
I saw a pretty old blog which updates the new tab conditionally. However, simply updating the tab does not steal the focus. I had to close the pending tab and open a new one.
Cons: An ugly chrome-extension://akfdobdepdedlohhjdalbeadhkbelajj/index.html in the URL bar.
I have a cheap work around that allows stealing focus from address bar focus. It's not for everyone. I do actually do use this because I want to control a new tab focus just that bad in my own custom new tab solution:
<script>
alert('Use enter key to cancel this alert and then I will control your focus');
document.getElementById('...AckerAppleIsCrafty...').focus()
</script>
USE CASE: I built my own HTML chrome custom tab that has a search input that custom searches my history and bookmarks the way I like it too.
Cash me focusing outside how bout dat?

Chrome extension won't allow get request

I'm trying to create my first chrome extension. Basically I have a simple html page and some javascript that im using to allow users to enter some data, the script will format it correctly and then output it:
<form>
MAC ADDRESS: <input type="text" id="mac" name="macAddress" maxlength="17" >
<button onclick="convert(); return false;">Convert</button>
</form>
Javascript:
function convert() {
var mac = document.getElementById('mac').value; //get string
var mac2 = mac.replace(/\:|-/g,""); //remove colons and dashes
//
//add fullstops after every 4th character, appart from last character.
//
mac2 = mac2.replace(/(.{4})(?!$)/g , '$1.');
//output string
document.getElementById("outputDiv").innerHTML= mac2;
};
My problem is that while this works fine as a normal web page, the get method, to the same page, is not working when I tried to implement it as an extension.
I've followed the tutorials on google's site and the extension is showing up but it doesn't seem to be able to handle get requests. I've tried modifying the manifest file using different suggestions I found on here but still no success.
Theres nothing in the console when I try to debug it (something briefly flickers up when I submit the get request but it doesn't stay up long enough to see what the issue is).
I'd really appreciate it if someone could point me in the right direction with this!
Due to the Content Security Policy applied to extensions:
Inline JavaScript will not be executed. This restriction bans both inline blocks and inline event handlers (e.g. ).
[...]
The inline event handler definitions must be rewritten in terms of addEventListener and extracted into popup.js.
For more info atake a look at the docs.

Select2 isn't working fine on a chrome extension popup

I'm experiencing a bad behavior of Select2 on a chrome extension using AngularJS and Angular-UI.
The scenario
Select2's content is loaded asynchronously via AngularJs $resouces module.
What should happen?
The content should be display when i click on the Select2.
What is actually happening?
When i first click on any select2 dropdown, it just winks and then hides.
Obs.:
The same code works just fine out of chrome's extension popup.
You can see it working here: http://moneynow2.apphb.com.
And can browse the code here at my github repository.
Mine working fine in Chrome extension, but I'm getting "Refused to execute inline event handler because it violates the following Content Security Policy directive: "default-src 'self' chrome-extension-resource:". Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback." In chrome console.
This is really hard to test.
It looks like in a popup, when I open the dropmenu, the route gets reloaded (the whole controller and contents of ng-view reloads). This doesn't occur on the webpage. I thought that the popup was appearing in the bottom-right corner, stretching out the window (it happened as I stepped through it). When this occurred, I thought it might have triggered a window-scroll event which actually causes select2 to disappear (it's a feature of select2 to prevent the dropmenu from staying in some random place since it's pos:fixed).
I also don't know enough about chrome popups to figure out what events may cause the 'url' to change or a scroll event to trigger, etc.
At first I would have suggested doing selectOptions = { data: $myResource.query() } or something, but I'm starting to think it won't help.
Suggestion:
Try removing the router and see what happens. I don't really know that you should bother with it in a chrome extension. In such a small space, less code is probably better anyway.

Preventing javascript running in a HREF

I have a problem with the following HTML:
<a href="javascript:document.formName.submit();" target="iframe">
Where formName is the name of a form inside the iframe. I would like the browser to navigate to the page "javascript:..." in the iframe, so it executes the javascript on the current page in the iframe. My problem is that the browser will attempt to execute the function and use the returned result as the url. Of course there is no form to submit on the current page, so I just get an error.
Cross domain iframes are no fly zones, you won't be able to do anything with or to the DOM inside of a frame on a different domain. Even if the user clicked the submit button inside the frame, your page would not be able to get the new url back out of the frame.
In this case, you can do it by reaching inside the iframe:
<a href="javascript:window.frames[N].contentDocument.FORMNAME.submit()">
(that may not be exactly the right incantation). In general, you should do this with an onclick handler for the hyperlink, that invokes a function defined by the iframe's document.
EDIT: There is NO WAY to make this work cross-domain. It's a violation of the browser's security policies.

Resources