I'm trying to build a Chrome extension and I need to load/save some data from/to the https://address.com. My manifest.json is as below:
"permissions": [
"geolocation",
"unlimitedStorage",
"https://address.com/"
],
"content_security_policy": "script-src 'self'; object-src 'self';connect-src 'self' https://address.com/;"
But I'm running into the below issue when I'm trying to load, I'm not sure what is the issue and how to fix it.
Refused to connect to 'https://address.com/graphql' because it violates the following Content Security Policy directive: "connect-src 'self' blob: .....
Please suggest, thanks.
Fetch Code:
try {
fetch("https://address.com/graphql", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ query: "{ getList(page:1, limit: 10) { t } }" })
})
.then(res => res.json())
.then(res => console.log("getList: ", res.data));
} catch (error) {
console.error("getListError:", error);
}
I just noticed another thing, the code works fine on sites like stackoverflow.com but giving error on facebook, twitter ... any idea.
Related
I'm following the GraphQL documentation to create a Node/Express server. When I get to the 2nd page, it instructs to enter the following code into my browser's developer console:
fetch('/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({query: "{ hello }"})
})
.then(r => r.json())
.then(data => console.log('data returned:', data));
The console returns the following error:
VM100:7 Refused to connect to 'http://localhost:4000/graphql' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.
How do I explicitly set connect-src?
I recently found out that request is no longer maintained, so the best alternative I found is got. I am trying to make an external API call to a REST Server but I am unsure as to how I can add a Bearer token in the authorization header of the POST request.
This is my code:
const response = await got.post(
"https://${SERVER}/${SOME_ID}/conversations/${CONVERSATION_ID}/messages",
{
json: [
{
text: req.body.message,
type: "SystemMessage",
}
],
responseType: "json",
headers: {
token: "Bearer pXw4BpO95OOsZiDQS7mQvOjs"
}
}
);
This results in a 401 Unauthorized. I was unable to find direction to such implementation in the documentation provided by GOT. And since there are not a lot of queries regarding this package, I was unsuccessful in finding anything on Google as well. If anyone can help me out in this regard, that would be very helpful!
Are you sure that the header name is "token" ?
Usually in API, the Bearer is in a header called "Authorization"
const response = await got.post(
"https://${SERVER}/${SOME_ID}/conversations/${CONVERSATION_ID}/messages",
{
json: [
{
text: req.body.message,
type: "SystemMessage",
}
],
responseType: "json",
headers: {
"Authorization": "Bearer pXw4BpO95OOsZiDQS7mQvOjs"
}
}
);
Here is the code
npm i postman-request link for npm package
const request = require('postman-request');
request({
url: 'your url',
headers: {
'Authorization': 'Bearer 71D50F9987529'
},
rejectUnauthorized: false
}, function(err, res) {
if(err) {
console.error(err);
} else {
console.log(res.body);
}
});
I am not sure why the following code is throwing google api key permission denied.
I have the api or service enabled both in firebase console and google console.
export async function createJobDynamicLink(job){
if(job.jobStatus !== 'approved' || (job.dynamicLink).length > 2){
console.log('Dynamic link already exist!');
return false;
}
console.log(dynamic_links);
console.log(dynamic_links_key);
// Firebase web api key logs just fine
const options = {
method: 'POST',
uri: `https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=${dynamic_links_key}`,
body: {
"longDynamicLink": makeDynamicLongLink(job)
},
json: true
};
return await requestpromise(options)
.then(function (parsedBody) {
console.log(parsedBody);
return parsedBody.shortLink;
})
.then((shortLink) => {
//post.shareUrl = shortLink;
console.log('short link: ' + shortLink);
//return event.data.ref.set(post);
return shortLink;
})
}
export async function makeDynamicLongLink(job) {
return buildUrl(`${dynamic_links}`, {
queryParams: {
link: `https://app.com/jobs/${slugify(job.jobTitle)}-${job.id}`,
apn: "com.app.appe",
ibi: "com.app.app",
dfl: "https://app.com",
st: job.jobTitle,
}
});
}
Is something wrong with the way I am doing the request using request-promise?
StatusCodeError: 403 - {
"error": {
"code": 403,
"message": "Requests from referer <empty> are blocked.",
"status": "PERMISSION_DENIED",
"details": [{
"#type": "type.googleapis.com/google.rpc.Help",
"links": [{
"description":"Google developer console API key",
"url": "https://console.developers.google.com/project/904573jjwj/apiui/credential"
}]
}]
}
}
Go to the Google API Credentials https://console.developers.google.com/apis/credentials and see if there is any restriction on your API Key you're using.
If it is restricted by HTTP referrers, then add your website domain to it and add the Referrer header like the above answer.
Although in your use case, None or IP address restriction is a better choice.
Because you are invoking your function from a node.js environment, the HTTP Header Referer isn't being set. When you create requests through a browser, the browser will automatically fill this field for you.
You can get a suitable referrer value using:
"https://" + process.env.GCLOUD_PROJECT + ".cloudfunctions.net/createJobDynamicLink"
// becomes "https://your-project-id.cloudfunctions.net/createJobDynamicLink"
This generated URL isn't callable, because it doesn't start with a region, but it means you now have a URL that can be used to identify that the call is coming from a Cloud Function.
To use it, add it to your request-promise options object.
const options = {
method: 'POST',
uri: `https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=${dynamic_links_key}`,
body: {
"longDynamicLink": makeDynamicLongLink(job)
},
headers: {
"Referer": "https://" + process.env.GCLOUD_PROJECT + ".cloudfunctions.net/createJobDynamicLink"
},
json: true
};
Note: I'd use request-promise-native instead of request-promise - same API but skips loading Bluebird.
In my case i had
<meta name="referrer" content="no-referrer">
in the head so the referer was not being sent
It is possible (though risky) to allow a webextension in the browser to load javascript from a remote url using the following directive in the manifest.json file - by including something like:
"content_security_policy": "script-src 'self' https://example.com; object-src 'self'"
as documented here.
My question is how do I then go ahead and insert the javascript source file remotely housed on https://example.com ?
I tried in Firefox by adding at the top of my extension code:
var script_insert='<script src="https://example.com/dict.js"></script>';
document.write( script_insert + '\n' );
where dict.jscontains:
window.dict_L1C = {
"a" : "hello",
"b" : "world"
}
but that fails with warnings:
Content Security Policy: Ignoring “'unsafe-inline'” within script-src: ‘strict-dynamic’ specified
Content Security Policy: Ignoring “https:” within script-src: ‘strict-dynamic’ specified
I guess I'm doing it the wrong way, or I am missing something important.
UPDATE:
I am now looking at the solutions provides here
This is how from within a webextension I managed to read a dictionary fromhttps://www.remote-dictionary.com/dict.json.
First create the manifest.js that contains a permissions section as follows:
{
"manifest_version": 2,
"name": "mywebextension",
"version": "1.0",
"description": "reads a dictionary from a remote website and uses it on another",
"background": { "scripts": [ "background.js" ] },
"content_scripts": [ { "matches": ["*://my-insertion-site.com/*"], "js": [ "content.js" ] } ],
"permissions": [ "storage", "https://www.remote-dictionary.com/*" ]
}
Next create the background.js file that accesses the remote dictionary and then stores it locally in the browser.
if (typeof chrome !== 'undefined') { browser = chrome}
function fetchDict() {
let req = new Request( "https://www.remote-dictionary.com/dict.json", {
method: 'GET',
headers: { 'Accept': 'application/json' },
redirect: 'follow',
referrer: 'client'
});
fetch(req).then(function(response) {
// .json returns another promise
return response.json();
}).then(function(data) {
browser.storage.local.set({data: data}); // set storage for content-script
}).catch(error => { console.log(error); });
}
fetchDict();
And the content.js script:
if (typeof chrome !== 'undefined') { browser = chrome }
browser.storage.local.get({data: ""},function(data){ // get from local storage
window.dict=data.data;
)
})
// later access the dictionary values:
window.dict[ "my_key"];
I try to get the html page from a internal webserver in my js code, and parse it to make bookmarks.
At the moment I have problems with Access-Control-Allow-Origin, but the permissions are set !
{
"manifest_version": 2,
"name": "test",
"description": "test",
"version": "1.0",
"options_page":"config.html",
"browser_action": {
"default_popup": "test.html",
"permissions": [
"*://*/*"
],
"content_security_policy": "script-src 'self' https://example.com; object-src 'self'"
}
}
I try the code from the example here : https://developer.chrome.com/extensions/xhr :
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// JSON.parse does not evaluate the attacker's scripts.
var resp = JSON.parse(xhr.responseText);
}
}
xhr.send();
But I get the error
XMLHttpRequest cannot load http://api.example.com/data.json. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'chrome-extension://nnbpdlokhkemfjmfkmlfnjonmeaccdmo'
is therefore not allowed access.
I'm pretty lost !
Actually I want to do that (that doesn't work either) :
function httpGet(url,user,pass)
{
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET",url, false );
xmlHttp.setRequestHeader("Authorization", "Basic " + btoa(user + ":" +pass))
xmlHttp.send( null );
response= xmlHttp.responseText;
startT=response.indexOf("menuData = [");
//alert(startT);
Text=response.substr(startT+11 );
Text=Text.substr(0,Text.indexOf("\n"));
var obj = eval (Text)
return Text
}
The permissions section of the manifest should be an independent entry, not located inside browser_action. Check the documentation for the manifest file format.