cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
46.69k stars 3.16k forks source link

Cypress silently drops secure cookies from requests (Chromium), fails to set secure cookie at all (Firefox) #18690

Open spiffytech opened 2 years ago

spiffytech commented 2 years ago

Current behavior

Cypress misbehaves when managing secure cookies on localhost.

Chromium

Cypress visits some path (e.g., /set-cookie) that sets a secure cookie. Then, Cypress visits another path (/) that reads the cookie value. On that second request, Cypress doesn't send the cookie. Chromium indicates the cookie is sent, but the web server doesn't receive it, and a MitM proxy shows the cookie is not in the request. If the cookie is not marked as secure, everything behaves correctly.

The attached reproduction repo provides the details about this test.

Cookie in devtools: devtools-cookie

Request that pretends to send the cookie: devtools-request

Intercepted request: mitm-intercept-secure

For comparison, here's the intercepted request when using an insecure cookie: mitm-intercept-insecure

Firefox

In Firefox, the secure cookie is never set in the first place.

Devtools prints: Cookie “mySecureCookie” has been rejected because a non-HTTPS cookie can’t be set as “secure”. (Related: #16611)

Desired behavior

localhost is considered a secure browsing context, and the repro app works correctly outside of Cypress. Setting and transmitting a secure cookie on localhost should be successful. Failing that, Chromium should not lie about whether the cookie is being sent.

Test code to reproduce

Here's an app I put together that minimally reproduces the issue, with failing Cypress tests.

npm install, npm start to launch the web server, npm test to show the Cypress tests demonstrating the failure.

Cypress Version

8.7.0

Other

If I open a normal Chromium or Firefox instance, everything works correctly. This only happens under Cypress' automation.

Chromium version: 94.0.4606.81 (openSUSE Build) stable (64-bit)

Firefox version: 93.0 (64-bit)

alexjamesmacpherson commented 2 years ago

I am also observing this issue and it significantly impedes our ability to implement and run Cypress tests for our application when it's running locally.

Any update on resolving this problem would be greatly appreciated, or if anyone knows of a workaround we can implement in the meantime, that would be great!

confiscar commented 2 years ago

Not really a work around, but had a similar problem today. Found another issue that mentioned how downgrading to 6.4.0 resolved their issues, which also fixed mine. Its either that or not setting the cookie as secure :(

Seems like a regression?

confiscar commented 2 years ago

Workaround:

Instead of using cy.visit(), get the window object and manually set location.href.

e.g.

cy.window().then((win) => win.location.href=yourURL);
sethlivingston commented 2 years ago

We're seeing the same problem. It happens when we intercept a call and modify the body -- the subsequent call won't have the cookie.

mheers commented 2 years ago

I'm also seeing the same problem. Running Cypress locally is fine, but when running in docker it breaks. I created a simple repository to reproduce the problem:

https://github.com/mheers/cypress-docker-cookie

cypress-app-bot commented 1 year ago

This issue has not had any activity in 180 days. Cypress evolves quickly and the reported behavior should be tested on the latest version of Cypress to verify the behavior is still occurring. It will be closed in 14 days if no updates are provided.

cypress-app-bot commented 1 year ago

This issue has been closed due to inactivity.

dcsaszar commented 9 months ago

This is still an issue in Cypress 13.6.0

FWIW, here's the workaround helper we run as the last step of our login command:

(Update 2024-03-24: We found a more effective workaround here.)

/**
 * Workaround for https://github.com/cypress-io/cypress/issues/18690
 */
function makeCookiesInsecure() {
  cy.getCookies().then((cookies) => {
    const cookie = cookies.find(({ secure }) => !!secure);
    if (!cookie) return;

    cy.clearCookie(cookie.name).setCookie(cookie.name, cookie.value, {
      ...cookie,
      secure: false,
      sameSite: undefined,
    });

    cy.reload();

    makeCookiesInsecure();
  });
}
jennifer-shehane commented 9 months ago

Reopening

georgwindhaber commented 8 months ago

I'm seeing the same problem with firefox v121 and cypress v12.17.4 or v13.6.3

In Chrome v120 it works for me