-
Notifications
You must be signed in to change notification settings - Fork 448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cross origin http request CORS fails with response header missing 'Access-Control-Allow-Credentials: true' #620
Comments
Have you tried enabling CORS via the Function App Settings? |
@christopheranderson thanks for the reply. |
Another stackoverflow issue but for azure app services. But in this case developer got away by disabling azure CORS handling and handled it in the web api code. But in the case of azure function, with http trigger your function do not get chance to have say in that. So we either need a way for azure to handle iit correctly or a way to bypass and handle in the code. Please help me. |
I have finally managed to get around the issue. The trick is to remove all the CORS entries from Azure Functions app and handle it directly in your code. Thanks to the tip shared in post regarding azure app service.
And from client side javascript: ` var request = new Request(url, { fetch(request) I close this issue for now, but it will be great if we can specify additional headers at the application level. |
Though with the workaround, I am able to get resources, but it still does not allow /.auth/* calls. https://shellmonger.com/2016/02/12/using-azure-app-service-authentication-with-a-web-application/ |
This is an Azure App Service feature request, not specific to Azure Functions. We'll put this on the backlog category for tracking purposes, but please file a UserVoice suggestion for Azure Web Apps here: https://feedback.azure.com/forums/169385-web-apps-formerly-websites |
@satjinder Thanks for the tip that removing all CORS entries allows for the headers to be set manually in the response in code. That solved my problem, and I can have my own custom logic for checking valid domains now. Note: Now I get a warning that CORS is not configured for the functions domain:
Is there any problem with ignoring this? |
@ricklove Can you please clarify what you did? This is my code:
When I clear all URLS from API -> CORS in the Azure Portal the "Access-Control-Allow-Credentials" header works properly and is set to true, but "Access-Control-Allow-Origin" is not passed through and therefore is not set. When I set API -> CORS in the Azure Portal to my domain name, that header is set properly, but Access-Control-Allow-Credentials is not set. |
That's not the behavior I obtained when I removed all entries in the CORS settings (in the Functions area). Note: There is no wildcard entry and I am getting an error in the portal that says, "CORS is not configured for this function app. " Both my headers are getting through fine: // (Excuse the custom code in Typescript)
let wildcard = true;
export function addCorsHeaders<T extends { [name: string]: string }>(request: T.SimpleRequest, headers: T): T {
// 'Access-Control-Allow-Origin': '*',
// 'Access-Control-Allow-Credentials': 'true',
let origin = request.headers['origin'] || request.headers['Origin'];
if (wildcard || cors_domains.indexOf(origin) >= 0) {
// Here is the important part
headers['Access-Control-Allow-Origin'] = origin;
headers['Access-Control-Allow-Credentials'] = 'true';
}
return headers;
} // This is where I call that
context.done(null, {
headers: addCorsHeaders(request,{
'Content-Type': 'application/json',
'Set-Cookie': `blobBaseName=${blobBaseName}; Expires=${new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toUTCString()}; Secure; HttpOnly`
}),
body: {
ok: true,
data: { urls, isNew },
}
}); And here are my response headers in Chrome:
After looking through the code, I see a difference in our responses:
Perhaps the context.res is not respecting your header and the done method is. |
@ricklove Thank-you. Implementing your code helped me isolate the issue. Apparently because I cleared out the "deployments" directory of logs, it actually caused my future deployments to say they were working, but actually fail to put my code into wwwroot. (I'm continuously deploying based on a git repository). As a result when I thought I was putting other code out to add new headers... I actually wasn't. Once I changed out my code to mimic your code it became absolutely clear that my changes weren't doing anything, and I explored further to find the real issue. I'm still trying to get the code deployed correctly, but I'm pretty sure that was the real reason why I had the results. |
A heads up: The workaround to remove all CORS in the portal no longer appeared to work. I discovered that this was because I had enabled the new Azure Functions Proxies (preview). Upon disabling proxies, it worked again. So, if you are having trouble getting manual CORS to work:
|
@safihamid not sure if this is expected side effect of enabling proxies. |
@ricklove we don't really do anything specific with CORS in Functions Proxies. Would you please let us know your scenario and how we can repro this? This is our default CORS setting for Proxies:
|
@safihamid Yes, of course, I was using proxies so it was unfortunate that I had to disable them because I could find no workaround for the CORS problem. SetupRemove all entries from the portal CORS panel. (Including the * wildcard entry.) This is required in order to bypass the CORS logic as mentioned above. CodeIn a Node.JS http function:
Repro ProblemYou will need to call this function with an ajax cross origin call (from a different domain) in order to trigger the CORS browser behavior.
|
@ricklove thanks for the repro, we have a fix for Proxy for this and will release it in the next few days. |
@safihamid Wow that was fast. Tell the team thanks for your work! |
fyi the fix is live now! You will need to update your Proxy runtime version to ~0.2 from the portal. |
Thanks @safihamid. I'm closing this issue as it seems like the main ask has been handled. If there are other feature request, please open a new issue so we can track properly. |
I'm not sure the issue @safihamid fixed is the same one that was originally reported. The proxies issue was more of a tangent that just happen to get reported here. |
Good catch @ahmelsayed. I'm still not sure about the original issue, there was a lot of back-and-forth. Can the original posters please comment? |
I hope this gets fixed soon. Getting bit bad by it :\ |
I posted this issue in the UserVoice as @lindydonna suggested: Quite new CORS stuff so I hope I described the problem accurately. I'd encourage anyone interested in getting this fixed to upvote on UserVoice |
The feature request was declined because the feature is not supported? |
I feel like the request has been misunderstood and needs to be reconsidered. This workaround isn't a solution, we need either a way to disable Azure's CORS responses and remove the warning regarding functions.azure.com, or the Azure CORS support needs to be extended to support the -Credentials header. Citing an article by a Microsoft developer for a workaround isn't a closing statement for declining. If anything it highlights that the issue is known and needs to be fixed. I understand that this is a Web App issue and not a Functions issue, however, I hope the developers for Azure Functions can help us get this resolved. Kind regards, |
@nevercast I agree completely. The whole response on that thread for the NFR doesn't make any sense at all and this is very much needed. There has to be a disconnect somewhere. Adding a configuration option in the portal that sets another HTTP Header does not sound like something that should be a huge development effort. The note on that thread is signed by an "Oded", could it possibly be @odvoskin ? |
Adding @cgillum as he may have some additional details here after it was discussed internally. |
Sorry for being late to the party. I agree, it looks like the feature request on the feedback site was misunderstood. We discussed this a bit internally and there's no technical reason why we can't add support for Let me know if you have any other thoughts/comments/feedback you'd be willing to share about your need for this. I'll reply back after another round of internal discussion. |
I may well be wrong about this, but I was under the impression you still need |
@burma-shave You're not wrong at all, that is precisely my use-case also, a JWT using |
@burma-shave Thanks for that info, a quick search confirms: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
We'll look into adding support for this. Thanks for your patience on this issue. @odvoskin can we update the feedback response? I think the case has been made that this feature is needed. |
Done on my end. @cgillum - please leave comments in the UserVoice item about approach and any timing we can share, when that becomes available. |
Thank you for reconsidering! This is great news. 👍 |
I am so glad to hear that. I did give up on this. |
I just wanted to talk a little bit about the "security implications" of cookies vs. tokens. There seems to be this impression that tokens are somehow more secure than cookies. I disagree with this. Both have their advantages and disadvantages and I think cookies, when handled properly, come out slightly ahead. I want the "Access-Control-Allow-Credentials" header because we use cookies, and we are a security consulting company. This doesn't mean we're right, but I've thought a decent bit about this. From a security stand-point, utilizing tokens completely prevents Cross-Site Request Forgery (CSRF) attacks. This is the main, and only real security advantage I can see that tokens have over cookies. They work to prevent CSRF attacks because a CSRF vulnerability is reliant on the web-browser automatically adding the session token when a request is sent for a given domain, even from an untrusted domain. Since tokens have to be added by JavaScript code running in the context of the domain, CSRF is stopped by default. However, being immune to this problem comes at a cost. Since JavaScript has to be able to access and send the session token, this means that Cross-Site Scripting (XSS) (Should the vulnerability exist) will ALWAYS be able to access the session token. While XSS's possibilities of actually being able to execute are reduced with a JSON application that properly sets the Content-Type to application/json; XSS is still one of the most common vulnerabilities in web applications. With tokens you are guaranteed that the worst possible exploit of XSS is available, the stealing of the session token. This is a huge negative, that I believe completely counters the positive of stopping CSRF. There is no way to use a token, and avoid this exploit scenario IF XSS is found in the application. Cookies on the other hand are vulnerable by default to CSRF since any web-browser will automatically add the cookie to a request destined for a given domain. You can prevent this behavior, however, by sending CSRF tokens from the framework itself to the server. This will mean you are sending both a session cookie and a CSRF token; but when you do you have completely blocked CSRF. In addition, with cookies you have the option of setting the "httpOnly" flag on cookie creation. This flag makes it impossible for JavaScript to read the cookie value, even though that value is still sent to the server for authentication. This means that even if a XSS vulnerability is discovered, it will NOT be possible to take advantage of the worst exploit for that vulnerability; stealing the session token. The attacker still will be able to utilize the XSS to grab the CSRF token, and send a fraudulent request to the server on behalf of the user; but this would also be possible with token auth. As a result if you use cookies, there are settings and ways to mitigate the additional risks posed with using that choice. If you use tokens, you do not have that option. That's just my 2 cents on this topic :-). If there are security advantages of tokens I'm missing; please let me know. I'm definitely open to learning something new. In any case, thank-you for re-opening the new feature request to get this into the product! It is very much appreciated! |
Thanks for the interesting write up, @securityvoid, and perhaps this isn't the place to continue a discussion on this, but if an XSS is found in your web app, then hijacking the Fetch/XML Request API used by the app and sending requests is still an equal threat, cookie or token, if you have an XSS vulnerability you should consider the entire account compromised on that domain. Sure, if you use an httpOnly cookie, the cookie cannot be stolen and sent to a third party domain for abuse, but the abuse can take place directly in the victim's browser. I think this highlights that token v. cookie, XSS is a severe threat for either, though I think XSS is a far better-understood problem compared to CSRF for example. In my use case, I'm using the Authorization header which also requires the -Credentials CORS rule, with a token. I could choose to store my JWT token in an httpOnly cookie, and while this means I cannot read it from my App, I still get some of the benefits of both. There is a lot of things to balance here, the argument isn't perfectly simple (for example, a non-httpOnly cookie is likely less secure than a token in localStorage). Developers can make mistakes about security, and they do quite often. But I don't think these concerns are a for or against justification of supporting -Credentials CORS on Azure. I don't believe it is the responsibility of Azure App Service/Function Apps to try and sandbox a developer and in doing so breaking perfectly secure means of client-server authorization (when done correctly). Lastly, I think it is important to say, that I am in no way a security professional. My work is in web development, so from a security point of view, someone should do their own research on top of my comments. |
I'm with @securityvoid on the discussion of cookie vs. token. I do feel you have a point @nevercast, however, I'm not sure XSS is better understood (though I could very well be wrong). I would argue more that XSS is more difficult to mitigate than CSRF especially with the implementation of the SameSite cookie attribute and therefore choose cookies as the transport mechanism for such data. In any case, I think both transport mechanisms should be supported by Azure Functions/App Service but I'm just running into this now and not sure where things stand internally. Update: Here's the exact error thrown by my browser even though the response is received in the "Network"
|
I've been affected by this too. I went down the path of removing all the CORS settings from the portal in order to use the CORS nuget packages in my service so that I could support .AllowCredentials(); as well as .SetIsOriginAllowedToAllowWildcardSubdomains();. This works well except that the .auth/* routes are not impacted by the custom CORS logic in my service. If the CORS settings in the portal supported wildcard subdomains as well as allow-credentials, I'd remove the custom logic from my API and let its routes as well as the .auth/* routes obtain their CORS settings from the portal configuration. |
Yes, sorry for the delay! We recently added support for Access-Control-Allow-Credentials. See our announcement here: https://azure.microsoft.com/en-us/blog/simplifying-security-for-serverless-and-web-apps-with-azure-functions-and-app-service/. Here is the note from the documentation:
|
Thanks for the update @cgillum! That's awesome. I understand reasoning behind not allowing Would you consider allowing This would still limit the scope of where the credentials could be shared, but enable multi-tenant service scenarios. Thanks! |
"To enable this in App Service, set What are you assuming that everybody is using? |
@pauldalyii would you mind opening a separate issue for your request? That will allow us to better track it. @TechInceptions this is the name of an ARM (Azure Resource Manager) property. See this tutorial for how to configure CORS in Azure App Service (works exactly the same for Functions): https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-rest-api#enable-cors Example CLI command: az resource update \
--name web \
--resource-group myResourceGroup \
--namespace Microsoft.Web \
--resource-type config \
--parent sites/<app_name> \
--set properties.cors.allowedOrigins="['http://localhost:5000']" \
--set properties.cors.supportCredentials=true This can also be done via the Azure Resource Explorer web interface. |
Cross origin http request (CORS) to Azure function does not return 'Access-Control-Allow-Credentials:true'. Is there a way to add custom headers?
Details
Error:
Response to preflight request doesn't pass access control check: Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. It must be 'true' to allow credentials. Origin 'http://localhost' is therefore not allowed access.
Mostly followed as per the following post except mine is CORS:
https://shellmonger.com/2016/02/12/using-azure-app-service-authentication-with-a-web-application/
Code
The text was updated successfully, but these errors were encountered: