I've been looking into the CSRF vulnerability and how to fix it in .NET application.
Based on my research here is the pseudo algorithm I need to do:
Check request for CSRF token in the request cookie, if it is not there, create one
on the server.
Once the token is created, add the token to the
response cookie to send back to client. Client sends this CSRF
token for all future request cookie.
When server receives a request and it
sees the CSRF cookie, the server validates against its stored CSRF
token value.
When it matches, then business as usual, if the values
don't match then stop the request.
My question is in step #3, I'm using ASP .NET web form; I can store this CSRF token in either Session or a ViewState.
I don't want to use ViewState because all the pages in our application have to support EnableViewState="true". If not, the ViewState content is wiped out on each and every post-back call.
Can I use Session in this situation? Does it compromise the fix if I use Session instead of ViewState?
So you're going for the Synchronizer token pattern (STP) technique, using a single token per user session.
There's no problem in using the ASP .NET session storage for saving CSRF tokens, based on the trivial assumption that the attacker has no access to it, this doesn't compromise your solution in any way. Nonetheless, as pointed out in Gabor Lengye's comment, using cookies to send the CSRF token to the server is flawed, embed the token in an HTML form instead, or use the Cookie-to-header token technique.
That said, I suggest you take a look at the AntiForgery Class which has built-in token generation, HTML embedding and validation methods. Security wise it's never a good idea to implement your own solution, instead go for established, trusted solutions.
Also make sure to use HTTPS to prevent your tokens from being hijacked in a Sniffing attack
Related
I have been asked to implement integration with a SAML 2.0 IdP for user Authentication purposes. I have never worked with any federated authorization processes so this is all new to me so please forgive if I am asking a stupid question but here it goes.
For My needs all I want is to send a SAMLP Authentication request. If I get a response that says the user is valid I will give them access to my system which will have a user id that matches what is returned. From that point on all authorization is to be performed by my system and I do not need to send a token with each request to the SAML IdP. After they log in I am done with the IdP.
Many of the questions and examples I see on here and other sites include adding extensive libraries to my project. When I look at them and the documentation around them they all seem to want to either perform the authentication with every request through an IIS Module or through integration with the MVC routing mechanism.
So now to my question. Can't I just create the XML myself and stick it on the the querystring as the SAMLRequest value? Then parse the response XML that comes back for the values I need? If this is a valid way of doing it does anyone have some example code that does this?
Any help would be greatly appreciated
The flow that you describe is how things are normally done: One SAML2 request to the Idp to authenticate the user, and then setting a session cookie for all subsequent requests.
Don't create this yourself unless you want to investigate substantial time to understand SAML2 and XML signature validation rules. They are complex and most custom implementations get it wrong, resulting in compromised security.
My own library, Kentor.AuthServices works the way you want. Even though it comes either as an httpmodule, an mvc controller or an owin middleware, it only interfers with the first requests that make up the actual sign in. All subsequent requests are just passed through and the session cookie mechanism handles the session authentication.
My application has an API part and a website-part.
On the website, the user can log in and gets a JWT bearer token from the API.
My question now is:
Where should I store that token?
Some say, store it in Cookie (while others say "don't, because CSRF"), some say HTML5 Web Storage, others say use Session (while other say, "don't use Sessions in ASP Net Core") and I saw an article where someone stored the auth-token in a database (??).
So, what's now the correct place?
MVC-web application with many controllers and a lot of views
If you have to use the token to authenticate every request to your MVC app I think the best option is store it in session cookie because, if not, the web browser are not going to send the token authomaticaly in every request and it will be a pain in the ass.
Now, to secure the cookie and requests:
Make session cookie (no expiring date)
Restrict the scope of the cookie all you can (domain and path).
Set Secure and HttpOnly attribures.
Set SameSite attribute.
If browser does not support SameSite use an anti-CSRF token.
Set restrictive X-Frame-Options.
Do not forget to verify the JWT signature on your server on every request.
Encrypt the JWT token to prevent leaking information that could lead to social engineering.
I have a API mobile service that handles users' login and verification. If a user is verified then it produces an authentication token. On my end I have a Web client that receives that token and uses it to call different Api controllers. How should I go about keeping a user logged in status constant?
Can I store the token on a cookie? would it be exposed to abuse if I do so? would a session work better? What is the best way to handle this issue? Sorry for the noob question, but I have never done this type of setup before.
The token can be stored relatively securely on the client as a cookie. Here's an example using Forms Authentication. It can be made even more secure by requiring SSL.
You can also consider using HTML 5 local storage like this:
http://www.princesspolymath.com/princess_polymath/?p=396
...which can be more efficient, as you manually use the token when making AJAX calls that require it instead of sending the cookie on every single request.
I have an ASP MVC4 web site. Originally, most of the content was served via controllers as one would expect. I have moved the data storage from SQL Server to MongoDB. I have also added a lot of ajax to update data client side, without a full refresh. This is working fine, but my controllers now have lots of methods that take json and return json. I was able to build a Node.js server that hits the database and exposes exactly the same functionality, without lots of going to and from C#.
My javascript client-side is now calling a Node.js REST API, this works great. My 'secure' code (like adding a new user) hits the same REST API from the server side.
My question is this: How can I handle security properly with this? I have three scenarios:
GET api/messages: No need for security, I want to expose my site's messages to anyone who is interested via a Json REST API.
GET api/my/messages: I need to allow access to this only if the user is logged in (it gets the user's messages).
POST api/users: This is a function that should only be called from the server, and nothing else should be able to use it.
As the user is already logging in to my ASP website, how can I use their logged in credentials to authenticate them with my REST service? While the user is logged in, the pages client side will hit it regularly for updates.
Is there any sensible/standard way to do this? The core idea is that the client side code uses a REST API that is at least partially open to the public, and that in fact that API offers all of my business logic - only parts of it (like creating a user) are locked down to super-admins only.
Thanks in advance!
Create two authentication middleware handlers. One you add to all your "my" routes and another which you add to your POST routes.
The "my" authenticator takes the asp.net auth cookie that is present in the request and makes a http call to your asp.net mvc site with it.
You'll need an action which either returns a 401 if the cookie is invalid otherwise it returns some info about that user's permissions perhaps.
If the request into node doesn't have a cookie, return a 401 again.
In addition, to prevent excessive calls to your mvc site to check the cookie, you could use the cookiesession middleware to set a cookie on the client with a flag of authenticated. That will result in 2 cookies for your client, but that shouldn't be an issue. Just make the node one expire before the aspx one.
The POST authenticator middleware can use any shared secret you like between your node and mvc server. e.g. a special header in the request.
If the user is required to login you can use [Authorize] on your controller actions. Autorization will be handled like any other webrequest.
Furthermore you might consider to add a key to your api requests which you can provide in the initial page load. A autorized user will have a GUID which he will sent with the api call. You can check if this key was issued by your app to a valid user.
As you said all the secure calls already go through your MVC server code which in turn calls the Node.js code, am I right? Basically you need a way to block calls to this Node.js from other clients that are not your MVC code.
Thinking out loud, these are the ideas that pop into my mind:
Use SSL only between MVC and Node. You can set up client and server certificates so that the Node code will only respond after authentication (I don't know how Node handles SSL so you will need some documentation here
If you want, the Node server could also check the call origin and so you can filter based on IP and only allow IPs where your MVC code is sitting
Use an encrypted authentication token on the secure methods on the Node code. Again I'm not really a Node expert but I can imagine it has ways of decrypting a token, or you can simply base it on a random number with a common seed... If noone has access to your server code ideally noone should be able to guess this token. Again, SSL will help against traffic sniffing
I am quite sure that people will come up with other ideas. For me, the most basic thing is anyway ensure that the secure methods are only accessible through an SSL connection and on this connection you can exchange all the info (token, passwords, etc.) you desire.
is there any security issue realated to leaving ASP.NET Session ID value on html hidden field?
Its in order to work around a problem when using uploadify, which is based on flash to work and have known problems (this link, look for 'STEP 6') in sending the right cookies to the server through ajax request so I'm having problems when trying to authenticate against my session based authentication process.
By puuting SessionId value in a hidden field it allows me to grab the right valu and after some code on global.asax sucefully work around this problem.
Am I doing something totally wrong? Btw, im using 128bit ssl encryption.
Thank you!!!
EDIT:
The point is, if session ids are alaways present in https post/request, whats the difference if I store them as a post argument or as cookie value beign sent within an http req.? If someone that intercepts my req and get my SessionId can easily bypass security, whats the best way to implement autenthication???
Yes anyone getting hold of the session id can access that user's session. This is a big security risk, made worse by the fact many people wrongly use it for custom authentication (which you appear to be doing).
By writing it into the page your making it easier to steal via XSS techniques and others. Session is not at all secure, that's why .NET has it's own authentication scheme using encryption and entirely decoupled from session.
I can send you a link, set your cookie, wait for you to login, share the same cookie and access all your details as if I were you. Session Id is a random token there is no encryption at all.
The way to implement authentication is via the .NET authentication cookie, and optionally the use of MembershipProvider. This creates an encrypted cookie based on the server unique machine key. Only this server can decrypt the cookie in order to authenticate the user. If someone forces a session ID on you, or steals it, they still can't authenticate as you.
Of course someone could also steal your authentication cookie, but there's an option to only serve the cookie over SSL to protect against this, and it can't be forced on you due to encryption.
It does open up a security hole, but it's no different than using cookieless sessions which stores the session ID in the URL.
Using HTTPS helps.