Substitute Chrome tab content without connecting to server - google-chrome-extension

I am writing a Chrome extension and for certain tabs I need:
Prevent a tab from connecting to its URL
Show custom text within the tab
(UPDATE) Tab's URL to stay the same preferably
Please suggest a direction how to achieve both the goals.
What I have tried... I can prevent original content from loading:
chrome.webRequest.onBeforeRequest.addListener(...
return {cancel: true};
A technical page is shown then:
Requests to the server have been blocked by an extension.
Try disabling your extensions.
ERR_BLOCKED_BY_CLIENT
(Maybe it's possible to have a custom technical page?)
But this also prevents my content script from loading and thus I lose ability to alter tab's DOM.
Without onBeforeRequest I can show custom text in the tab via a content script, but Chrome still gonna request the original URL.

Instead of cancelling the request by returning {cancel: true}, redirect the request to a URL which contains your custom content by returning {redirectUrl: "..."}.
The easiest way of doing this will be to include a "request blocked" HTML document within your extension as a web-accessible resource. You can pass parameters to the document using query string arguments -- they are ignored when fetching web-accessible resources, but can be accessed from content scripts using window.location.search.
A notable example of an extension that uses this approach is uBlock Origin, which uses a web-accessible HTML page document-blocked.html as a substitute for blocked web pages.

Related

How can I access the url a document is loaded from in chrome.webRequest.onBeforeRequest?

I am building a chrome extension that redirects the tab to an html file if a url on a blacklist is loaded. This html file includes both continue and back buttons. The only problem is I am using chrome.webRequest.onBeforeRequest and I am unable to find a way to store the url that the request originates from. According to the MDN web docs there is a FrameAncestor property that allows you to access this url, but this is not supported by chrome. Are there any equivalent functions or work arounds?

How to inject script into a page using bookmarklet if the Content Security Policy is enabled on the server?

I have a bookmarklet which uses jQuery and parses some elements on the page. To use jQuery, i am creating a script tag(with src as the jQuery URL) dynamically and appending to the head tag. This works well for many sites. But, there are few sites like Facebook, for which the bookmarklet is not able to inject the external JS file into the dom.I came to know that this behaviour is because of the response header "Content Security Policy" which prohibits the inclusion of scripts from any other unauthorized domain. This is to prohibit XSS atacks.
I have a genuine case to insert an external JS file into the DOM. Is there any workaround to by pass the Content Security Policy?
Self-contained bookmarklets are another possibility. Here's jQuery 3.3.1.
Take
javascript:(function(){
})();
And fill the empty line with the jQuery source code, for example the contents of https://code.jquery.com/jquery-3.4.1.min.js .
Afterward set it as URL of your bookmark(let).
The spec says (at least I think it still does) that CSP should not prevent bookmarklets, but no browser has implemented this. Your only option is to disable CSP in the browser or use an extension.

chrome extension options change default popup.html

I have a chrome extension where the popup.html simply has an iframe that loads a page.
I want to allow users to select their language, and as I'm helping a charity do this each language page is very different as they need very different content based on the country!
Therefore, I can't just replace some of the fields like the google developer page example does; I need to change the page that is loaded in the iframe.
e.g. In my directory where the pages are stored I have english.html, german.html, spanish.html all of which are completely different pages.
By default the english.html page loads in the iframe, but the user should be able to go into the options file and select german so when they click on the extension the german.html loads by default every time.
Here is the jsfiddle showing what I currently have in the popup.html, and the popup.js:
http://jsfiddle.net/hemang2/EDV82/
You'll see the flickr API being called, but that's only there because I wasn't sure how to get rid of it!
So essentially my question is how to link the options file to change the default url loaded in the iframe.
Use the setPopup method: http://developer.chrome.com/extensions/browserAction.html#method-setPopup
It allows you to set any html file as your popup.

Blocking Chrome Extensions from running on my site

As a web developer, is there any way to prevent a user's Chrome extensions from being applied to my site? i.e. a header, meta tag, anything? Additionally, if there is, is there also a way to whitelist particular extensions?
It's not possible. At the web server end, you are only only able to control what the browser will allow you to control. In simple terms, this means you can control the data (HTML, javascript, headers etc) that you send back to it. That's about it.
Can't you create a Content Security Policy (CSP) and block inline javascript and only allow javascript from specific domains? You could even create a CSP in report-only mode and collect violation reports via something like https://report-uri.io/

Firefox or Chrome plugin to block and filter all outgoing connections

In Firefox or Chrome I'd like to prevent a private web page from making outgoing connections, i.e. if the URL starts with http://myprivatewebpage/ or https://myprivatewebpage/ in a browser tab, then that browser tab must be restricted so that it is allowed to load images, CSS, fonts, JavaScript, XmlHttpRequest, Java applets, flash animations and all other resources only from http://myprivatewebpage/ or https://myprivatewebpage/, i.e. an <img src="http://www.google.com/images/logos/ps_logo.png"> (or the corresponding <script>new Image(...) must not be able to load that image, because it's not on myprivatewebpage. I need a 100% and foolproof solution: not even a single resource outside myprivatewebpage can be accessible, not even at low probability. There must be no resource loading restrictions on Web pages other than myprivatewebpage, e.g. http://otherwebpage/ must be able to load images from google.com.
Please note that I assume that the users of myprivatewebpage are willing to cooperate to keep the web page private unless it's too much work for them. For example, they would be happy to install a Chrome or Firefox extension once, and they wouldn't be offended if they see an error message stating that access is denied to myprivatewebpage until they install the extension in a supported browser.
The reason why I need this restriction is to keep myprivatewebpage really private, without exposing any information about its use to webmasters of other web pages. If http://www.google.com/images/logos/ps_logo.png was allowed, then the use of myprivatewebpage would be logged in the access.log of Google's ps_logo.png, so Google's webmasters would have some information how myprivatewebpage is used, and I don't want that. (In this question I'm not interested in whether the restriction is reasonable, but I'm only interested in the technical solutions and its strengths and weaknesses.)
My ideas how to implement the restriction:
Don't impose any restrictions, just rely on the same origin policy. (This doesn't provide the necessary protection, the same origin policy lets all images pass through.)
Change the web application on the server so it generates HTML, JavaScript, Java applets, flash animations etc. which never attempt to load anything outside myprivatewebpage. (This is almost impossibly hard to foolproof everywhere on a complicated web application, especially with user-generated content.)
Over-sanitize the web page using a HTML output filter on the server, i.e. remove all <script>, <embed> and <object> tags, restrict the target of <img src=, <link rel=, <form action= etc. and also restrict the links in the CSS files. (This can prevent all unwanted resources if I can remember all HTML tags properly, e.g. I mustn't forget about <video>. But this is too restrictive: it removes all dyntamic web page functionality like JavaScript, Java applets and flash animations; without these most web applications are useless.)
Sanitize the web page, i.e. add an HTML output filter into the webserver which removes all offending URLs from the generated HTML. (This is not foolproof, because there can be a tricky JavaScript which generates a disallowed URL. It also doesn't protect against URLs loaded by Java applets and flash animations.)
Install a HTTP proxy which blocks requests based on the URL and the HTTP Referer, and force all browser traffic (including myprivatewebpage, otherwebpage, google.com) through that HTTP proxy. (This would slow down traffic to other than myprivatewebpage, and maybe it doesn't protect properly if XmlHttpRequest()s, Java applets or flash animations can forge the HTTP Referer.)
Find or write a Firefox or Chrome extension which intercepts all outgoing connections, and blocks them based on the URL of the tab and the target URL of the connection. I've found https://developer.mozilla.org/en/Setting_HTTP_request_headers and thinkahead.js in https://addons.mozilla.org/en-US/firefox/addon/thinkahead/ and http://thinkahead.mozdev.org/ . Am I correct that it's possible to write a Firefox extension using that? Is there such a Firefox extension already?
Some links I've found for the Chrome extension:
http://www.chromium.org/developers/design-documents/extensions/notifications-of-web-request-and-navigation
https://groups.google.com/a/chromium.org/group/chromium-extensions/browse_thread/thread/90645ce11e1b3d86?pli=1
http://code.google.com/chrome/extensions/trunk/experimental.webRequest.html
As far as I can see, only the Firefox or Chrome extension is feasible from the list above. Do you have any other suggestions? Do you have some pointers how to write or where to find such an extension?
I've found https://developer.mozilla.org/en/Setting_HTTP_request_headers and thinkahead.js in https://addons.mozilla.org/en-US/firefox/addon/thinkahead/ and http://thinkahead.mozdev.org/ . Am I correct that it's possible to write a Firefox extension using that? Is there such a Firefox extension already?
I am the author of the latter extension, though I have yet to update it to support newer versions of Firefox. My initial guess is that, yes, it will do what you want:
User visits your web page without plugin. Web page contains ThinkAhead block that would send a simple version header to the server, but this is ignored as plugin is not installed.
Since the server does not see that header, it redirects the client to a page to install the plugin.
User installs plugin.
User visits web page with plugin. Page sends version header to server, so server allows access.
The ThinkAhead block matches all pages that are not myprivatewebpage, and does something like set the HTTP status to 403 Forbidden. Thus:
When the user visits any webpage that is in myprivatewebpage, there is normal behaviour.
When the user visits any webpage outside of myprivatewebpage, access is denied.
If you want to catch bad requests earlier, instead of modifying incoming headers, you could modify outgoing headers, perhaps screwing up "If-Match" or "Accept" so that the request is never honoured.
This solution is extremely lightweight, but might not be strong enough for your concerns. This depends on what you want to protect: given the above, the client would not be able to see blocked content, but external "blocked" hosts might still notice that a request has been sent, and might be able to gather information from the request URL.

Resources