Fetch API not sending session cookies when used inside a Chrome Extension - google-chrome-extension

I'm trying to make a Chrome Extension which scrapes some details from Pull Requests on Github using the Fetch API, and then displays them elsewhere. I'm running into some problems when I try to use this with a non-public repository on Github. I believe this is related to CSRF protection, and the rules that govern Chrome extensions having access to session cookies.
I have the following in my extension's manifest.json:
"content_scripts": [{
"matches": [
"*://github.com/*/*/pulls"
],
"js": ["script/underscore-1.8.3.min.js", "script/content.js"]
}],
"permissions": [
"tabs",
"activeTab",
"*://github.com/*",
"webNavigation"
]
But when I run the following from within my script/content.js:
fetch('/redacted/redacted/pull/4549', {credentials: 'same-origin'}).then((response) => {
return response.text();
}).then((text) => {
// do cool stuff
})
This produces a 404 response from Github. Inspecting this request with Chrome Inspector's network tab, I can see it is not sending my GitHub session header with the request.
If I make the very same request using the Javascript prompt in the Inspector, I can see a 200 response, and I can see that it is sending my session cookies.
My understanding was that specifying the Github domain in my manifest.json would mean my extension would have access to my session data in my content scripts, is this not correct? What should I be doing to make a valid request to this protected content?

According to Chrome blog, to include cookies you need credentials: 'include' instead of credentials: 'same-origin'.

Specifying github in the permissions only gives access to the host, its there to limit damage if the extension/app is compromised by malware (source).
Its not indicated in the content script documentation that session data can be retrieved in content scripts, just their DOMs. I think it would be better if you use and incorporate the official Github API in the chrome extension project you're creating.

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.

How to obtain GET request URL using chrome.webRequest API?

I create a chrome extension which offer accessibility to download any media in opened page of Facebook, including photo, video, and story. But I'm stuck when about to access/catch facebook's video story request URL that's shown up in Network tab in console, using chrome.webRequest API.
By excluding bytestart and byteend params from URL above, we got the full video file (with an expiration token). The <video> tag itself has src attribute like blob:https://www.facebook.com/<some_alpha_numerics_and_hyphens>.
This is what I've tried in my extension project:
permission:
"permissions": [
"webRequest",
"*://*/*"
],
I've tried to listen all the events available but no luck.
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
console.log('onBeforeRequest', details.url);
},
{
urls: ["<all_urls>"]
}
);
// onBeforeSendHeaders
// onSendHeaders
// onHeadersReceived
// onAuthRequired
// onResponseStarted
// onBeforeRedirect
// onCompleted
// onErrorOccurred
I haven't tried chrome.declarativeWebRequest https://developer.chrome.com/extensions/declarativeWebRequest because it's for Beta and Dev channels only.
Is it really possible or did I have mistake in using it? Thank you in advance.
I would recommend adding the "webRequestBlocking" permission to your manifest.json file.
According to the documentation the callback uses a blocking event handler that requires the "webRequest" as well as the "webRequestBlocking" permission in order to work.
Reference: https://developer.chrome.com/extensions/webRequest#examples

Chrome extension doesn't show popup after packing

I am making a Chrome Extension with Login functionality from Auth0, to do that, if user clicks on a login button, it shows login page from Auth0.
On my local machine, I am using local folder to load unpacked extension, then when I click login button, it shows login popup page.
But When I click pack extension, it stops showing Popup page.
My Manifest includes:
"permissions": [
"tabs",
"storage",
"identity",
"notifications"
]
"oauth2": {
"client_id": "***.apps.googleusercontent.com",
"scopes": ["profile"]
}
I checked on background page library JS files for auth0 is also loading.
What else can be problem here?
Problem is with Allowed Callback URLs on auth0 settings and Chrome Extension ID.
On Auth0 setting, my callback URL is https://some-id-for-my-extesion.chromiumapp.org/auth0, this ID is same if developer chooses source code folder because I included export key in my manifest.json.
However, when I pack my extension, it gives me different ID for extension even I don't specify key, and manifest.json still includes export key.So after packing my ID would be packed-ext-id, so my callback URL also should be http://packed-ext-id.chromiumapp.org/auth0
If you come up with this problem, please check callback URLs on auth0, and make sure it matches with extension.
You can see ID below your extension.

getting same origin policy error on getJSON in chrome extension

My Chrome extension background.js checks if a condition is true, and if so, download a script from my server which makes changes to the DOM. Now I'm trying to make a jquery getJSON call from that downloaded script, again, to my server, but I'm getting a XMLHttpRequest cannot load https://www.mydomain.com/loadit.php?h=&fr=0&type=5&category=. Origin http://thisdomain.com is not allowed by Access-Control-Allow-Origin.]`
Now, my manifest file has the following:
"permissions": [
"tabs",
"http://*/*",
"https://*/*"
Which I thought was supposed to allow cross origin requests from any url, so why am I getting the error?
EDIT: What's even stranger is that I'm inserting both an external css file and another js file (jquery) from that downloaded script, and both give me no problems. It's just that getJSON request that does...
ALthough I still don't know exactly why the extension wasn't allowing the cross-domain request, I was able to complete the request by using jquery.Ajax with Jsonp instead of the getJSON.

chrome.tabs.captureVisibleTab on secure pages?

I am developing a chrome plugin that is making use of the screen capture functionality via 'chrome.tabs.captureVisibleTab', but it fails on https pages. I requested permission for secure pages:
permissions:[
"tabs", "http://*/*", "https://*/*"
],
Is this even possible on secure pages?
This is the error I am seeing with sample URL:
Error during tabs.captureVisibleTab: Cannot access contents of url "https://www.host.com/test". Extension manifest must request permission to access this host.
I think you want to use <all_urls>
See this : http://code.google.com/chrome/extensions/match_patterns.html
T.

Resources