Rails API Session Security and CSRF - ruby-on-rails

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

Related

rails - What is the biggest security risk in intentionally disabling a CSRF check on the 'create' action?

I have a fully working product on Rails 5. I now wish to make a Chrome extension, using which users can create an 'Article'.
However, requests from my Chrome extension will be treated as Cross Site by my rails app. Hence, I was thinking of not doing the CSRF check at all on just my create action.
What is the biggest security risk associated with this? I understand after this, anyone will be able to make POST request to my server that creates a new article - however, this is not a damaging action like update, or worse, delete.
The Rails guide states that,
CSRF attack method works by including malicious code or a link in a
page that accesses a web application that the user is believed to have
authenticated. If the session for that web application has not timed
out, an attacker may execute unauthorized commands.
If a CSRF token is a valid one, it is a kind of assurance that the user session has not been hijacked and the request has been made with the user consent.
For more info, I recommend you to refer the Rails guide http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf

Are session, stored in cookies, safe enough to store important information like id of user?

I'm doing simple authentication. When the user had login, app stored user's id in session[:user_id]. I heard about sessions' encryption, but is it okay? I mean, can user change :user_id in his session to admin's id, for example?
The short answer is no, it's not a good idea.
Especially if people are accessing your site from a public location, or even worse, a public computer. The reason it's 'no' is because of Session Hijacking. You can read about Session Hijacking in section 2.3 of the Ruby on Rails security guide. You can get around this somewhat by using https (TLS/SSL). Refer to the guide for more information.
You could use OAuth or OpenID.
These options might be too hard and too long winded for your purpose.
There is a shortcut; to use an already existing well-known authentication and authorization framework like "Sign in With Google", which is essentially OAuth2 but you can use the tokens to give users with a google account access to your system. Here is the Ruby quick start guide.
Regarding encrypting session data, while a nice idea, it's still open for attack unfortunately. Definitely better than just storing id's in the sesssion data. Over at Information Security StackExchange you'll find some good commentary.
Do you need to encrypt session data?
...
... You don't need to encrypt it. At most, encryption is a form of
obfuscation. You're putting the key on the same system as the data, so
it can always be found and extracted.
ref: https://security.stackexchange.com/questions/18880/do-you-need-to-encrypt-session-data

Digging into Oauth2.0 authorization code

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

How should I secure my SPA and Web.API?

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/

CSRF Token in Django and iOS

So I am trying to understand what to do here... I am doing a POST call to my Django server from iOS and I keep getting the 403 Error (Invalid CSRF Token). I am thinking about implementing a function that will return me the token (you will need to be logged in to access that function), and then add the token to my POST call.
Now... I don't understand what is the point of doing that? If I use TastyPie and the required login is APIKey... should I just exempt the csrf check?
To make sure I understand things right... is the CSRF generated per user session? Therefore, if I don't use Cookies, CSRF is not necessary?
How do people usually use their Django Servers with an iOS and making such POST calls?
Thanks!
You're right: if you don't use cookies to manage your sessions, you don't need CSRF protection. CSRF works because session cookies are automatically attached to the request; access tokens are not.
I personally found this article very useful. It is definitely worth reading, and would probably answer a lot of your questions.
As for tastypie: it allows SessionAuthentication. If you allow session authentication in tastypie, I suggest you look into a way to protect your users against CSRF. For other authentication schemes this doesn't seem necessary. As far as I know, Dmitry is right about tastypie disabling CSRF by default, which means it is strange that you get that 403 Error. Perhaps there is something else going on. Try wrapping the view in #csrf_exempt.
As for CSRF tokens, they are also called session independent nonces. They are meant to be permanent, but you probably know that is impossible for cookies. Anyway, this means that CSRF cookies persist through sessions.
You're right, CSRF does not make much sense in this case, because its purpose is to protect users from data tampering in a browser.
I believe that Tastypie disables CSRF on its views by default.

Resources