For an Angular 1 app I am working on, cookie authentication is used. The problem is: when making OPTIONS calls, cookies are not sent and the server tries to redirect user to login again. Just wondering, whose "fault" is it? Server (Azure API Apps) or frontend? If frontend, how do I send cookies on OPTIONS call? I am using augular-resource and have configured it as below:
$httpProvider.defaults.withCredentials = true
The specification says:
Otherwise, make a preflight request. Fetch the request URL from origin source origin using referrer source as override referrer source with the manual redirect flag and the block cookies flag set, using the method OPTIONS, and with the following additional constraints … Exclude user credentials.
and also
The term user credentials for the purposes of this specification means cookies, HTTP authentication, and client-side SSL certificates that would be sent based on the user agent's previous interactions with the origin. Specifically it does not refer to proxy authentication or the Origin header.
So the client should not send cookies, and the server should be able to respond to the preflight request without requiring authentication to take place first.
Related
I read this blog What Happens If Your JWT Is Stolen?
The blog says that if one gets the JWT he/she can send requests to the server on behalf of the user.
My question is:- if JWT is stolen and my website don't allow request from unknown domain (due to same origin policy), will I be safe? Is there a way to override same origin policy by the hacker.
I know with XSS attack hacker can send the request from my domain. But here, just assume the hacker only has the JWT and there is no XSS attack.
These policies are a set of rules for browsers. Every HTTP client like curl or Postman can "override" these policies and send custom requests. With Postman you can configure the request as you want.
Same origin policies don't protect your server from attackers. They protect users of your web application from involuntary executing malicious code.
If attackers get a valid token they can send valid requests.
"Can same orgin policy prevent attack if jwt is stolen?" No, they can't.
Your website is a server that answers HTTP(S) requests. An HTTP request is just a bunch of text in a few IP packets. Anybody connected to the Internet can send any text they want to your server. The only information in there which is reliable is the origin and target IP adress of the server and the client connecting (as otherwise the packets won't arrive). Now to ensure that a certain request comes from a certain user, you share a secret with the user, which gets send with the request. When a request arrives, this secret is the only way to authenticate the user. If someone is able to steal or guess that secret, there is no way for the server to distinguish between the user and the attacker.
my website don't allow request from unknown domain
Not quite, the browser which the user uses to store the secret the server gave to the user, ensures that the secret gets only shared with your server. If you disable cross origin sharing, code of other websites the user visits with their webbrowser is unable to perform requests to your server in the background. Thus it prevents that other code uses the secret to perform an action on your server.
In conclusion CORS policies only help to keep secrets secret, if the secret is not secret anymore they won't help.
I am working on an app and would like to use http post requests to send data from client to server, on which the server uses the origin url from the client to allow to use our services, so my question is, can the http url from the client side be faked as a security threat to access my services, and if so, what other alternatives should i take?
An example is, if a client-side script running on a page from foo.com wants to request data from bar.com, in the request it must specify the header Origin: http://foo.com, and bar must respond with Access-Control-Allow-Origin: http://foo.com.
What is there to stop malicious code from the site roh.com from simply spoofing the header Origin: http://foo.com to request pages from bar?
What is there to stop malicious code from the site roh.com from simply
spoofing the header Origin
The browser is. CORS restrictions and headers only work in the browser and the browser is very strict about controlling them. This is specifically to prevent drive-by attacks from random scripts on random sites a user may unknowingly visit. It’s to protect the user of the browser.
However, absolutely nothing prevents a rogue server from sending an arbitrary HTTP request with any arbitrary headers to your server. I could do so from my command line using curl or such right now. These headers do not pose any sort of guarantee or protection for your server.
'on which the server uses the origin url from the client to allow to use our services'
The origin url can be faked very easily.
Add a login with a token to prevent that.
I have a tenant in Azure which hosts a number of apps. I'm using OpenID Connect for authorization. In the login.microsoft.com openid-configuration, an end_session_endpoint URL is supplied. This article explains how to send a sign-out request. This will end the session in Azure, but not on my client (an Angular2 SPA). To do this, I'm using angular-oauth2-oidc and the following code:
this.http.get('https://login.microsoftonline.com/TENANT_ID/oauth2/logout",')
.toPromise()
.then(function () {
this.oauthService.logOut();
}
);
The GET to login.microsoftonline.com will end the session on the server and the logOut() call will end the session locally. When I run this, I get the following error:
XMLHttpRequest cannot load https://login.microsoftonline.com/TENANT_ID/oauth2/logout. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:51518' is therefore not allowed access.
When I check the response from the login.microsoftonline.com GET, Access-Control-Allow-Origin is not one of the response headers. I'm very surprised it wouldn't have that header with * as the value. In any event, how can I address this? I see there is a CORS setting in App Services and I added my localhost (testing locally currently) to CORS for one of the apps in the tenant, but it's still not working.
Temporarily, I've added an API endpoint on my apps API that makes a call in C# to the login.microsoftonline.com URL, but it's annoying to have to do that. I'd like to do it all through javascript.
You need to redirect the browser to the URL. You can't call it over AJAX.
You must also redirect the user to the end_session_endpoint for sign-out.
Azure AD does not allow cross-domain calls on the login endpoints, and you can't change that.
You can redirect the user to:
https://login.microsoftonline.com/ccb87602-82bf-4f35-b7d2-aaaaaaaaaaaa/oauth2/logout?post_logout_redirect_uri=https%3a%2f%2fsitename.azurewebsites.net%2fHome%2fSignedOut
The post_logout_redirect_uri parameter allows you to specify where the user's browser should be redirected after log out. This way the user won't lose context. Do make sure to save up the user's work on your app's side before redirecting so you don't get angry users.
Due to a change in requirements I had to implement a Dropwizard web service for communicating with our SAP Business One instance. This works great so far.
Furthermore, I need to make sure only authenticated clients are allowed to access the API. For accomplishing this I am using a JWT which is generated by an other already existing web service. For communicating with both web services I am using the same Aurelia fetch client.
Despite of having set the credentials option to include as well as returning the same values for the Access-Control-Allow-Origin and Access-Control-Allow-Credentials headers (http://127.0.0.1:9000 and true) the cookies are only sent to the web service that generates the JWT and not to the Dropwizard web service.
Below you can see the code for initialising the fetch client.
configuration.useStandardConfiguration()
.withDefaults
({
credentials: "include",
headers:
{
"Content-Type": "application/json;charset=utf-8"
}
});
Next, the following screenshot is shown in the developer console of Firefox when communicating to the go web service. The Cookie header is sent as expected.
However, when accessing the resource on the Dropwizard web service the cookie header is not sent.
In the first case the request is done from http://127.0.0.1 to http://127.0.0.1.
In the second case, the request is done from http://127.0.0.1 to http://192.168.16.22:8090, isn't it? This is a CORS request
Maybe this is your issue: Cross domain POST request is not sending cookie Ajax Jquery
You cannot set or read cookies on CORS requests through JavaScript. Although CORS allows cross-origin requests, the cookies are still subject to the browser's same-origin policy, which means only pages from the same origin can read/write the cookie.
Hopefully this is simple to answer.
With a credentialed request in XHR2, which cookies are sent?
I've been following the MDN article on credentialed requests, and it shows that the cookie pageAccess=2 is sent with the request. However it doesn't explain where that cookie comes from, and why that cookie specifically is being sent. Is it simply that all cookies set by the page are sent in any credentialed request?
From the HTML5 Rocks page on CORS:
The .withCredentials property will include any cookies from the remote domain in the request, and it will also set any cookies from the remote domain.
I assume "any cookies" means "all cookies" (probably subject to a HTTPS-only flag on the cookie), since there is no mechanism to specify cookies with XHR2.
The cookies that get sent are the cookies that were set by the remote domain: if foo.com sends a request a credentialed request to bar.com, any cookies set by bar.com are sent. To put this in practical terms, suppose facebook.com has a CORS-aware API that requires you to be logged in to use. I've logged in to Facebook earlier in my browser session, but now I'm browsing foo.com, which is going to use Facebook's API on my behalf. foo.com asks th ebrowser to send a cross-domain request to facebook.com along with all my facebook.com cookies so Facebook knows who I am and that I've already authenticated to Facebook.