Can objects attached to requests in expressjs be tampered with? - javascript

In express.js we often attach objects to the req object in middleware, e.g. req.myObject. What prevents a user sending an http request that includes req.myObject already set to some value? For example, I could use req.myObject as part of authentication. Could a user set req.myObject = true when sending a request when it should really be false? Potentially an issue if req.myObject is set on some routes but not others but middleware that checks req.myObject is re-used across routes.

req is an object created by Express when a request is received. It's not something passed directly from client to the server, in fact it isn't even available to client.
A client can only relay information to the server in some limited ways - GET query, POST form data, or route paths which are attached to the req object by Express as req.query, req.body, and req.params respectively.
Anything else attached to the req object is out of scope of the client, at least directly.
Related question: Node.js request object documentation?

Related

Most secure way of sending data to DELETE request (req.params / req.query)

req.params property
We can call a DELETE request by using the req.params.id by gathering URL parameters for pointing to a record by its id for example to a backend route /users/delete/id/:id
req.query property
We can call a DELETE request by using req.query.id for extracting a JSON object and send it to a backend route /users/delete?id=2 to the controller/model for a record to be deleted like
{"id": "2"}
Question
What is the safest way for sending data to DELETE requests in terms of security issues that a user may take advantage of directly or indirectly considering we already have a safe login system?
If you were using GET or POST then the URL and body (if it wasn't JSON) might be vulnerable to CSRF attacks, but you can't trigger a DELETE request with cross-origin code (unless explicitly granted permission with a perflight CORS request).
You aren't, so it doesn't make any difference (at least from a security perspective).

Can res.locals be accessed by the api caller?

Currently working on an app where I authenticate and set the auth properties of a user in a middleware (to be used in the route). These auth properties are stored in res.locals.user.
I was wondering if the api caller could access and log the res.locals variable after the request is sent back. From what I've read it doesn't seem like the case but I want to be sure.
I've seen answers refer to the request/response lifecycle so any resource on that would also be greatly appreciated.
Thank you
res.locals.user is local to your server and local to the code processing that specific request. The sender of an incoming http request has no access to that data.
If you want to share anything in that with the sender of an incoming http request, then you can write your code to include something from there in the response you are sending back as the http response or if you are using an html template engine, then you can code the template to include anything you want from res.locals.user.
Server-side variables are only available on the server unless your code specifically sends them back to the client. And, things in the req or res object are only available to that specific request while it is being processed. Once the request processing is over and your code for processing the request is done, then those specific req and res objects will be garbage collected and they are not reachable from other requests.

ExpressJS: When authenticating, do I store the JWT token from the backend or the frontend?

I am inheriting a backend Express API and a front end React app.
Currently I am using cookie-parser in my POST /login API like so:
res.cookie('something', 'abc123', {
maxAge: COOKIE_MAX_AGE
});
on my front end app, there is a function for checking if an auth token exists:
export function isAuthCookiePresent() {
console.log('ALL COOKIES:', cookies.get());
return (
cookies.get(AUTH_COOKIE_NAME) && cookies.get(AUTH_COOKIE_NAME) !== null
);
}
And as expected I see { something: 'abc123' } in my console logs.
However, when I try logging in this using autodeployed branches in Vercel (https://vercel.com/), the cookie is missing.
I was under the impression that cookies were supposed to be set on the front end? But in the code the cookie is being set on the backend. And I don't see anything in the code that passes it to the front end. I thought I would find something on the front end like that would have a "upon successful login, execute cookies.set("x-auth-token", res.body.token)"
It's odd to me that it works locally at all. Would someone mind explaining how this works? I thought cookies were stored in the browser on the client side. But if that was true, why does cookie-parser even exist in express and why is it being used server side?
However, when I try logging in this using autodeployed branches in Vercel (https://vercel.com/), the cookie is missing.
This is because it appears you are setting the cookie server side, and as far as I know vercel only handles client side and will not let you use express.
I was under the impression that cookies were supposed to be set on the front end? But in the code the cookie is being set on the backend. And I don't see anything in the code that passes it to the front end. I thought I would find something on the front end like that would have a "upon successful login, execute cookies.set("x-auth-token", res.body.token)"
Cookies can actually be set through headers (Set-Cookie: <cookie-name>=<cookie-value>), which is what express's res.cookie does. MDN's article on the Set-Cookie header says:
The Set-Cookie HTTP response header is used to send a cookie from the server to the user agent, so the user agent can send it back to the server later. To send multiple cookies, multiple Set-Cookie headers should be sent in the same response.
It's odd to me that it works locally at all. Would someone mind explaining how this works? I thought cookies were stored in the browser on the client side. But if that was true, why does cookie-parser even exist in express and why is it being used server side?
Cookies are, in fact, stored client-side. They are accessible through client side javascript and backend with the cookie header. The cookie-parser module is needed to parse the name=value syntax sent by the Cookie header (Cookie - HTTP | MDN). It's being used server-side becuase validating cookies in the frontend can let any user give a false "true" value to your if statement that you use to validate cookies.
As an answer to the question: I recommend backend because JWTs have to be signed, and setting and signing them client-side will let anyone sign an arbitrary payload.

Do Node and Express validate certain request fields?

I am questioning whether it is required to validate fields like req.ip or req.path server-side.
It boils down to the question: Is it possible for the client to set something like .set('Remote-Addr', <Malicious JavaScript>) and it successfully being propagated to my Node or Express middleware?
Thanks for helping!
There is no way to validate source IP, particular when proxies are involved. In the proxy case, a chain of IP addresses is supposed to be put in http headers, but that can certainly be faked so what express thinks is the original IP cannot be trusted. It is likely accurate, but not guaranteed accurate.
req.path is entirely local and does not involve any client headers and is not subject to any client spoofing. It just comes from the actual HTTP request URL that arrives at your server. The only way it wouldn't be the same as the actual request URL is if you were using a mount point for routers in which case the mount point part of the path will have been removed by express. Or perhaps if your own middleware attempted to mess with it.

Get express encoded cookie as header value

Please see the communication description
Client --- POST /login (no cookie yet) ---> Node Server
Node Server ---> ‘set-cookie’ : ‘…’ -> Client (sets cookie and uses it for next requests)
How could I get encoded value of the cookie which is set as a set-cookie header before it is sent to the client on the first request ?
Express 3.x, cookieParser, expression-session and a mongo as a storage are used.
I tried:
to access req.cookies but is not populated on the first request
because client doesn't have a cookie yet.
res.getHeader('set-cookie') returns undefined perhaps because it
is set after express route handler is called by express-session.
At the server side how could I access either a set-cookie header in my handler or the cookie value in the response object even if request.cookie is empty ?
Almost a year later, but the reason you can't access is because express-session and other middlewares use a package called onHeaders which "Execute a listener when a response is about to write headers."
So you have to use it as well to modify the headers
var onHeaders = require('on-headers')
onHeaders(res, function(){
// knock yourself out
console.log(res.getHeader('set-cookie'));
});
Listeners are triggered in reverse order so for you to get the value this code (the listener) must be as soon as possible in your code.

Categories