geckodriver icon indicating copy to clipboard operation
geckodriver copied to clipboard

Add cookie fails with NS_ERROR_ILLEGAL_VALUE

Open devl00p opened this issue 3 years ago • 2 comments

Hello,

I noticed that something seems to be wrong with the "add cookie" feature. The driver seems to reply that a value of the cookie is incorrect but I followed the webdriver documentation carefully ( https://w3c.github.io/webdriver/#dfn-adding-a-cookie ) and I still can't figure out what is the problem.

I looked at chrome://remote/content/marionette/cookie.js too but it didn't help neither.

Please find bellow the example code in Python.

What it is doing is:

  • loading http://httpbin.org/cookies/set/foo/bar that sets a cookie for that website
  • use get cookies to make sure the cookie was set (which is the case)
  • attempt to set a new cookie (as you can see the keys/values are almost the same than the previous one)

Geckodriver was launched with geckodriver --port 38045 -vv

System

  • Version: 0.31.0 (b617178ef491 2022-04-06 11:57 +0000)
  • Platform: Linux
  • Firefox: 101.0.1 (64 bits)

Testcase

from datetime import datetime
from time import sleep

import requests

PORT = 38045
BASE_URL = f"http://localhost:{PORT}/session"


class Headless:
    def __init__(self):
        response = requests.post(
            BASE_URL,
            json={
                "capabilities": {
                    "alwaysMatch": {
                        "browserName": "firefox"
                    }
                }
            }
        )
        self._session_id = response.json()["value"]["sessionId"]

    def get(self, url: str) -> str:
        response = requests.post(
            f"{BASE_URL}/{self._session_id}/url",
            json={"url": url}
        )
        return response.json()

    def get_cookies(self):
        response = requests.get(
            f"{BASE_URL}/{self._session_id}/cookie",
        )
        return response.json()


    def add_cookie(self, properties: dict):
        response = requests.post(
            f"{BASE_URL}/{self._session_id}/cookie",
            json={"cookie": properties}
        )
        return response.json()

    def close(self):
        response = requests.delete(f"{BASE_URL}/{self._session_id}")


headless = Headless()
headless.get("http://httpbin.org/cookies/set/foo/bar")
sleep(1)
print(headless.get_cookies())  # works
response = headless.add_cookie(
    {
        "name": "test",
        "value": "secret",
        "path": "/",
        "domain": "httpbin.org",
        "httpOnly": False,
        "secure": False,
        "sameSite":"None",
    }
)
print(response)  # prints the "unable to set cookie" / NS_ERROR_ILLEGAL_VALUE error message

Stacktrace

cookie.add@chrome://remote/content/marionette/cookie.js:212:20 GeckoDriver.prototype.addCookie@chrome://remote/content/marionette/driver.js:1886:10

Trace-level log

1655740488460   webdriver::server       DEBUG   -> POST /session/915011d3-be15-4b63-91cb-7d2548cd925b/url {"url": "http://httpbin.org/cookies/set/foo/bar"}
1655740488470   Marionette      DEBUG   0 -> [0,2,"WebDriver:Navigate",{"url":"http://httpbin.org/cookies/set/foo/bar"}]
1655740488485   Marionette      TRACE   [21] Received event beforeunload for about:blank
1655740488786   Marionette      TRACE   Remoteness change detected. Set new top-level browsing context to 41
1655740488816   Marionette      TRACE   [41] Received event beforeunload for about:blank
1655740488875   Marionette      TRACE   [41] Received event pagehide for about:blank
1655740488944   Marionette      TRACE   [41] Received event DOMContentLoaded for http://httpbin.org/cookies
1655740488988   Marionette      TRACE   [41] Received event pageshow for http://httpbin.org/cookies
1655740488989   Marionette      DEBUG   0 <- [1,2,null,{"value":null}]
1655740488992   webdriver::server       DEBUG   <- 200 OK {"value":null}
1655740490000   webdriver::server       DEBUG   -> GET /session/915011d3-be15-4b63-91cb-7d2548cd925b/cookie
1655740490005   Marionette      DEBUG   0 -> [0,3,"WebDriver:GetCookies",{}]
1655740490007   Marionette      DEBUG   0 <- [1,3,null,[{"name":"foo","value":"bar","path":"/","domain":"httpbin.org","secure":false,"httpOnly":false,"sameSite":"None"}]]
1655740490007   webdriver::server       DEBUG   <- 200 OK {"value":[{"name":"foo","value":"bar","path":"/","domain":"httpbin.org","secure":false,"httpOnly":false,"sameSite":"None"}]}
1655740490011   webdriver::server       DEBUG   -> POST /session/915011d3-be15-4b63-91cb-7d2548cd925b/cookie {"cookie": {"name": "test", "value": "secret", "path": "/", "domain": "httpbin.org", "httpOnly": false, "secure": false, "sameSite": "None"}}
1655740490013   Marionette      DEBUG   0 -> [0,4,"WebDriver:AddCookie",{"cookie":{"domain":"httpbin.org","httpOnly":false,"name":"test","path":"/","sameSite":"None","secure":false,"value":"secret"}}]
1655740490014   Marionette      DEBUG   0 <- [1,4,{"error":"unable to set cookie","message":"[Exception... \"Component returned failure code: 0x80070057 (NS_ERROR_ILLEGAL ... t/marionette/cookie.js:212:20\nGeckoDriver.prototype.addCookie@chrome://remote/content/marionette/driver.js:1886:10\n"},null]
1655740490014   webdriver::server       DEBUG   <- 500 Internal Server Error {"value":{"error":"unable to set cookie","message":"[Exception... \"Component returned failure code: 0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsICookieManager.add]\"  nsresult: \"0x80070057 (NS_ERROR_ILLEGAL_VALUE)\"  location: \"JS frame :: chrome://remote/content/marionette/cookie.js :: cookie.add :: line 212\"  data: no]","stacktrace":"cookie.add@chrome://remote/content/marionette/cookie.js:212:20\nGeckoDriver.prototype.addCookie@chrome://remote/content/marionette/driver.js:1886:10\n"}}

devl00p avatar Jun 20 '22 16:06 devl00p

The domain you are using here is an "effective" TLD at https://publicsuffix.org/list/public_suffix_list.dat , and we are not able to create "domain" cookies for a TLD.

Note that when you pass "domain" to AddCookie, it will not be used as the "Domain" value of the cookie. Instead it will be prefixed with a dot (.httpbin.org here) to make it a "domain cookie" available from all the subdomains of this domain. But again that's not allowed for TLDs (and effective TLDs apparently).

If you just want to create a cookie with "Domain=httpbin.org" (without making it a "domain cookie"), you can omit the "domain" and it should work fine.

Let me know if that helps. On Firefox' side, I'll see if we can make that error more explicit...

juliandescottes avatar Sep 21 '22 16:09 juliandescottes

Filed https://bugzilla.mozilla.org/show_bug.cgi?id=1791813 to improve the error message

juliandescottes avatar Sep 21 '22 16:09 juliandescottes