Express module cookie-session not including SameSite and Secure in Response Set-Cookie - setcookie

Seen this before here, but I've seen no real resolution. The server's Node Express express-session module OR cookie-session module sends back a Session Cookie, but as I had not coded in the SameSite/Secure attributes, they are not there and do the client on a subsequent POST to the server fails as Not Logged In, with a 403. As expected.
First, my client logs in to the server successfully:
Here is the corresponding server code, using express-session:
Which produced a Session Cookie via the Set-Cookie. NOTICE the SameSite='none' and Secure=true attributes were not included, and as expected, not there.
Now, I have added the sameSite and secure attributes to the session object and run the Login again.
Lets look at the Response Headers returned from this Login, with the attributes added to the session object. Not only do we not see the attributes on the Set-Cookie Response Header, but there is NO cookie returned!
It appears that when these 2 attributes are added to the session object in either express-session or cookie-session that the result is no cookie is returned. The meaning being that a subsequent POST to the server will return a 403, User Not Logged In.
I'm really stumped. I've spent a LOT of time on this! Thank you for ideas and help.

You seem to be misusing the cookie-session middleware. The cookieSession function takes an JavaScript object but the documentation doesn't mention any cookie field in that object.
Anything specified in a cookie field is ignored by the middleware and has no effect on the resulting cookie; the only reason your cookie ended up being flagged HttpOnly is that it's the middleware's default behaviour.
Instead, all the cookie attributes should be specified in a "flat" object, like so:
app.use(cookieSession({
name: 'session',
secret: secret,
domain: 'chicagomegashop.com',
sameSite: 'none',
secure: true,
httpOnly: true
}));
However, you have another issue. If I'm interpreting your screenshots correctly, you seem to attempt to set a cookie with a Domain attribute of chicagomegashop.com in a response from https://paylivepmt.com. That cannot work; browsers will ignore such a Set-Cookie response header:
The user agent will reject cookies unless the Domain attribute specifies a scope for the cookie that would include the origin server.

Related

How to access cookies inside a Cypress request to a different domain?

I'm trying to authenticate at a different domain as part of a Cypress test using cy.request. The authentication request needs to contain the value of the XSRF-TOKEN cookie as a header. This is easily solved when on the same baseURL as the authentication domain: visit the domain, read the cookie via cy.getCookie, then make the request. Since cypress does not allow visiting multiple domains in a single test a different workflow is needed.
My solution right now is to replace the initial cy.visit with a cy.reqeuest (this sets the cookie as verified by looking at the request headers of the second request). However, I can't figure out how to read this cookie before I make the second authentication request. cy.getCookies() is empty, and document.cookie is empty. The response of the cy.request only contains a "set-cookie" header the first time, and I can't figure out how to read the default headers of the cy.request since cy.intercept does not work with cy.request.
Sketch of my attempt (where c.value is null):
cy.request({url: "https://notbaseurl/login"}).then(res => {
cy.getCookie("XSRF-TOKEN").then(c => {
cy.request({url: "https://notbaseurl/auth", method: "POST", headers: {"X-XSRF-TOKEN": c.value}})
})
})
This is not currently possible. See https://github.com/cypress-io/cypress/issues/8956

Why can't I see cookie parameters after I log in?

I'm working on making a Symfony website secure. I have taken a look at this page: How to set secure and httponly attributes on Symfony 4 session
and applied the suggested change into framework.yaml:
session:
handler_id: ~
cookie_secure: true
cookie_httponly: true
When I log in, in the network tab I see three instances of Set-Cookie. The first is a cookie removal, having secure and HttpOnly attributes. The second is a cookie creation, where the cookie identifier has the secure and HttpOnly attributes. The third is setting some parameters in an HTTP-encoded manner, this one also has the secure and HttpOnly attributes. So far so good. However, when I go to any page, I have a Cookie attribute among the Request Headers which has the same identifier as the one which was created earlier, but the secure and HttpOnly attributes are not specified.
So, when I log in and the cookie is created I have the attributes I expect, but later, on visiting separate pages I no longer see them. Why is the secure and HttpOnly attribute not specified on later, after-login Request Headers? Did I miss something?
The security attributes are set by the server in the Response headers and the browser uses them to determine if it has to send the cookie along in the Request, but it never sends the attributes themselves, just the cookie value. If you inspect an ajax or unsecure request the cookie header should not appear in the request at all.
You can see some examples in the RFC6265.

When should I really set "Access-Control-Allow-Credentials" to "true" in my response headers?

MDN says, when the credentials like cookies, authorisation header or TLS client certificates has to be exchanged between sites Access-Control-Allow-Crendentials has to be set to true.
Consider two sites A - https://example1.xyz.com and another one is B- https://example2.xyz.com. Now I have to make a http Get request from A to B. When I request B from A I am getting,
"No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://example1.xyz.com' is therefore not allowed
access."
So, I'm adding the following response headers in B
response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
This resolves the same origin error and I'm able to request to B. When and why should I set
response.setHeader("Access-Control-Allow-Credentials", "true");
When I googled to resolve this same-origin error, most of them recommended using both headers. I'm not clear about using the second one Access-Control-Allow-Credentials.
When should I use both?
Why should I set Access-Control-Allow-Origin to origin obtained from request header rather than wildcard *?
Please quote me an example to understand it better.
Allow-Credentials would be needed if you want the request to also be able to send cookies. If you needed to authorize the incoming request, based off a session ID cookie would be a common reason.
Setting a wildcard allows any site to make requests to your endpoint. Setting allow to origin is common if the request matches a whitelist you've defined. Some browsers will cache the allow response, and if you requested the same content from another domain as well, this could cause the request to be denied.
Setting Access-Control-Allow-Credentials: true actually has two effects:
Causes the browser to actually allow your frontend JavaScript code to access the response if credentials are included
Causes any Set-Cookie response header to actually have the effect of setting a cookie (the Set-Cookie response header is otherwise ignored)
Those effects combine with the effect that setting XMLHttpRequest.withCredentials or credentials: 'include' (Fetch API) have of causing credentials (HTTP cookies, TLS client certificates, and authentication entries) to actually be included as part of the request.
https://fetch.spec.whatwg.org/#example-cors-with-credentials has a good example.
Why should I set Access-Control-Allow-Origin to origin obtained from request header rather than wildcard *?
You shouldn’t unless you’re very certain what you’re doing.
It’s actually safe to do if:
The resource for which you’re setting the response headers that way is a public site or API endpoint intended to be accessible by everyone, and
You’re just not setting cookies that could enable an attacker to get access to sensitive information or confidential data.
For example, if your server code is just setting cookies just for the purpose of saving application state or session state as a convenience to your users, then there’s no risk in taking the value of the Origin request header and reflecting/echoing it back in the Access-Control-Allow-Origin value while also sending the Access-Control-Allow-Credentials: true response header.
On the other hand, if the cookies you’re setting expose sensitive information or confidential data, then unless you’re really certain you have things otherwise locked down (somehow…) you really want to avoid reflecting the Origin back in the Access-Control-Allow-Origin value (without checking it on the server side) while also sending Access-Control-Allow-Credentials: true.
If you do that, you’re potentially exposing sensitive information or confidential data in way that could allow malicious attackers to get to it. For an explanation of the risks, read the following:
https://web-in-security.blogspot.jp/2017/07/cors-misconfigurations-on-large-scale.html
http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
And if the resource you’re sending the CORS headers for is not a public site or API endpoint intended to be accessible by everyone but is instead inside an intranet or otherwise behind some IP-address-restricted firewall, then you definitely really want to avoid combining Access-Control-Allow-Origin-reflects-Origin and Access-Control-Allow-Credentials: true. (In the intranet case you almost always want to only be allowing specific hardcoded/whitelisted origins.)

Are my cookies really HTTP only? Flag is absent in Cookie request header

Ive made some configurations to (finally) have my cookies set on HTTP only.
"Seem" to work.
Ive tried them with postman and I have the following:
When I hit the login page:
On the cookies section, my cookie with name JSESSIONID appears to be HTTP only (it has the check)
When I enter to the logged area , the same result...
The headers dont give me more details.
Then,
I check it with google chrome. I open the developers toolbar.
I load the login page.
At the headers on the response headers I get
Set-Cookie: JSESSIONID=434434..... HttpOnly
So, its fine (I guess).
Then I reload the page (or sign in).
Then the problem:
No response headers received.
The Request Headers brings my cookie (with the same ID at then the previous one) without the httponly, host info or any other cookie value I set before.
At the cookies tab I get Request Cookies only and no Response cookie.
And the request cookie is non http-only
At my resources tab, the Cookie is there, as HTTP only and with the previous values I set.
My question now is... Is it a really http-only cookie? Or my configuration is not properly set?
Should I always get the response cookie or the request cookie should be always http-only (In case I am trying to set it as http-only) or is this behavior normal (or at least accepted) ?
When I try to print my cookie with Javascript at both scenarios I get a null as response (what makes me think then it is correct).
Ideas?
Client doesn't send cookie attributes other than name and value back to server.
See also RFC6265 section 4.2.2 (emphasis mine).
4.2.2. Semantics
Each cookie-pair represents a cookie stored by the user agent. The
cookie-pair contains the cookie-name and cookie-value the user agent
received in the Set-Cookie header.
Notice that the cookie attributes are not returned. In particular,
the server cannot determine from the Cookie header alone when a
cookie will expire, for which hosts the cookie is valid, for which
paths the cookie is valid, or whether the cookie was set with the
Secure or HttpOnly attributes.
Everything's behaving as specified.

Routes using cookie authentication from previous version of Paw no longer work on new version

I have a route that uses an authentication cookie set by another route. I've created it like this:
This method no longer works in the new version. Paw complains that there is no set-cookie header in the response from the Authenticate request.
It seems this is because Paw now takes the cookies and handles them differently from other headers. I like this approach because it should make this sort of authentication easier, but, unfortunately, it's not working like I would expect.
Here's how I have configured a newer request:
So, I've set the cookie header to the Response Cookies dynamic value which, I believe, should pass along the cookies set previously. I would think I should select the Authenticate request from the dropdown (since it's the response from this request that actually sets the cookie, but the cookie value disappears if I do that. Instead, I have left the request value as Current Request since that seems to contain the correct value.
I've also noticed the Automatically send cookies setting which I thought might be an easy solution. I removed the manual cookie header from my request leaving this checked in hopes it might automatically send over any cookies from the cookie jar along with the request, but that doesn't seem to work either. No matter what I try, my request fails to produce the desired results because of authentication.
Can you help me understand how to configure these requests so that I can continue using Paw to test session-authenticated routes?
Here are a couple of things that will make you understand how cookies work in Paw (starting from version 2.1):
1. Cookies are stored in Jars
To allow users to keep multiple synchronous sessions, cookies are stored in jars, so you can switch between sessions (jars) easily.
Cookies stored in jars will be sent only if they match the request (hostname, path, is secure, etc.).
2. Cookies from jars are sent by default, unless Cookie header is overridden
If you set a Cookie header manually, cookies stored in jars wont' be sent.
And obviously unless Automatically Send Cookies is disabled.
3. The previous use of "Response Headers" was hacky. Use Response Cookies.
In fact, Set-Cookie (for responses) and Cookie (for requests) have different syntaxes. So you can't send back the original value of Set-Cookie (even though it seemed to be working in most cases).
The new Response Cookies dynamic value you mentioned has this purpose: send back the cookies set by a specific request.
Now, in your case, I would use a Response Cookies dynamic value all the time. As you have only 1 request doing auth / cookie setting, it might be the easiest to handle. Also, maybe check Ignore Domain, Path, Is Secure and Date to make sure your cookie is always sent even if you switch the host (or something else).
Deleting the cookies in the cookie jar and hitting the authentication endpoint again seems to have fixed the problem. Not sure why, but it seems to be working now either manually sending a cookie or using the Automatically send cookies setting.

Resources