In the code below:
https://github.com/jeyben/IOSLinkedInAPI/blob/master/IOSLinkedInAPI/LIALinkedInAuthorizationViewController.m
On lines 108-109, the author checks to see if the state parameter returned after the Oauth2.0 authentication is the same as the one passed in. Is that necessary? How would the state parameter change or be compromised in a webview?
RECOMMENDED. An opaque value used by the client to maintain
state between the request and callback. The authorization
server includes this value when redirecting the user-agent back
to the client. The parameter SHOULD be used for preventing
cross-site request forgery as described in Section 10.12.
From https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
However that said I do not think it is absolutely necessary as it would be a stretch for someone to try and do cross-site forgery due to the SSH provided by default from the OAuth 2.0 protocol. It is still a good security measure to take though as it is possible for someone to learn the way the requests are made, or a portion of them and try to fake things out. Also it is interesting how this changed on mobile but quite honestly it does not change all that much. Something that is important about the state being checked is that if the user was on a website that was hacked in the WebView then the mobile application could use that state to protect itself from accepting the hacked websites information as true. Anyways this is one of the many conversations that could be had about the state variable.
Hope this helps.
Anthony
Related
I am doing an api with Rails(api-only). Security is so importand for me. I got 2 question. 1-) I am keeping user's id in session[:authID], is it safe to use like this? 2-) Do i need CSRF protection for api-only? I'm using Next.js for client. If it is needed, how can i?
Q1. I am keeping user's id in session[:authID], is it safe to use like this?
ANS - It's not good practice to keep user ids in session as it reveals your table structure (not fully but still) like where your user table's primary key starts from. Rather than that you can use device-token-auth gem (details can be found here and here)
Q2. Do i need CSRF protection for api-only?
ANS - Cross-Site or Cross-Session Request Forgery requires a user to have a browser and another trusted website. This is not relevant for APIs, since they don't run in the browser and don't maintain any session. Therefore, you should disable CSRF for APIs. You can check here for details.
Hope the brief helps you.
Thank you
I had a look at Rails' ActionController::RequestForgeryProtection module and couldn't find anything related to using secrets. Basically, it uses secure PRNG as a one time pad, xors, computes Base64 and embeds into HTML (form, tags). I agree that it is impossible for an attacker to guess what a PRNG generates, but nevertheless I can generate (or forge if you like) a similar token, embed it into my "evil" form and submit. As far as understand Rails compares ( verifies) it on the backend. But I can't fully understand why it is secure. After all, I can generate my own token exactly like Rails does. Could someone clarify how the security is achieved?
You might misunderstand what this protects against, so let's first clarify what CSRF is, and what it is not. Sorry if this is not the point of confusion, might still be helpful for others, and we will get to the point afterwards.
Let's say you have an application that allows you to say transfer money with a POST request (do something that "changes state"), and uses cookie-based sessions. (Note that this is not the only case csrf might be possible, but by far the most common.) This application receives the request and performs the action. As an attacker, I can set up another application on a different domain, and get a user to visit my rogue application. It does not even have to look similar to the real one, it can be completely different, just having a user visit my rogue domain is enough. I as the attacker can then send a post to the victim application's domain, to the exact url with all the necessary parameters so that money gets transferred (the action will be performed). The victim user need not even know if this happens in xhr from javascript - or I can just properly post a form, the user gets redirected, but the harm is done.
This is affected by a few things, but the point is that cross-origin requests are not prevented by the same origin policy, only the response will not be available to the other domain - but in this case when server state changes in the victim application (like money gets transferred), the attacker might not care much about the response itself. All this needs is that the victim user that visits the attacker's page while still being logged in to the victim application. Cookies will be sent with the request regardless of the page the request is sent from, the only thing that counts is the destination domain (well, unless samesite is set for the cookie, but that's a different story).
Ok, so how does Rails (and similar synchronizer token solutions) prevent this? If you lok at lines 318 and 322 in the source, the token received from the user is compared to the one already stored in the session. When a user logs in, a random token is generated and stored for that particular user, for that particular session. Subsequent requests that change state (everything apart from GET) check if the token received from the client is the same that's stored in the session. If you (or an attcker) generate and send a new one, that will be different and the request will fail validation. An attacker on their own website cannot guess the correct token to send, so the attack above becomes impossible. An attacker on a different origin also cannot read the token of a user, because that is prevented by the same origin policy (the attacker can send a GET request to the victim app, but cannot read the response).
So to clarify, CSRF is not a protection against parameter tampering, which might have caused your confusion. In your own requests, if you know the token, you can change the request in any way, send any parameter, the CSRF token does not protect against this. It is against the attack outlined above.
Note that the description above is only scratching the surface, there is a lot of depth to CSRF protection, and Rails too does a little more, with some other frameworks doing a lot more to protect against less likely attacks.
We've got a hospital as a customer which wants to have an app developed. This app will probably make use of various ways of validation, of which OAuth2 is one. They have a list of requirements, of which one kind of puzzles me:
For every user session, the app needs to generate an unpredictable
"state parameter". The app needs to validate the "state value" for
every request which is sent to the redirect URL; the "state" needs to
be recorded with all authorization requests; and the "state value" has
to be validated with the access token which it receives.
Although they don't specifically mention it I guess this talks about OAuth. I've got some experience with OAuth2. I know what access tokens and refresh tokens are. But this story is above my head. What kind of "state parameter" and "state value" are they talking about?
Could anybody shed some light on this story?
This is about the state parameter that OAuth 2.0 has defined in the authorization request as a RECOMMENDED parameter (https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1) used to protected against cross-site request forgery and to correlate requests and responses in general:
state
RECOMMENDED. An opaque value used by the client to maintain
state between the request and callback. The authorization
server includes this value when redirecting the user-agent back
to the client. The parameter SHOULD be used for preventing
cross-site request forgery as described in Section 10.12.
I believe they chose to write an OAuth 2.0 client application requirement on their own words. The specification states that:
The client MUST implement CSRF protection for its redirection URI. This is typically accomplished by requiring any request sent to the redirection URI endpoint to include a value that binds the request to the user-agent's authenticated state (e.g., a hash of the session cookie used to authenticate the user-agent). The client SHOULD utilize the "state" request parameter to deliver this value to the authorization server when making an authorization request.
(emphasis mine, read the whole story in section 10.12 of the specification)
For a more step-by-step guided approach on how to use the state parameter you can refer to Using the State Parameter. This page mentions Auth0, but the process should be the same for any other OAuth 2.0 compliant server. Also note that the specific steps assume a browser-based application and as such store the unpredictable state parameter in Web storage. Other types of clients would use other stores, but the principle remains the same.
I have to implement a web site (MVC4/Single Page Application + knockout + Web.API) and I've been reading tons of articles and forums but I still can't figure out about some points in security/authentication and the way to go forward when securing the login page and the Web.API.
The site will run totally under SSL. Once the user logs on the first time, he/she will get an email with a link to confirm the register process. Password and a “salt” value will be stored encrypted in database, with no possibility to get password decrypted back. The API will be used just for this application.
I have some questions that I need to answer before to go any further:
Which method will be the best for my application in terms of security: Basic/ SimpleMembership? Any other possibilities?
The object Principal/IPrincipal is to be used just with Basic Authentication?
As far as I know, if I use SimpleMembership, because of the use of cookies, is this not breaking the RESTful paradigm? So if I build a REST Web.API, shouldn't I avoid to use SimpleMembership?
I was checking ThinkTecture.IdentityModel, with tokens. Is this a type of authentication like Basic, or Forms, or Auth, or it's something that can be added to the other authentication types?
Thank you.
Most likely this question will be closed as too localized. Even then, I will put in a few pointers. This is not an answer, but the comments section would be too small for this.
What method and how you authenticate is totally up to your subsystem. There is no one way that will work the best for everyone. A SPA is no different that any other application. You still will be giving access to certain resources based on authentication. That could be APIs, with a custom Authorization attribute, could be a header value, token based, who knows! Whatever you think is best.
I suggest you read more on this to understand how this works.
Use of cookies in no way states that it breaks REST. You will find ton of articles on this specific item itself. Cookies will be passed with your request, just the way you pass any specific information that the server needs in order for it to give you data. If sending cookies breaks REST, then sending parameters to your API should break REST too!
Now, a very common approach (and by no means the ONE AND ALL approach), is the use of a token based system for SPA. The reason though many, the easiest to explain would be that, your services (Web API or whatever) could be hosted separately and your client is working as CORS client. In which case, you authenticate in whatever form you choose, create a secure token and send it back to the client and every resource that needs an authenticated user, is checked against the token. The token will be sent as part of your header with every request. No token would result in a simple 401 (Unauthorized) or a invalid token could result in a 403 (Forbidden).
No one says an SPA needs to be all static HTML, with data binding, it could as well be your MVC site returning partials being loaded (something I have done in the past). As far as working with just HTML and JS (Durandal specifically), there are ways to secure even the client app. Ultimately, lock down the data from the server and route the client to the login screen the moment you receive a 401/403.
If your concern is more in the terms of XSS or request forging, there are ways to prevent that even with just HTML and JS (though not as easy as dropping anti-forgery token with MVC).
My two cents.
If you do "direct" authentication - meaning you can validate the passwords directly - you can use Basic Authentication.
I wrote about it here:
http://leastprivilege.com/2013/04/22/web-api-security-basic-authentication-with-thinktecture-identitymodel-authenticationhandler/
In addition you can consider using session tokens to get rid of the password on the client:
http://leastprivilege.com/2012/06/19/session-token-support-for-asp-net-web-api/
I want the users of my website to use Dropbox to store their files. I will be using OAuth 1.0 for this purpose. I can't use OAuth 2.0 as Dropbox only supports OAuth 1.0.
If I completely implement the authorization and file retrieval/storage at the server-side it will cost me a lot of bandwidth for the file storage/retrieval. I thought of completely shifting this to JavaScript for saving the bandwidth. However, in that case the consumer secret will be exposed to the world causing security issues.
To prevent the consumer secret exposure I have thought of performing the request_token, authorize and access_token phases at the server-side. Then pass the necessary parameters to JavaScript which will then handle storage and retrieval of files.
Is this a good idea? Or can you see any problems in it?
I think it makes perfect sense.
As long as you make absolutely sure that none of your keys/secrets appear anywhere in your JavaScript code, and make absolutely sure to only persist keys/secrets for the duration of the session you should be safe.
EDIT: You can of course persist the access token to Dropbox server side beyond the scope of the session. That way you can reuse the same access token across several sessions.
I've encountered the same issue, the only thing is if the endpoint, in your case Dropbox, supports CORS, aka returns ACCESS_CONTROL_ALLOW_ORIGIN permitting the browser to post to it. Otherwise you could post via a FORM but i dont think you'll be able to read the response.
FYI i've wrapped this into a clientside library, take a look at http://adodson.com/hello.js/ and serverside OAuth1 shim https://npmjs.org/package/oauth-shim