Skip to content

Support cookie SameSite=None option on nodejs - #8652

Merged
diemol merged 16 commits into
SeleniumHQ:trunkfrom
n2o1988:nodejs-cookie-samesite-allow-none
Sep 10, 2020
Merged

Support cookie SameSite=None option on nodejs#8652
diemol merged 16 commits into
SeleniumHQ:trunkfrom
n2o1988:nodejs-cookie-samesite-allow-none

Conversation

@n2o1988

@n2o1988 n2o1988 commented Aug 27, 2020

Copy link
Copy Markdown
Contributor

Thanks for contributing to Selenium!
A PR well described will help maintainers to quickly review and merge it

Before submitting your PR, please check our contributing guidelines.
Avoid large PRs, help reviewers by making them as simple and short as possible.

Description

Allows cookies to be added with SameSite set to "None" in addition to "Lax" and "Strict", as per https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite.
This option is only valid if the cookie is Secure (see https://web.dev/samesite-cookies-explained/#samesitenone-must-be-secure and proposal).

Motivation and Context

Follow up to #7901
Recent updates to Chrome 85 (and soon landing on Firefox) changed the default from None to Lax, requiring us to explicitly set sameSite: 'None', which the original implementation does not allow (not sure why, maybe None wasn't an option, back then?).
This also mirrors what the Java bindings support: https://github.com/SeleniumHQ/selenium/blob/trunk/java/client/src/org/openqa/selenium/Cookie.java#L111
Other bindings (such as Python) have the same issue and should be updated too (I'm not a Python dev though).

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • I have read the contributing document.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Allows cookies to be set with SameSite=None in addition to "Lax" and
"Strict". As per https://web.dev/samesite-cookies-explained/, this
option is only valid if the cookie is set as Secure.
@CLAassistant

CLAassistant commented Aug 27, 2020

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@n2o1988

n2o1988 commented Aug 27, 2020

Copy link
Copy Markdown
Contributor Author

There's an existing failing test (at least on my machine)

  1. [chrome] can send commands to devtools and get return
    Message:
    TypeError: driver.sendDevToolsCommandAndGetReturn is not a function

This error occurs in the trunk branch too, so nothing related to this PR.

I'm not sure why the Lint check failed, I use an ESLint extension in VSCode that's supposed to auto format everything according to the repo's rules. The error doesn't seem related to my change.

@n2o1988 n2o1988 changed the title Nodejs cookie samesite allow none Support cookie SameSite=None option on nodejs bindings Aug 27, 2020
@n2o1988 n2o1988 changed the title Support cookie SameSite=None option on nodejs bindings Support cookie SameSite=None option on nodejs Aug 27, 2020

@n2o1988 n2o1988 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of clarifications

*
*
* @type {(!Date|number|undefined)}
* @type {(string|undefined)}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was a copy-paste mistake in the original PR.

await driver.manage().addCookie(cookie)
await assert.doesNotReject(
async () => await driver.manage().addCookie(cookie)
)

@n2o1988 n2o1988 Aug 27, 2020

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other test cases for SameSite take a different approach to test this: they set the cookie and read it straight after.
In case of None, the cookie has to be secure, and I found this means the getCookie call would not return any cookie (since the test page in localhost is not served via https I presume?).

I figured the best way to test this is to test that it does not throw an exception. In fact, an invalid combination (see below tests) would cause the underlying driver to raise an exception.
This sounds sufficient to me but let me know if this is not enough.

I did make sure that this works in our real test suites (where the app is served on https).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this is fine

}
)

ignore(env.browsers(Browser.FIREFOX, Browser.IE, Browser.SAFARI)).it(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't these tests work in Firefox?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mirrored the original tests, didn't want to change too much. I'll double-check. Maybe it wasn't an option at the time of the original implementation but it is now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, updated.

await driver.manage().addCookie(cookie)
await assert.doesNotReject(
async () => await driver.manage().addCookie(cookie)
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this is fine

}
)

ignore(env.browsers(Browser.FIREFOX, Browser.IE, Browser.SAFARI)).it(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this work in Firefox?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@AutomatedTester AutomatedTester added the C-nodejs JavaScript Bindings label Aug 27, 2020
@@ -1177,9 +1177,15 @@ class Options {
expiry = Math.floor(date.getTime() / 1000)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the related webdriver specification

Defaults to None if omitted when adding a cookie.

We should set sameSite cookie by default as "None" when omitted.

Suggested change
if (!sameSite) {
sameSite = 'None'
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too sure we should do that given that:

  • no other Selenium binding is doing that: all seem to leverage on the underlying driver/browser implementation for the default value
  • I think it's the Browsers' responsibility to define the default behavior. For instance, in Chrome 85 that's exactly what changed: default is now Lax for Chrome and soon for Firefox too. That change was the reason I opened this PR in the first place.
  • with the new security proposal, sameSite='None' should always be accompanied by Secure=true, so we'd need to take that into account
  • changing that would be a breaking change (nothing against it, but I'd like the maintainers' opinion)

Interested to hear thoughts from @AutomatedTester


if (sameSite === 'None' && !secure) {
throw new error.InvalidArgumentError(
`Invalid cookie configuration: SameSite=None must be Secure`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It helps further understanding that None is a string and we keep a consistent sameSite formatting

Suggested change
`Invalid cookie configuration: SameSite=None must be Secure`
'Invalid cookie configuration: sameSite="None" must be Secure'

@n2o1988 n2o1988 Aug 28, 2020

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was following the cookie header format (e.g. SameSite=None; Secure; ).
I can change that if you feel strongly about it, but then it should be secure: true instead of Secure.

@n2o1988 n2o1988 closed this Aug 28, 2020
@n2o1988 n2o1988 reopened this Aug 28, 2020
@n2o1988

n2o1988 commented Sep 1, 2020

Copy link
Copy Markdown
Contributor Author

@AutomatedTester any other thoughts on this one?

@AutomatedTester

Copy link
Copy Markdown
Member

This looks like it is about ready to land. There are linting errors. Could you fix those please and I will get it landed.

@n2o1988

n2o1988 commented Sep 4, 2020

Copy link
Copy Markdown
Contributor Author

This looks like it is about ready to land. There are linting errors. Could you fix those please and I will get it landed.

@AutomatedTester the linting errors seem unrelated to my change.
I think you the same errors show up in the trunk branch?

It also seems like this "Super-Linter" has conflicting rules with the ones declared in the .eslintrc.js config
Example: prettier wants you to have a trailing comma for arrays on multiple lines.
The "Super-Linter" check on Github says the opposite.

/github/workspace/javascript/node/selenium-webdriver/lib/webdriver.js:45:28: Unexpected trailing comma.

@diemol

diemol commented Sep 4, 2020

Copy link
Copy Markdown
Member

@n2o1988 I just ran the linter again on trunk and it is passing. Somehow the changes to the files in this PR are making the linter fail. It'd be nice if you can have a look 🙏

@n2o1988

n2o1988 commented Sep 4, 2020

Copy link
Copy Markdown
Contributor Author

@diemol maybe I'm doing this wrong.
How do I run that linter locally?

My linting config says everything is good, locally (at least according to .eslintrc.js).

@diemol

diemol commented Sep 4, 2020

Copy link
Copy Markdown
Member

@n2o1988 I did not do it locally, I only ran the GitHub action job again on trunk.

@n2o1988

n2o1988 commented Sep 4, 2020

Copy link
Copy Markdown
Contributor Author

@diemol it's kinda hard to spot what's wrong in this case.

If you look at the output of the linter, it shows a whole bunch of things I haven't changed, and the rules it's using are conflicting with the rules specified by ESLint
image

I never touched those lines.. :|

@AutomatedTester

Copy link
Copy Markdown
Member

Let me have a look at the linter stuff since I set it up

@n2o1988

n2o1988 commented Sep 7, 2020

Copy link
Copy Markdown
Contributor Author

@AutomatedTester any updates on merging this PR?

@n2o1988

n2o1988 commented Sep 8, 2020

Copy link
Copy Markdown
Contributor Author

@AutomatedTester @diemol 🆙

We're sort of in a hurry to get this released, otherwise we'll have to go the way of pinning our own fork (which I'd like to avoid).
Any chance this can get merged & released anytime soon?

@n2o1988

n2o1988 commented Sep 10, 2020

Copy link
Copy Markdown
Contributor Author

Up: any updates on merging this PR @AutomatedTester @diemol ?

@diemol

diemol commented Sep 10, 2020

Copy link
Copy Markdown
Member

Merging this, thank you for your contribution @n2o1988!

However, I cannot say when the next alpha release will happen.

@diemol
diemol merged commit 63d9869 into SeleniumHQ:trunk Sep 10, 2020
@n2o1988

n2o1988 commented Sep 11, 2020

Copy link
Copy Markdown
Contributor Author

Thanks @diemol !
Is there a release tracker page or a way to get notified when the next alpha is released?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-nodejs JavaScript Bindings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants