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

#175 Add support for SameSite cookies #271

Closed
wants to merge 2 commits into from

Conversation

aldaris
Copy link

@aldaris aldaris commented Oct 14, 2019

This PR adds support for SameSite attributes, allowing consumers of the API setting cookies with SameSite flags None, Lax, and Strict.
#175

@aldaris aldaris mentioned this pull request Oct 14, 2019
@joakime
Copy link

joakime commented Nov 15, 2019

The current Google Chrome 80 (canary builds) are already enforcing SameSite and will produce many errors / warnings if it's not used properly.

@joakime
Copy link

joakime commented Nov 15, 2019

@aldaris this PR is failing the Eclipse ECA checks.

  1. Make sure you have a filed ECA at eclipse - follow details link
  2. Make sure your commit uses the same email address on file with your ECA
  3. Make sure you follow the Developer Certificate of Origin as by using the "Signed Off By" features of git commit - https://wiki.eclipse.org/Development_Resources/Contributing_via_Git

@yang-wei
Copy link

yang-wei commented Jan 6, 2020

@joakime @aldaris Can we just make this commit goes into next release ?

@aldaris
Copy link
Author

aldaris commented Jan 6, 2020

@yang-wei The ECA related concerns should not be a problem any more, but the code still needs to be reviewed.

@yang-wei
Copy link

yang-wei commented Jan 8, 2020

for anyone who is looking for alternative, we do this for our scala code

  private def setNoneSamesiteCookie(response: HttpServletResponse) {
    val setCookieHeader = "Set-Cookie"
    val l = new ListBuffer[String]()
    response.getHeaders(setCookieHeader).toArray().foreach(s => {
      l += String.format("%s; %s", s, "SameSite=None")
    })
    l.toList match {
      case head :: tail => {
      // this will clean all headers and set the first header with samesite
        response.setHeader(setCookieHeader, head)
        tail.foreach(s => {
          response.addHeader(setCookieHeader, s)
        })
      }
      case Nil => None
    }
  }

@driverpt
Copy link

driverpt commented Jan 8, 2020

Ok, but isn't that overriden if we set other Cookies ?

@yang-wei
Copy link

yang-wei commented Jan 9, 2020

overriden with the attribute SameSite=None.
In my case I want all my cookies to have SameSite=None attributes. Feel free to change my code according to your needs

Copy link

@joakime joakime left a comment

Choose a reason for hiding this comment

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

Avoid using user's default locale in toUpperCase.

Also, perhaps don't override toString() for literal, instead have new toLiteral() method?

api/src/main/java/jakarta/servlet/http/Cookie.java Outdated Show resolved Hide resolved
@aldaris
Copy link
Author

aldaris commented Jan 16, 2020

I've used @since Servlet 4.x in the JavaDoc as I have no idea what version this will translate to. Also not sure whether you want to mention that this is Jakarta Servlet or something.

Also I was wondering if you were happy with the current wording of the JavaDoc.

Copy link

@joakime joakime left a comment

Choose a reason for hiding this comment

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

+1 from me.

Copy link
Contributor

@gregw gregw left a comment

Choose a reason for hiding this comment

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

A few more changes... but almost there!

api/src/main/java/jakarta/servlet/SessionCookieConfig.java Outdated Show resolved Hide resolved
api/src/main/java/jakarta/servlet/SessionCookieConfig.java Outdated Show resolved Hide resolved
api/src/main/java/jakarta/servlet/http/Cookie.java Outdated Show resolved Hide resolved
*
* <p>
* Note that this mode is browser dependent, and browsers may require cookies to have the {@literal Secure}
* attribute to be set at the same time.
Copy link
Author

Choose a reason for hiding this comment

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

/*
I wonder if this should mention the horrors of:
https://www.chromium.org/updates/same-site/incompatible-clients
Chances are it would turn outdated eventually though.
*/

Copy link
Contributor

Choose a reason for hiding this comment

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

I think a general warning that browsers may interpret spec differently is fine.... Perhaps we should say that on every feature :)

@aldaris
Copy link
Author

aldaris commented Jan 16, 2020

If you can give me a final thumbs up on the review, I'll squash my commits so you can merge this. :)

Copy link
Contributor

@gregw gregw left a comment

Choose a reason for hiding this comment

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

LGTM

@gregw
Copy link
Contributor

gregw commented Jan 17, 2020

@aldaris I can squash and merge from git if you like.

@markt-asf
Copy link
Contributor

I thought the plan was not to change the API at all for 5.0. Or is this planned for 5.1? If so, we need to create a 5.0.x branch.

@gregw
Copy link
Contributor

gregw commented Jan 17, 2020

@markt-asf good question. But we really need to make changes like this to stay relevant.
Ideally we'd do a 4.1 release in the javax space with this and then make 5.0 the exact jakarta equivalent.... but I think we can't legally make any such changes in javax space.
So this is either in 5.0 or has to be punted to 5.1. Personally I think it would be crazy if our inability to change javax specs resulted in us holding back reasonable maintenance changes like this from a major 5.0 release, thus requiring a 5.1 straight away afterwards.

@bshannon thoughts?

@bshannon
Copy link
Contributor

You definitely can't change the javax version.

You can make changes like this in 5.0, but the review process requires you to call them out,
and it may be harder to justify them. If 5.1 is 6 months after 5.0, is this still critical in 5.0?
(6 months is just an example, not a commitment.)

It would probably be best to engage with the platform project team and/or the spec committee
to see what the reaction to something like this is going to be before you commit to it.

@gregw
Copy link
Contributor

gregw commented Jan 18, 2020

The argument to include this feature in 5.0 is that browsers already support this feature, there is demand for its usage and containers are already adding non-standard configuration to support it. To not have it in 5.0 just makes the standard less relevant to current needs.

For now I'll leave this unmerged until we engage with platform project team and/or the spec committee and develop firm plans for 5.0 and 5.1

@gregw gregw added this to In Progress in 5.0 via automation Jan 18, 2020
Signed-off-by: Peter Major <peter.major@forgerock.com>
Signed-off-by: Peter Major <peter.major@forgerock.com>
Copy link
Contributor

@stuartwdouglas stuartwdouglas left a comment

Choose a reason for hiding this comment

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

There are some minor changes related to now targetting 5.1, but other than that I think it is mostly ready to go.

Once this goes in we need to add some TCK tests for it though, and we have not really sorted out exactly how that is going to work yet.

*
* @see jakarta.servlet.http.Cookie#setSameSite(SameSite)
*
* @since Servlet 5.0
Copy link
Contributor

Choose a reason for hiding this comment

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

Needs to be 5.1 now

Copy link
Member

@BalusC BalusC Apr 17, 2021

Choose a reason for hiding this comment

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

And replace <tt> over all place by <code> or {@code}. The <tt> is disallowed since the HTML5 era and newer versions of the Javadoc tool is prone to error out on them.

*
* @see jakarta.servlet.http.Cookie#getSameSite
*
* @since Servlet 5.0
Copy link
Contributor

Choose a reason for hiding this comment

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

5.1

* @param sameSite the <i>SameSite</i> attribute's value; may be null if the attribute should be a container
* provided context default or not set if there is no context default.
*
* @since Servlet 5.0
Copy link
Contributor

Choose a reason for hiding this comment

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

5.1

* @return the <i>SameSite</i> attribute associated with this cookie; may be null to indicate that the attribute
* should be a container provided context default or not set if there is no context default.
*
* @since Servlet 5.0
Copy link
Contributor

Choose a reason for hiding this comment

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

5.1

/**
* The available values that can be used with the cookie's <i>SameSite</i> attribute.
*/
public enum SameSite {
Copy link
Contributor

Choose a reason for hiding this comment

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

IMHO this should be a javadoc only feature. I don't see any benefit to including this in the ServletContext.

@stuartwdouglas
Copy link
Contributor

This also needs an entry in the changelog of the spec document

@s3curitybug
Copy link

Any update on this?

@s3curitybug
Copy link

Could someone show up and explain what is happening with this PR? I've been willing to set the samesite attribute in my cookies for so long and this PR has been blocked for months, apparently waiting for small changes.

@thenatog
Copy link

Would be great to see this one merged in.

* Retrieves the {@link SameSite} instance from its String representation.
*
* @param value the String to be converted
* @return the corresponding {@link SameSite} enum
Copy link
Member

Choose a reason for hiding this comment

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

It should document @throws IllegalArgumentException as well for the unhappy path.

@dagnelies
Copy link

dagnelies commented Apr 25, 2021

Oh man, this should have been merged ages ago.

It was reported in #175 in 2017, you got a generous PR in 2019 and now is 2021 and it's still in limbo.

I never imagined it would take so many years to add a damn property to cookies. Everybody builds workarounds since ages because of this!

Can't you just swap the @since 5.0 into @since 5.1 and be done with it?! It's soooo overdue.

My apologies for the rudeness.

@BalusC
Copy link
Member

BalusC commented Apr 26, 2021

It was proposed 2016 https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-same-site but indeed still hasn't yet ended up in the standard spec, they're after 5 years still drafting it https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-07 (7th revision!) The current PR uses a predefined enum instead of a free text string and this moving target is very prone to cause forward and backward compatibility problems in the future.

It's much better to add a generic Cookie#setAttribute method as suggested here #175 (comment) until they have crystallized it into the spec.

@BalusC BalusC mentioned this pull request Apr 26, 2021
@BalusC
Copy link
Member

BalusC commented Apr 26, 2021

I've prepped a PR to add Cookie#setAttribute: #399

gregw added a commit that referenced this pull request May 17, 2021
* Add Cookie#setAttribute
#175
#271

* Skip null value from check for reserved token

* Alternative approach to cookie attribute handling
github.com//pull/399#discussion_r624276777

* Make sure path is referenced via constant

* In hindsight, token check doesn't need to be performed on value

* Match casing with spec; mapping is case insensitive anyway

* Optimized Cookie to lazily create attribute map

* Added junit test

* Updates from review

* Fixed quote

* surefire plugin

* Updates from review

* Updates from review

Co-authored-by: Bauke Scholtz <balusc@gmail.com>
@markt-asf
Copy link
Contributor

This has been superseded by the addition of generic attribute support.

@markt-asf markt-asf closed this Oct 7, 2021
@Lonzak
Copy link

Lonzak commented Oct 7, 2021

@markt-asf Do you have a link for the generic attribute support? To which version was this added? This would make it more future proof - nice.

@markt-asf
Copy link
Contributor

#401 - it will be in Servlet 6.0

@Lonzak
Copy link

Lonzak commented Oct 7, 2021

Damn 6.0 is quite late - so now there is no solution for 5.1, right?

@pizzi80
Copy link

pizzi80 commented Dec 6, 2023

I think this issue should be reopened and implemented in Servlet 6.1

The SameSite attribute it's too important to be declassed as a generic attribute,
there are a lot of conseguences around not setting or setting the wrong value!

If I use the generic setAttribute method and make a typo,
the webapp may no longer work properly!

For real world developers it's really important to have a set-in-stone fundamental attribute like this one

https://web.dev/articles/samesite-cookie-recipes?hl=en
https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#creating_cookies

@BalusC
Copy link
Member

BalusC commented Dec 6, 2023

SameSite spec is still in draft mode: https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-13 13th cycle already!
We really want to put it in Servlet spec but as long as they don't we can't.

@joakime
Copy link

joakime commented Dec 6, 2023

@pizzi80 I actually think the generic setAttribute method is ideal.

Esp considering how quickly the Cookie spec is evolving.

  1. SameSite attribute - https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-13#section-4.1.2.7
  2. Partitioned attribute - https://developers.google.com/privacy-sandbox/3pcd#partitioned and https://developer.mozilla.org/en-US/docs/Web/Privacy/Partitioned_cookies
  3. Cookie name prefixes (and validation associated with it) - https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-13#section-4.1.3

It's not ideal to have to wait for another Servlet spec release (and associated implementations) to handle the evolution of Cookie in your webapp.

@dagnelies
Copy link

dagnelies commented Dec 6, 2023

We really want to put it in Servlet spec but as long as they don't we can't.

Why can't you?

There is the spec committee on one side and reality on the other.
Chrome supports SameSite since 2016, Firefox since 2018 and all other browsers since many years already. Everybody uses it, everybody supports it ...except for Java Servlets ...still missing it 7 years later ....because of the "status" of some document. Seriously, what's the harm of adding this?! Everybody needs it.

@joakime
Copy link

joakime commented Dec 6, 2023

If I use the generic setAttribute method and make a typo,
the webapp may no longer work properly!

You can make typos in many places in Servlet and your webapp may no longer work.
(eg: url-patterns, request-dispatchers, query strings, pretty much most response headers, Content-Type, CORS, Content-Encoding, etc)

@BalusC
Copy link
Member

BalusC commented Dec 6, 2023

Chrome supports SameSite since 2016, Firefox since 2018 and all other browsers since many years already

Browsers don't represent a spec.

Seriously, what's the harm of adding this

Jakarta EE isn't a random "3rd party library". Jakarta EE is also a spec.

Just use setAttribute(). It will be there forever. Direct future complaints about unfinished HTTP specs to HTTP spec guys please, not to us.

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

Successfully merging this pull request may close these issues.

None yet