XPages: Dealing With "Cookie name X is a reserved token"

Feb 3, 2021, 10:49 AM

Tags: xpages

The other day, John Dalsgaard asked a question in the XPages Slack Community to do with an exception that a client was seeing when going to any XPage:

java.lang.IllegalArgumentException: Cookie name ""categories":"[\"performance\",\"unclassified\",\"targeting\",\"functionality\"]"" is a reserved token
	at javax.servlet.http.Cookie.<init>(Cookie.java:144)
	at com.ibm.domino.xsp.bridge.http.servlet.XspCmdHttpServletRequest.parseCookieString(XspCmdHttpServletRequest.java:349)
	at com.ibm.domino.xsp.bridge.http.servlet.XspCmdHttpServletRequest.getCookies(XspCmdHttpServletRequest.java:283)
	at com.ibm.domino.xsp.bridge.http.servlet.XspCmdHttpServletRequest.readSessionId(XspCmdHttpServletRequest.java:185)
	at com.ibm.domino.xsp.bridge.http.servlet.XspCmdHttpServletRequest.<init>(XspCmdHttpServletRequest.java:156)
	at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:256)

As the uncharacteristically-short stack trace implies, this happens long before any actual XPage code in an NSF. What's going on here is that something - possibly a too-clever-for-its-own good script - set a cookie using a JSON value so that it can store structured data. However, this is kind of an illegal thing to do: by the spec, commas are reserved in the Set-Cookie header and, by virtue of the shared cookie-octet part of the spec, are also illegal in the client-sent Cookie header.

Who Is Wrong Here?

And actually, as I type, I'm starting to blame XPages less for this: commas in HTTP headers indicate multiple wholly-distinct values. For example, take an Accept header, like:

text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

The commas there indicate distinct values according to the HTTP spec itself, while the semicolons are just an idiom used by the Accept header.

The Cookie header doesn't make use of this meaning of the comma, instead relying entirely on semicolons for some reason. Still, HTTP-wise, it seems that a server should treat this:

Cookie: foo=[bar,baz];othercookie=hi

...as equivalent to this conceptual version:

Cookie: foo=[bar
Cookie: baz];othercookie=hi

... which then should break, as "baz];othercookie" is wildly illegal in the rules for tokens because "]" and ";" show up in the separators list.

Long story short, unencoded JSON is extremely likely to run afoul of all sorts of rules here, and ideally the browser wouldn't send a header like that in the first place.

The Workaround

The XPages developers were aware of this, but made the fix an opt-in thing at the server filesystem level. To avoid this specific trouble, go to the "xsp" directory in your Domino program directory (not the data directory), create a file named "bootstrap.properties", and set its contents to:

1
xsp.commas.not.delimiters.in.cookie=true

To my knowledge, the only "documentation" that exists for this is an incidental mention in the XPages Portable Command Guide, where the property being false by default shows up in the sample output from running tell http xsp show settings on the console. Fortunately, once you know that it exists, the name is pretty self-documenting, and it does just what it says on the tin.

As with other server configuration options, I think this should be configurable at the NSF level, and should at the very least be something configurable in the data directory. Doing anything in the program directory only gives me the willies. The stack should also give a better error earlier, rather than relying on the Servlet Cookie class to balk at the malformed name.

In any event, if you have a case where you're using a library or same-domain-server app that sets a header like this, this property should help.

New Comment