Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some cookies cannot be removed with jar.delete() or jar.clear() #3026

Closed
basgroot opened this issue Apr 20, 2023 · 4 comments
Closed

Some cookies cannot be removed with jar.delete() or jar.clear() #3026

basgroot opened this issue Apr 20, 2023 · 4 comments
Labels

Comments

@basgroot
Copy link

basgroot commented Apr 20, 2023

Brief summary

We have a scenario where we must remove cookies from the request. However, it seems a specific cookie cannot be removed.
Code snippet:

const jar = http.cookieJar();
jar.delete(url, "amlbcookie");
jar.clear(url);  // To be sure, delete all (won't work either)
console.log(jar.cookiesForURL(url));

Output:

time="2023-04-20T07:08:12Z" level=info msg="{\"amlbcookie\":[\"01\"]}" source=console

After that, a request still sends the cookie (full code below).

I've tried to reproduce with other (httpOnly, secure) cookie-websites, but I didn't manage, so it has something to do with this URL.

Can you explain why this is not working? Is it something in my code, or are there scenario's where cookies just cannot be removed?

k6 version

v0.43.1

OS

Arch Linux

Docker version and image (if applicable)

20.10.24, build 297e128

Steps to reproduce the problem

Run this code:

import http from "k6/http";
import {check} from "k6";

export const options = {
  vus: 1,
  iterations: 1,
};

function doSomeRequest(url) {
    // Just do some request to create a cookie..
    const params = {
        "headers": {
            "Content-Type": "application/json",
            "Accept-API-Version": "resource=2.1, protocol=1.0"
        }
    };
    const jar = http.cookieJar();
    console.log("↓Available cookies:↓");
    console.log(jar.cookiesForURL(url));
    // Delete cookies:
    jar.delete(url, "amlbcookie");
    jar.clear(url);  // To be sure, delete all (won't work either)
    console.log("↓Available cookies after delete and clear:↓");
    console.log(jar.cookiesForURL(url));
    const req = http.post(url + "?authIndexType=service&authIndexValue=authn-web-v4", {}, params);
    if (req.status !== 200) {
        console.log("Error connecting with status " + req.status);
    }
    console.log("↓Cookies used in the request:↓");
    console.log(req.request.cookies);
    check(req, {
        // The second time the request is done this check fails, which is not as expected.
        "No amlbcookie cookie in the request": (r) => r.request.cookies.hasOwnProperty("amlbcookie") === false
    });
}

export default function () {
    const url = "https://auth-sim.logonvalidation.net/am/json/realms/root/realms/dca/authenticate";
    console.log(">>>>>> REQUEST 1 (set cookie) <<<<<");
    doSomeRequest(url);
    console.log(">>>>>> REQUEST 2 (test if cookie can be removed) <<<<<");
    doSomeRequest(url);
}

Expected behaviour

The check passes twice, indicating that the amlbcookie cookie is not part of the (second) request.
Or, if the cookie for some reason cannot be removed, I would like to see some feedback from K6 with the reason of this behavior.

check(req, {
    "No amlbcookie cookie in the request": (r) => r.request.cookies.hasOwnProperty("amlbcookie") === false
});

Actual behaviour

The check fails the second time, because the cookie is not deleted and the cookieJar is not cleared. Without an indication from K6 if this failure.

Output:

time="2023-04-20T07:08:12Z" level=info msg=">>>>>> REQUEST 1 (set cookie) <<<<<" source=console
time="2023-04-20T07:08:12Z" level=info msg="↓Available cookies:↓" source=console
time="2023-04-20T07:08:12Z" level=info msg="{}" source=console
time="2023-04-20T07:08:12Z" level=info msg="↓Available cookies after delete and clear:↓" source=console
time="2023-04-20T07:08:12Z" level=info msg="{}" source=console
time="2023-04-20T07:08:12Z" level=info msg="↓Cookies used in the request:↓" source=console
time="2023-04-20T07:08:12Z" level=info msg="{}" source=console
time="2023-04-20T07:08:12Z" level=info msg=">>>>>> REQUEST 2 (test if cookie can be removed) <<<<<" source=console
time="2023-04-20T07:08:12Z" level=info msg="↓Available cookies:↓" source=console
time="2023-04-20T07:08:12Z" level=info msg="{\"amlbcookie\":[\"01\"]}" source=console
time="2023-04-20T07:08:12Z" level=info msg="↓Available cookies after delete and clear:↓" source=console
time="2023-04-20T07:08:12Z" level=info msg="{\"amlbcookie\":[\"01\"]}" source=console
time="2023-04-20T07:08:12Z" level=info msg="↓Cookies used in the request:↓" source=console
time="2023-04-20T07:08:12Z" level=info msg="{\"amlbcookie\":[{\"name\":\"amlbcookie\",\"value\":\"01\",\"replace\":false}]}" source=console

     ✗ No amlbcookie cookie in the request
      ↳  50% — ✓ 1 / ✗ 1

     checks.........................: 50.00% ✓ 11

The workaround is to override the request cookie with an empty one with the same name, but this is not optimal.

@basgroot
Copy link
Author

Update:
Using the CookieJar() with uppercase C it is possible to send no cookies at all. Code:

const jar = http.CookieJar();
const params = {
    "headers": {
        "Content-Type": "application/json",
        "Accept-API-Version": "resource=2.1, protocol=1.0"
    },
    "jar": jar
};
const req = http.post(url + "?authIndexType=service&authIndexValue=authn-web-v4", {}, params);

I still think the jar.delete() is not working as expected, but this is a reasonable workaround.

@imiric
Copy link
Contributor

imiric commented Apr 20, 2023

Hi there, thanks for opening this issue, and for the detailed explanation and script ❤️

I'm able to reproduce it with your script and example URL, and like you said, it doesn't happen on other sites (e.g. https://httpbin.test.k6.io/).

I was also able to reproduce it with a custom endpoint. It happens if the URL contains a nested path, i.e. more than one /. If I set the cookies on the /cookies endpoint, then they're cleared properly by k6, but if they're set on /cookies/foo, they're not. 😕

I'm still looking into why this is the case, and will update this issue, and hopefully push a fix once I figure it out. This won't make it in the upcoming v0.44.0 release this Monday, but will be part of the next release.

@imiric
Copy link
Contributor

imiric commented Apr 20, 2023

OK, so after a bit more reading and testing, I now think k6 is behaving as expected.

Here are the headers sent by https://auth-sim.logonvalidation.net/am/json/realms/root/realms/dca/authenticate:

Set-Cookie: amlbcookie=01; Path=/; Domain=auth-sim.logonvalidation.net; Secure; HttpOnly; SameSite=none
Set-Cookie: amlbcookie=01; Path=/; Domain=auth-int.ssoc.onesim.eu41p.inf.iitech.dk; Secure; HttpOnly; SameSite=none
Set-Cookie: amlbcookie=01; Path=/; Domain=am-config; Secure; HttpOnly; SameSite=none
Set-Cookie: amlbcookie=01; Path=/; Domain=fr.ssoc.onesim.eu41p.inf.iitech.dk; Secure; HttpOnly; SameSite=none
Set-Cookie: amlbcookie=01; Path=/; Domain=am; Secure; HttpOnly; SameSite=none

Notice the Path=/ parameter. It means that the cookie should be sent for all requests under /, which k6 does.

Yet when you call jar.delete() or jar.clear() on that exact URL, it doesn't match that exact cookie, since the path is different.

Instead, you should call jar.delete('https://auth-sim.logonvalidation.net/', 'amlbcookie'), or jar.clear('https://auth-sim.logonvalidation.net/'), which works as expected, and deletes the cookie.

So you'll need to inspect the Response.cookies map to get the path the cookie was set on, and then clear it with that path.

Let me know if this resolves it, and please close the issue if so.

@imiric imiric added the awaiting user waiting for user to respond label Apr 21, 2023
@basgroot
Copy link
Author

Thank you for the really fast and accurate response. I confirm the solution is to use 'scheme+host+cookie path', instead of the full URL.
That makes the code a little more complex, because that info is only available after a request and not part of the cookiesForURL() response.
But it will do. I'll close the issue.

Thanks!
Bas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants