Is Session checking for login necessary for POST request too? - node.js

Im beginner in login system, i use session for it. I have implemented the login system with session checking, but only for GET Request because it can be accessed directly in browser address bar so i cannot be accessed directly in address bar before login.
My question is, is necessary to implement the session checking in POST Request too? Or just implement it into GET Request that can be accessed in address bar directly?

It is not necessary. id depend on the use case. If your frontend is different is in some other language like react, angular etc... then it will be directly handle by the state/browser storage.
Still if you need to implement through node side then express-session is a good option to choose. You can use the JWT token for calling the api through the request. On logout case just expire the tokens

Related

Storing Express session Id in React

I'm having a problem of understanding the steps for authentication using Express session(backend) + React(frontend)..
When a user logs in the server set up a session cookie object with the user id and this way it can identify if the user is logged in or not...
What about the client side? when user logs in and and I generate a token I send it back to the react app and save it in localStorage to use it for every request I make later? I heard that this is not secured.... So I ask you how should I implement that? How can I save the token I get from the server to use it when I make requests later?
One way I can think of is making another get request on server side which returns the session.userId so I can see if thats true then the user is logged in... I'm just trying to figure out how to implement that
thanks!
Browsers implement cookie storage, you don't have to do anything explicit on the client side to maintain the express session. When authentication first happens the server sends a header to the client instructing it to store a cookie and the browser will hold onto that cookie and send it back on all subsequent requests. None of this needs to happen in client scripts (i.e. your javascript code).
You don't need to store cookies in local storage, usually you should not and session cookies will be "httponly", meaning the client scripts are forbidden from accessing them. This is to mitigate the possibility of session stealing in the case of XSS.

pass node express session to phantomjs open

My app has a route /project/:id which is protected by an auth middleware that uses passport to allow visitors to authenticate with their slack account.
I'd like to use phantomJS to render /project/:id to pdf. I thought the best way to do this would be to create a route /print/:id (same auth middleware) which creates a phantom instance and uses the open method to request /project/:id.
When /print/:id is requested, the browser session is detected as normal, that's fine. But when phantom does the internal request, it's session is not authorised. The best option would appear to be copying the browser session onto the phantom session.
I note that phantom's open method allows a settings parameter, but I have no idea what properties on the request object would need to be passed in to that settings parameter.
I note there's a similar question regarding cookies but there's no clear solution there and if I understand correctly, recreating the cookie might be more appropriate for accessing a third party, when you don't have access to the session itself.
I infer from the question that you are the developer of the application and have PhantomJS on the same server as this project.
If that's true, the simplest and very reliable solution would be to check if a request for /project/:id was local plus if useragent is PhantomJS's and disable auth middleware that time.

How to implement CSRF protection for GET requests in Express?

How do I implement CSRF protection using built-in Express middleware for HTTP GET requests?
For instance, user logout often made via GET request and actually change state of web application so it should be protected against CSRF.
Unfortunately, CSRF middleware ignores HTTP GET and doesn't export helpers to manually check token.
BTW, they now expose the way of explicitly setting which methods to ignore
app.use(csurf({ignoreMethods: ['HEAD', 'OPTIONS']}))
You could create a custom fork of the Connect CSRF middleware that would not ignore GET requests. The line that does so is here: https://github.com/senchalabs/connect/blob/master/lib/middleware/csrf.js#L76
However, don't do it. GET requests are safe and idempotent: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
In other words, no one is worried that a malicious web script might log them out from a site. The worry is that it could post spam in your name or transfer money out of your bank account. That's what you need CSRF to protect against. Lots more info here: http://en.wikipedia.org/wiki/Csrf

How to set up XSRF protection in web apps?

I am a web application newbie. I know that XSRF protection questions have been asked in SO but the questions have been specific to a particular language (RoR/Python for example) or a library (jQuery). I would like to know how I can implement XSRF protection in my web application.
My understanding is that XSRF protection relies to using a unique random token that must be authenticated when a HTTP request is made. I have the following questions:
When should the authentication token be initialized? Should it be set on page load (i.e. GET request)?
Where should the token be initialized? Should they be set in input fields, cookies or request headers? How is this random value generated? How do I persist this value in order to be used for comparison?
When should the authentication token be verified? How does I compare authentication tokens? How do I compare these tokens with the token that I have persisted?
Is there a difference in the set up for a synchronous form request versus an AJAX request?
When should the authentication token be initialized?
The first time, during a session, that the user arrives at a page containing any form that you wish to protect from CSRF attacks.
Should it be set on page load (i.e. GET request)?
It should be embedded in the form when the HTML for it is generated.
Should they be set in input fields, cookies or request headers?
Hidden inputs.
Using a cookie would miss the point (which is that it comes from the page and does not persist in the browser). Extra headers can only work when using XHR, use a general approach.
How is this random value generated?
With a random number generator
How do I persist this value in order to be used for comparison?
Sessions
When should the authentication token be verified?
As part of the authorization step.
How does I compare authentication tokens? How do I compare these tokens with the token that I have persisted?
if ( $request->paramaters->{csrf} eq $session->data->{csrf} )
Is there a difference in the set up for a synchronous form request versus an AJAX request?
No. You still have a session and you still have a piece of the POST data being the token.
I'm not going to talk about a specific solution that you must follow as there are many, I'll talk about the main idea instead and you could implement it however you want.
The key idea to prevent XSRF is to store a random token in a place where code from other domains cannot access (such as a cookie). You could generate this token on server side and instruct the browser to store it locally for the entire session. (don't need to persist anything on server side)
Whenever you perform a request, send:
the token in your storage (if you use cookie, the browser will send it automatically).
the same token as the stored one in your request (whether as a header or in body using hidden field depending on how server code gets it)
On server side, the server will check for a match.
A sample code in jquery (with jquery cookie plugin):
$.ajax({
url:"someurl",
data:{token:$.cookie('token')}
});
The ability to read the cookie proves that this is from your domain, not external domains
There are various ways to implement this mechanism (don't need to stick to a specific solution) as long as they stick the the main idea:
Storing a secret token on browser in a place code from other domains cannot read it.
Send the secret token and the same token from browser to your server. The ability to send that same token proves that this is not a XSRF request.
How do I persist this value in order to be used for comparison?
We could store it as a cookie or as a session variable. Personally, I prefer cookie because:
Reduce memory consumption on server side.
We don't need to include that token in every generated HTML file in order for the browser to send it back.
Is there a difference in the set up for a synchronous form request
versus an AJAX request?
No, as long as you could prove this is not a XSRF request by sending the same token in the request. It does not matter where token is (a hidden field, a custom header,..). In case of Form, people usually send it as a hidden field.

How to enforce same origin policy in Express.js?

Suppose I have the following URL route:
app.post('upvote', function(req, res) {
// make a database a call to increase vote count
});
What can I do to prevent others from opening up a console and sending AJAX POST request on www.mysite.com/upvote? I'd like it so that only www.mysite.com is allowed to make that POST request and no one else.
What can I do to prevent others from opening up a console and sending AJAX POST request
Who is "others"?
If others==users of the site... there is nothing you can do to stop them sending whatever requests they like, using the JavaScript console or any other means. You can't trust the client, so you have to have server-side authorisation: requiring that the user be logged into an account, and registering that the account has upvoted so can't vote again.
If others==admins of other sites (by serving script to their users that causes submissions to your site)... it isn't possible for JavaScript on another site to cause an AJAX POST request, or at least not unless you deliberately opt into that using CORS. But it's quite possible for them to cause a POST by simply creating a <form> pointing to your address and submitting it.
This is a classic Cross Site Request Forgery problem. The widely-accepted solution to XSRF issues is to include a secret token as a parameter in each POST (form or AJAX) submission. That secret token is associated with the logged-in state of the user, either by being stored in the server-side session, or replicated in a client-side cookie. Either way an attacker from another site isn't capable of getting hold of a token that is valid for the logged-in user, so they can't fake the request.
You need XSRF protection on all actions that have a direct effect, whether AJAX or form-based POSTs.
I agree with bobince. others is a very general term.
If others belong to other sites (malicious sites on net).
express has csrf middleware to protect from Cross Site Request
Forgery. You can use it to prevent such a scenario. See the API docs
here.
If others are users of your own site
then that is an authentication issue. Every request must be
checked before serving / executing it. You should implement a user
authentication to prevent this situation. I use passport, and
ensure that user is authenticated before I actually run app.post
handler.

Resources