XMLHttpRequest succeeds without manifest permissions? Maybe CORS? - google-chrome-extension

I have developed a Google Chrome extensions that uses YouTube Data API v2. My permission field in the manifest looks like this, because the script is injected in pages under youtube.com and I also need access to tabs:
"permissions": ["tabs", "*://*.youtube.com/*"]
This also works when I do a request to YouTube Data API v2 because the request is done to http://gdata.youtube.com/, so it is the same domain. But now I am migrating to YouTube Data API v3, and the requests must be done to http://www.googleapis.com/youtube/v3/ (note HTTPS instead of HTTP also). However, surprisingly, my requests are working perfectly without adding any new permission.
I know, I am asking something that doesn't seem to be a problem, but personally I consider any behavior that I don't understand in my software a problem. Why does this happen? Am I not supposed to add a permission such as "*://*.googleapis.com/*" in order for my XMLHttpRequest requests to the API to work?
I also have some king of guess about this: HTTP Access Control headers. My requests do send a Origin header with value chrome-extension://myExtensionId. And the answer from the API also contains the following header:
Access-Control-Allow-Origin: chrome-extension://myExtensionId
But could this be the reason Chrome is allowing me to do a cross-origin XMLHttpRequest without any extra permission defined in the manifest? Not sure, and apparently this is not documented anywhere in Google APIs, YouTube Data API v3 or Chrome Extensions developer documentation.

If Chrome does not find the permission in the manifest, it treats a request as a normal request. This means that a request will still succeed when the right CORS headers are set. Otherwise, a request will fail because of the same origin policy.
The Google API JavaScript library explicitly mentions support for CORS:
Making a request: Option 3
Google APIs support CORS. Please visit the CORS page for more information on using CORS to make requests.
If possible, I still recommend adding the permission to the manifest file. For simple requests, this does not bring any advantages. For non-simple requests, this will half the number of requests: Non-simple requests are always preceeded by a preflight (OPTIONS) request which checks if the client is permitted to access the source.
By adding the permission to the manifest file, Chrome will not fall back to CORS, and always use one network request to complete the request. Great!
However... you might think again if you're the author of an already-deployed extension. When new origin permissions are added to the manifest file, the extension will be disabled until the user approves the extension. The dialog box shows "Remove extension" and "Enable" next to each other, so there's a chance of loosing the user.
If you wish, you can overcome this problem by using an optional permission, activated at the options page. Clearly explain in layman language that the option will improve the speed of the extension, and don't forget to mention that additional permissions will be requested.

Related

Is it possible to update parts/directives in the "content-security-policy" header using DeclarativeNetRequest API?

I am in the process of migrating from Manifest V2 to V3, from Web Request API to Declarative Net Request API. Using Web Request, I modify the "content-security-policy" header by adding a domain into the list of various directives (default-src, frame-src, etc). I tried using the "append" operation in the rule action. Is it possible to target a directive? What if the directive does not exist? Does append just add the supplied string to the end? With Web Request, I was able to examine each directive and update each accordingly, before returning the new value. This allowed me to inject a script that is needed into each frame.
Instead, would it be possible to continue to use the Web Request API with V3? In my setup, I have my chrome extension "Published - unlisted". I do use the force install option when deploying the extension to our internal users, and the only reason I have it unlisted and not private is so that the users who have the extension can get updated whenever a new version is released. Would it be possible to have users updated without having the extension listed? Perhaps by hosting the extension in my own server? Please advise on what can be done to have the ability to update the response header, specifically the "content-security-policy" header the way I have done before, and whether I can continue to use Web Request API going forward (using V3). In the Chrome dev website, there's a mention about continuing to use Web Request if force install is used, and only if its "deployed to a given domain or to trusted testers", but I'm not sure what that actually means. What would I need to do to meet the criteria?
I tried using the append operation in the rule action via the Declarative Net Request API, but its not working as expected. I dont see the security policy being updated when I inspect the response header in dev tools. I also get errors stating that many scripts, images, etc violate the security policy for websites that did not have one to begin with (My extension targets any website).

JSONP mimetype mismatch for instagram embed api

We are using JSONP approach to load instagram embed posts, however recently we got an issues with response content-type mime-type mismatch.
Any solutions to fix JSONP approach without switching to embed.js or to json?
Cross-Origin Read Blocking (CORB) blocked cross-origin response https://api.instagram.com/oembed/?url=https://www.instagram.com/p/BJPIEc8BHEI/&hidecaption=false&callback=_jsonp_instagramImage_0 with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.
and IE:
The resource from ... was blocked due to MIME type mismatch
Loading just by creating <script> and callback
Facebook say:
This issue is related to the legacy Instagram API (api.instagram.com)
which isn't supported via this channel; this bug reporting tool only
supports issues related to the Instagram Graph API. Additionally, as
the legacy Instagram API has been deprecated as of July 2018, the team
is no longer accepted bug reports for this API. Thanks for your
understanding.
https://developers.facebook.com/bugs/235545030662906/
See also https://github.com/sugarshin/react-instagram-embed/issues/89.
I ran into a similar issue; it looks like Facebook changed their CORS policies a few days ago and didn't tell anybody. You'll have to work around CORS. I set up a php script to handle my GET request from my webapp, which in turn calls a python script to make the GET request and pass back the data. Happy to share the code if you'd like.

How to detect ajax request which created by other extension content script

I have created chrome extension, which can handle current page ajax request, but my extension can't handle ajax request, which crated by other exstension (that requests I can see in chroome network tool). How can I handle ajax which initiators are other exstension scripts ??
please take a look at this
The webRequest API only exposes requests that the extension has
permission to see, given its host permissions. Moreover, only the
following schemes are accessible: http://, https://, ftp://, file://,
or chrome-extension://. In addition, even certain requests with URLs
using one of the above schemes are hidden, e.g.,
chrome-extension://other_extension_id where other_extension_id is not
the ID of the extension to handle the request,
https://www.google.com/chrome, and others (this list is not complete).
Also synchronous XMLHttpRequests from your extension are hidden from
blocking event handlers in order to prevent deadlocks. Note that for
some of the supported schemes the set of available events might be
limited due to the nature of the corresponding protocol. For example,
for the file: scheme, only onBeforeRequest, onResponseStarted,
onCompleted, and onErrorOccurred may be dispatched.
According to that, could you please check your host permissions settings and add there chrome-extension://* or just <all_urls>

Status code without requiring webRequest permission?

I'm writing a Chrome extension to fallback to Wayback Machine when a link fails.
webNavigation seems sufficient for the DNS-lookup case, but I don't see a way to detect link failure with only webNavigation in general.
For example, http://www.google.com/adasdasdasdasdasdasd is a 404 link - but I still get webNavigation onDOMContentLoaded and onCompleted, without indication of HTTP error (no onErrorOccurred is sent).
I was really hoping to avoid needing the webRequest permission with wide-open host patterns. Is there a way to detect HTTP failure that I'm missing?
Send a XMLHttpRequest HEAD request in onBeforeNavigate and analyze the response status code in onreadystatechange callback. If it's 404 then use chrome.tabs.update to change the tab url.
The drawback of sending an additional request for every page is insignificant since web pages usually generate a lot more requests while loading.

Implementing Google+ one-time code flow authentication from chrome extension

I am trying to implement a Google+ sign in option as part of a chrome extension using the one-time code flow as described here.
While making a request using the javascript Google API package a popup opens with an "origin_mismatch" error. This is obviously since I need to add my origin to the relevant Client Id on the Google API console.
My origin is : chrome-extension://<my extension id> however when trying to add that on the API console I get an error saying "Invalid URI: chrome-extension://..." which probably means this scheme is not supported.
Any idea what I can do instead?
I've faced the same problem. I think Google has changed the validation for javascript origins and doesn't allow origins from chrome-extension any more. Google gives you the Chrome Identity API instead (https://developer.chrome.com/apps/app_identity)
But there is a workaround. If you already have at least one chrome-extension://[ext_id] origin in your client ID and you have for example the older version of your extension with this extension ID, you can:
install this extension
go to C:\Users\username\AppData\Local\Google\Chrome\User Data\Default\Extensions (for windows)
find your extension there and open the manifest.json
copy the line "key":"[your_key]" and paste it into your developed manifest
and after next build you should get the extension with the same id as it was in the working one. Also it won't change any more.

Resources