I just started working with vue.js and try to send a post request to my server, but the request is blocked by CSP.
Error Message:
Refused to connect to 'http://127.0.0.1:5000/login' because it violates the following Content Security Policy directive: "connect-src 'self' ws:".
I have already tried to change my meta-tag but have not come to any solution.
<meta http-equiv=Content-Security-Policy content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:; connect-src 'self' ws:;">
Rest call:
export default {
name: "Login",
data() {
return {
loading: false,
login: {
email: "",
password: ""
}
}
},
methods: {
auth(){
fetch("http://127.0.0.1:5000/login",{
body: JSON.stringify(this.login),
method: "POST",
headers:{
"Content-Type": "application/json"
},
credentials: 'same-origin'
})
.then(res =>{
severdata = JSON.parse(res)
console.log(serverdata)
})
console.log(this.login.email)
this.loading = true;
setTimeout(() => {
this.loading = false;
}, 5000);
}
}
};
</script>```
In your server , you need to return the Content-Security-Policy header.
To allow everything (unsafe), use the following (found on this post):
default-src * 'unsafe-inline' 'unsafe-eval'; script-src * 'unsafe-inline' 'unsafe-eval'; connect-src * 'unsafe-inline'; img-src * data: blob: 'unsafe-inline'; frame-src *; style-src * 'unsafe-inline';
Related
I use the following code inside a Github Action workflow file:
await github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'refs/heads/' + '${{ github.event.inputs.combineBranchName }}',
sha: baseBranchSHA
});
The code results into a 404 :
RequestError [HttpError]: Not Found
at /home/runner/work/_actions/actions/github-script/v6/dist/index.js:6173:21
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async eval (eval at callAsyncFunction (/home/runner/work/_actions/actions/github-script/v6/dist/index.js:13340:16), <anonymous>:71:3)
at async main (/home/runner/work/_actions/actions/github-script/v6/dist/index.js:13436:20) {
status: 404,
response: {
url: 'https://api.github.com/repos/myusername/myrepo/git/refs',
status: 404,
headers: {
...
},
data: {
message: 'Not Found',
documentation_url: 'https://docs.github.com/rest/reference/git#create-a-reference'
}
},
request: {
method: 'POST',
url: 'https://api.github.com/repos/myusername/myrepo/git/refs',
headers: {
accept: 'application/vnd.github.-preview+json',
'user-agent': 'actions/github-script octokit-core.js/3.6.0 Node.js/16.13.0 (linux; x64)',
authorization: 'token [REDACTED]',
'content-type': 'application/json; charset=utf-8'
},
body: '{"ref":"refs/heads/combined-prs-branch","sha":"a3167bb784fa5d045bbad57545a7a96c5d89be4f"}',
request: { agent: [Agent], hook: [Function: bound bound register] }
}
}
I'm using a PAT that has access to public repo.
I went from 403 error with GITHUB_TOKEN to 404 with PAT_TOKEN.
So I guess I solved the permission issue but why is it 404 now ?
I can access the URL https://api.github.com/repos/myusername/myrepo/git/refs in a browser.
I use SendGrid and I know my SendGrid-API key is working by checking from a terminal.
I verified my email in SendGrid Sender Identity.
curl -i --request POST \
--url https://api.sendgrid.com/v3/mail/send \
--header 'Authorization: Bearer MY-API-KYE_HERE' \
--header 'Content-Type: application/json' \
--data '{"personalizations": [{"to": [{"email": "myname#gmail.com"}]}],"from": {"email": "connect#mywebsite.com"},"subject": "SendGrid Test!","content": [{"type": "text/plain", "value": "Howdy!"}]}'
HTTP/1.1 202 Accepted
Server: nginx
Date: Mon, 20 Dec 2021 04:42:08 GMT
Content-Length: 0
Connection: keep-alive
X-Message-Id: 9G5w8P8_SJWPwj1acrNRPQ
Access-Control-Allow-Origin: https://sendgrid.api-docs.io
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl
Access-Control-Max-Age: 600
X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html
Strict-Transport-Security: max-age=600; includeSubDomains
And I get an email.
It works on localhost as well.
But when I deploy to Vercel with the following code, it won't send any email.
import sgMail from '#sendgrid/mail'
import dotenv from 'dotenv'
dotenv.config()
const host = process.env['HOST_URL']
const email_from = process.env['EMAIL_FROM']
const SENDGRID_API_KEY = process.env['SENDGRID_API']
export const sendGridConfirmationEmail = async (name, email, confirmationCode) => {
await sgMail.setApiKey(SENDGRID_API_KEY)
const msg = {
to: email,
from: `${email_from}`,
subject: "Please confirm your account",
text: `Email Confirmation: Hello ${name}.
Please confirm your email by clicking on the following link.
Click here, ${host}/auth/confirm/${confirmationCode}`,
html:`<h1>Email Confirmation</h1>
<h2>Hello ${name}</h2>
<p>Please confirm your email by clicking on the following link.</p>
<a href=${host}/auth/confirm/${confirmationCode}> Click here</a>
</div>`,
}
await sgMail
.send(msg)
.then(() => {
console.log('Email sent')
})
.catch((error) => {
console.error(error)
})
}
I tried the following too, but not working either.
export const sendGridConfirmationEmail = async (name, email, confirmationCode) => {
await fetch(SENDGRID_API, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${SENDGRID_API_KEY}`
},
body: JSON.stringify({
personalizations: [
{
to: [
{
email
}
],
subject: 'Demo success :)'
}
],
from: {
email: email_from,
name: 'Test SendGrid'
},
content: [
{
type: 'text/html',
value: `Congratulations <b>${name}</b>, you just sent an email with sendGrid. ${confirmationCode}`
}
]
})
});
}
How can I send email from Vercel using SendGrid?
I solve the problem.
When I call sendGridConfirmationEmail, I need to use await.
export const post = async ({ body }) => {
...
if (mail_method === "sendgrid") {
await sendGridConfirmationEmail(
body.name,
body.email,
token
);
console.log('SendGrid registration is emailed.')
}
...
Im using the braintree javascript v3 sdk and using a paypal checkout button for my shop.
Code example:
braintree.client.create({
authorization: 'sandbox_xxxx'
}, function(err, clientInstance) {
if (err) {
console.log(err);
return;
}
braintree.paypalCheckout.create({
client: clientInstance
}, function (paypalCheckoutErr, paypalCheckoutInstance) {
if (paypalCheckoutErr) {
console.error('Error creating PayPal Checkout:', paypalCheckoutErr);
return;
}
paypal.Button.render({
env: 'sandbox',
commit: true,
buttonStyle: {
color: 'blue',
shape: 'rect',
size: 'medium'
},
payment: function () {
return paypalCheckoutInstance.createPayment({
flow: 'checkout',
amount: '10.00',
currency: 'EUR'
});
},
onAuthorize: function (data, actions) {
return paypalCheckoutInstance.tokenizePayment(data, function (err, payload) {
document.getElementById("paynonce").value = payload.nonce;
document.getElementById("paymentform").submit();
});
},
onCancel: function (data) {
console.log('checkout.js payment cancelled', JSON.stringify(data, 0, 2));
},
onError: function (err) {
console.error('checkout.js error', err);
}
}, '#paypal-button').then(function () {
});
});
});
To secure my application im using my Content security police:
add_header Content-Security-Policy "default-src 'none';
img-src 'self' *.paypal.com data:;
manifest-src 'self';
style-src 'self' 'unsafe-inline' *.braintreegateway.com *.braintree-api.com https://www.gstatic.com https://fonts.googleapis.com;
script-src 'self' 'nonce-xxxx' *.paypal.com *.paypalobjects.com *.braintreegateway.com https://www.gstatic.com;
font-src 'self' https://fonts.gstatic.com;
connect-src 'self' *.paypal.com *.paypalobjects.com *.braintreegateway.com *.braintree-api.com https://fonts.googleapis.com https://www.google-analytics.com https://www.gstatic.com https://fonts.gstatic.com;
object-src 'none';
base-uri 'self';
form-action 'self';
frame-src *.paypal.com *.braintreegateway.com *.braintree-api.com;
frame-ancestors 'none';";
The button is working fine but the problem is i still recieve reports and errors because the paypal executes inline Javascript:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'nonce-xxxx' *.paypal.com *.paypalobjects.com *.braintreegateway.com https://www.gstatic.com". Either the 'unsafe-inline' keyword, a hash ('sha256-xxx='), or a nonce ('nonce-...') is required to enable inline execution.
[Report Only] Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'nonce-xxxx' *.paypal.com *.paypalobjects.com *.braintreegateway.com https://www.gstatic.com".
As you can see i whitelisted all important urls. I do also add a nonce to run the scripts:
<script nonce="xxxx" src="https://www.paypalobjects.com/api/checkout.js" data-version-4 log-level="warn"></script>
<script nonce="xxxx" src="https://js.braintreegateway.com/web/3.55.0/js/paypal-checkout.min.js"></script>
Not sure it has to do with:
For cross site cookies i use session.cookie_samesite = Strict
Get this warnings:
A cookie associated with a cross-site resource at http://developer.paypal.com/ was set without the `SameSite` attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.
A cookie associated with a cross-site resource at http://www.paypal.com/ was set without the `SameSite` attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.
For a total of 9 paypal subdomains.
EDIT:
I checked my html and found there are multiple inline scripts rendered to the paypalbutton html check my attachment.
How i can solve this problem ?
For the cookie warnings, these are associated with PayPal's domains and it is their responsibility to update them. In current stable Chrome, these warnings are purely informational and are not affecting behaviour. However, if you're using Canary, Dev, or Beta versions you may experience those cookies being blocked.
More context is available at:
https://web.dev/samesite-cookie-recipes
https://www.chromium.org/updates/same-site
It sounds as if those PayPal scripts are trying to inject additional scripts in the page. You may want to consider 'strict-dynamic' to allow the trust to propagate to additional resources:
script-src 'nonce-xxxx' 'strict-dynamic';
This will cause the whitelist or source expressions such as 'self' or 'unsafe-inline', but you can also include them for browsers that do not support strict-dynamic.
Your errors are specifically about 'unsafe-inline' and 'unsafe-eval', so for older browsers you may need to consider those as well. However, I'd test with the strict-dynamic first to see if that meets your needs.
script-src 'nonce-xxxx' 'strict-dynamic' 'unsafe-inline' 'unsafe-eval' 'self' *.paypal.com *.paypalobjects.com *.braintreegateway.com https://www.gstatic.com;
I would also validate that you definitely do not have any inline scripts in the page that you have missed (either from your own code or other third-party services that are not PayPal), in case these are the source of the errors.
I'm setting up login with social media for my app, but my content-security-policy is blocking twitter login from working as intended.
I use window.open to create the popup and post to the twitter library php file. This part works fine. I can click the authorize app button and the user is logged in. The problem is the popup fails to close and the user is not redirected to the members page.
This is the csp log I receive every time the error occurs.
{
"csp-report": {
"document-uri": "https://dev.example.com/twitter-callback.php?oauth_token=Fr5kdwAAAAAAy_TdAAABaTlfL8o&oauth_verifier=i418eqFom1jKd3jYrpirNvAlPJnOBedG",
"referrer": "https://api.twitter.com/oauth/authorize",
"violated-directive": "script-src-elem",
"effective-directive": "script-src-elem",
"original-policy": "upgrade-insecure-requests; default-src https:; connect-src 'self'; font-src 'self' data:; frame-src accounts.google.com platform.twitter.com syndication.twitter.com staticxx.facebook.com www.facebook.com www.google.com; frame-ancestors 'none'; img-src 'self' data: platform.twitter.com syndication.twitter.com *.twimg.com; script-src 'self' 'unsafe-inline' platform.twitter.com/widgets.js apis.google.com/ cdn.polyfill.io/v2/polyfill.min.js cdn.syndication.twimg.com/timeline/profile cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.js connect.facebook.net/en_GB/sdk.js connect.facebook.net/en_US/sdk.js platform.twitter.com www.google.com/recaptcha/api.js www.gstatic.com/charts/ www.gstatic.com/recaptcha/ 'nonce-cjJas4W2X3GtCJszEQ0UZtZqie1hGOWr'; style-src 'self' 'unsafe-inline' blob: cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/ www.gstatic.com/charts/ platform.twitter.com *.twimg.com; base-uri 'none'; object-src 'self'; manifest-src 'self'; report-uri /csp-report/csp.php;",
"disposition": "enforce",
"blocked-uri": "inline",
"line-number": 1,
"source-file": "https://dev.example.com/twitter-callback.php?oauth_token=Fr5pdwAAAy_TAABaTlfL8o&oauth_verifier=i418eqFm1jrNvAlPJnOBedG",
"status-code": 0,
"script-sample": ""
}
} at Date: March 01 2019 13:08:56
If I turn off the csp the login works perfectly OK so it's definitely the csp causing the issue.
Edit: I've tried to add a script-src-elem policy to the CSP e.g script-src-elem 'self' 'unsafe-inline' api.twitter.com/oauth/authorize, but it didn't work.
I figured this out myself in the end.
The problem was caused by having a nonce in script-src. My php script injects inline javascript to close the popup window and redirect, but I forgot about adding a nonce to those script tags.
// close child window and redirect parent window then exit
echo "<script nonce=\"$nonce\">
if (window.opener) {
window.opener.location.href = 'members.php';
window.close();
} else {
window.location.href = 'members.php';
}
</script>";
exit;
Done
I'm trying to set a Mailgun mail service in an ionic app. Here is the code:
Controller:
$http({
"method": "POST",
"url": "https://api.mailgun.net/v3/" + mailgunUrl + "/messages",
//"crossDomain": "true",
"headers": {
"Access-Control-Allow-Origin": "*",//"http://localhost:8100",
"Access-Control-Allow-Headers": "content-type, accept",
//"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE",
"Content-Type": "application/x-www-form-urlencoded",
'Authorization' : 'Basic '+ mailgunApiKey
//"Authorization": "Basic " + mailgunApiKey//$base64.encode('api:key-'+mailgunApiKey)
},
data: "from=" + "no-reply#ineevent.com" + "&to=" + $scope.datapopup.mail + "&subject=" + "Guestlist" + "&text="
config.xml
<content src="main.html"/>
<access origin="*"/>
<plugin name="cordova-plugin-whitelist" version="1"/>
<plugin name="cordova-plugin-crop" spec="~0.1.0"/>
<allow-navigation href="*" />
<allow-intent href="*"/>
<allow-intent href="http://*/*"/>
<allow-intent href="https://*/*"/>
<allow-intent href="tel:*"/>
<allow-intent href="sms:*"/>
<allow-intent href="mailto:*"/>
<allow-intent href="geo:*"/>
I receive the status '0' error and the logs show that CORS (Cross-Origin request) is not allowed with access-control-allow-headers missing (translated from french).
Another error from Chrome is 'Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.'.
I tried also from android device but is not working. Any idea?
Add this to index.html
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
and add cordova-plugin-whitelist plugin to your app.
For the purpose of development you can use CORS plugin for Chrome.
Your controller can be like this:
.controller("EmailCtrl", function($scope, $http) {
var mailgunUrl = "YOUR_DOMAIN_HERE";
var mailgunApiKey = window.btoa("api:key-YOUR_API_KEY_HERE")
$scope.recipient = "mail#gmail.com";
$scope.send = function(recipient, subject, message) {
$http(
{
"method": "POST",
"url": "https://api.mailgun.net/v3/" + mailgunUrl + "/messages",
"headers": {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Basic " + mailgunApiKey
},
data: "from=" + "ionic#example.com" + "&to=" + recipient + "&subject=" + subject + "&text=" + message
}
).then(function(success) {
console.log("SUCCESS " + JSON.stringify(success));
}, function(error) {
console.log("ERROR " + JSON.stringify(error));
});
}
})
The answer is very simple:
when you run android from ionic you shouldn't use any optional parameter:
ionic run android