From 4942a45b68be089432aaf1e2453b8b41361973b2 Mon Sep 17 00:00:00 2001 From: maximthomas Date: Mon, 27 Jul 2026 17:53:50 +0300 Subject: [PATCH] Fix docs contradicting each other on XUI + HttpOnly session cookies --- .../main/asciidoc/admin-guide/chap-securing.adoc | 8 +++++++- .../deployment-planning/chap-deployments.adoc | 2 +- .../main/asciidoc/dev-guide/chap-client-dev.adoc | 6 ++++++ .../main/asciidoc/reference/chap-config-ref.adoc | 8 +++++++- .../config/validserverconfig.properties | 1 + .../template/sms/serverdefaults.properties | 16 +++++++++++----- 6 files changed, 33 insertions(+), 8 deletions(-) diff --git a/openam-documentation/openam-doc-source/src/main/asciidoc/admin-guide/chap-securing.adoc b/openam-documentation/openam-doc-source/src/main/asciidoc/admin-guide/chap-securing.adoc index 05047ec757..8b4fd5ad69 100644 --- a/openam-documentation/openam-doc-source/src/main/asciidoc/admin-guide/chap-securing.adoc +++ b/openam-documentation/openam-doc-source/src/main/asciidoc/admin-guide/chap-securing.adoc @@ -110,7 +110,13 @@ To configure OpenAM server to use secure cookies, in the OpenAM console, navigat + HttpOnly cookies are meant to be transmitted only over HTTP and HTTPS, and not through non-HTTP methods, such as JavaScript functions. + -You can configure the OpenAM server to use HttpOnly cookies by navigating to Configure > Server Defaults > Advanced, and setting the `com.sun.identity.cookie.httponly` property's value to `true`. Save your changes. Note that the XUI reads the `iPlanetDirectoryPro` SSO cookie from the browser to track the session, so enabling `HttpOnly` breaks XUI console login; the property therefore defaults to `false`. Set it to `true` only in deployments that do not rely on the XUI. +You can configure the OpenAM server to use HttpOnly cookies by navigating to Configure > Server Defaults > Advanced, and setting the `com.sun.identity.cookie.httponly` property's value to `true`. Save your changes. Both the classic UI and the XUI support HttpOnly session cookies: when HttpOnly is enabled, the XUI relies on the automatically sent cookie instead of reading the token from JavaScript, and the `/json/authenticate` response delivers the token only through the `Set-Cookie` header rather than echoing `tokenId` in the response body. To keep returning `tokenId` in the body as well (for example, for non-browser or raw-REST integrations), set `org.openidentityplatform.openam.httponly.allowTokenInBody` to `true`. Note that doing so re-exposes the token to scripts on the OpenAM origin, so leave it at its default of `false` unless an integration requires it. For both properties, see `com.sun.identity.cookie.httponly` and `org.openidentityplatform.openam.httponly.allowTokenInBody` in xref:../reference/chap-config-ref.adoc#chap-config-ref["Configuration Reference"] in the __Reference__. ++ +Both properties are read once when the server starts, so you must restart the OpenAM server for a change to either of them to take effect. ++ +`com.sun.identity.cookie.httponly` defaults to `false` to preserve the behaviour of existing integrations that read the session cookie, or the `tokenId` from the authentication response body, from script. Enabling HttpOnly is recommended for browser-facing deployments: an HttpOnly session cookie prevents a cross-site scripting flaw on the OpenAM origin from reading a replayable session token. ++ +One known limitation applies: the OpenID Connect session management OP iframe (`/oauth2/connect/checkSession`) computes the browser state by reading the session cookie from JavaScript, so it cannot observe the session while `HttpOnly` is enabled. + To reduce cross-site request forgery (CSRF) exposure, OpenAM also sets a `SameSite` attribute on its cookies. A standard installation ships with `org.openidentityplatform.openam.cookie.samesite=Lax`. You can change this to `Strict` or `None` (the latter requires secure cookies) under Configure > Server Defaults > Security > Cookie. diff --git a/openam-documentation/openam-doc-source/src/main/asciidoc/deployment-planning/chap-deployments.adoc b/openam-documentation/openam-doc-source/src/main/asciidoc/deployment-planning/chap-deployments.adoc index 83d0a3e34c..060258029e 100644 --- a/openam-documentation/openam-doc-source/src/main/asciidoc/deployment-planning/chap-deployments.adoc +++ b/openam-documentation/openam-doc-source/src/main/asciidoc/deployment-planning/chap-deployments.adoc @@ -226,7 +226,7 @@ When you first configure OpenAM, there are many options to evaluate, plus a numb * On a server that includes OpenAM Console, all the endpoints defined in the Web application descriptor, `WEB-INF/web.xml`, are available for use. -* To prevent cross-site scripting attacks, you can configure session cookies as HTTP Only by setting the property `com.sun.identity.cookie.httponly=true`. This property prevents third-party scripts from accessing the session cookie. Because the XUI reads the `iPlanetDirectoryPro` SSO cookie from the browser, this property defaults to `false`; enable it only in deployments that do not use the XUI. By default, OpenAM also sets `org.openidentityplatform.openam.cookie.samesite=Lax` to reduce cross-site request forgery (CSRF) exposure. +* To prevent cross-site scripting attacks, you can configure session cookies as HTTP Only by setting the property `com.sun.identity.cookie.httponly=true`. This property prevents third-party scripts from accessing the session cookie. Both the classic UI and the XUI support HttpOnly session cookies, so enabling it is recommended for browser-facing deployments; it defaults to `false` only to preserve the behaviour of existing integrations that read the session cookie, or the `tokenId` from the authentication response body, from script. Two consequences to plan for: the OpenID Connect session management OP iframe (`/oauth2/connect/checkSession`) reads the session cookie from JavaScript and so cannot observe the session while HttpOnly is enabled, and the property is read only at server startup. See xref:../admin-guide/chap-securing.adoc#secure-communications["Securing Communications"] in the __Administration Guide__. By default, OpenAM also sets `org.openidentityplatform.openam.cookie.samesite=Lax` to reduce cross-site request forgery (CSRF) exposure. * You can deploy a reverse proxy within delimitarized zone (DMZ) firewalls to limit exposure of service URLs to the end user as well as block access to back end configuration and user data stores to unauthorized users. diff --git a/openam-documentation/openam-doc-source/src/main/asciidoc/dev-guide/chap-client-dev.adoc b/openam-documentation/openam-doc-source/src/main/asciidoc/dev-guide/chap-client-dev.adoc index f32b150da9..bf0bd9b885 100644 --- a/openam-documentation/openam-doc-source/src/main/asciidoc/dev-guide/chap-client-dev.adoc +++ b/openam-documentation/openam-doc-source/src/main/asciidoc/dev-guide/chap-client-dev.adoc @@ -512,6 +512,12 @@ The `/json/authenticate` endpoint does not support the CRUDPAQ verbs and therefo The simplest user name/password authentication returns a `tokenId` that applications can present as a cookie value for other operations that require authentication. The type of `tokenId` returned varies depending on whether stateless sessions are enabled in the realm to which the user authenticates: +[NOTE] +==== +When the server is configured with HttpOnly session cookies (`com.sun.identity.cookie.httponly=true`), the token is delivered only through the `Set-Cookie` header and `tokenId` is __not__ returned in the response body shown in these examples. Clients that rely on reading `tokenId` from the body should either use the automatically sent cookie instead, or ask the server administrator to set `org.openidentityplatform.openam.httponly.allowTokenInBody` to `true`. See xref:../reference/chap-config-ref.adoc#chap-config-ref["Configuration Reference"] in the __Reference__. +==== + + * If stateless sessions are not enabled, the `tokenId` is an OpenAM SSO token. * If stateless sessions are enabled, the `tokenId` is an OpenAM SSO token that includes an encoded OpenAM session. diff --git a/openam-documentation/openam-doc-source/src/main/asciidoc/reference/chap-config-ref.adoc b/openam-documentation/openam-doc-source/src/main/asciidoc/reference/chap-config-ref.adoc index 294b06134e..c088d7f70e 100644 --- a/openam-documentation/openam-doc-source/src/main/asciidoc/reference/chap-config-ref.adoc +++ b/openam-documentation/openam-doc-source/src/main/asciidoc/reference/chap-config-ref.adoc @@ -5621,7 +5621,10 @@ Default: `3` When set to `true`, mark cookies as HttpOnly to prevent scripts and third-party programs from accessing the cookies. + -Both the classic UI and the XUI support HttpOnly session cookies. When HttpOnly is enabled, the XUI relies on the automatically sent cookie instead of reading the token from JavaScript, and a successful `/json/authenticate` response delivers the token only through the `Set-Cookie` header (the `tokenId` is, by default, no longer returned in the response body). See `org.openidentityplatform.openam.httponly.allowTokenInBody` to control that behaviour. +Both the classic UI and the XUI support HttpOnly session cookies. When HttpOnly is enabled, the XUI relies on the automatically sent cookie instead of reading the token from JavaScript, and a successful `/json/authenticate` response delivers the token only through the `Set-Cookie` header (the `tokenId` is, by default, no longer returned in the response body). See `org.openidentityplatform.openam.httponly.allowTokenInBody` to control that behaviour. The OpenID Connect session management OP iframe (`/oauth2/connect/checkSession`) is a known exception: it reads the session cookie from JavaScript to compute the browser state, and so cannot observe the session while HttpOnly is enabled. + ++ +Changes to this property do not take effect until you restart the OpenAM server. + Default: `false` @@ -6062,6 +6065,9 @@ Set this property to `true` to keep the legacy behaviour of also returning `toke + When the session cookie is not HttpOnly, `tokenId` is always returned in the response body, regardless of this property. ++ +Changes to this property do not take effect until you restart the OpenAM server. + + Default: `false` diff --git a/openam-server-only/src/main/resources/config/validserverconfig.properties b/openam-server-only/src/main/resources/config/validserverconfig.properties index e6c5b4cd7e..d3ae6aca25 100644 --- a/openam-server-only/src/main/resources/config/validserverconfig.properties +++ b/openam-server-only/src/main/resources/config/validserverconfig.properties @@ -38,6 +38,7 @@ com.iplanet.am.console.remote=true,false com.iplanet.am.cookie.c66Encode=true,false com.iplanet.am.cookie.encode=true,false com.sun.identity.cookie.httponly=true,false +org.openidentityplatform.openam.httponly.allowTokenInBody=true,false com.iplanet.am.cookie.name= com.iplanet.am.cookie.secure=true,false org.openidentityplatform.openam.cookie.samesite=Lax,Strict,None diff --git a/openam-server-only/src/main/webapp/WEB-INF/template/sms/serverdefaults.properties b/openam-server-only/src/main/webapp/WEB-INF/template/sms/serverdefaults.properties index 903cf773ad..f369bb0c32 100644 --- a/openam-server-only/src/main/webapp/WEB-INF/template/sms/serverdefaults.properties +++ b/openam-server-only/src/main/webapp/WEB-INF/template/sms/serverdefaults.properties @@ -50,11 +50,17 @@ com.iplanet.am.profile.host=%SERVER_HOST% com.iplanet.am.profile.port=%SERVER_PORT% com.sun.identity.client.notification.url=%SERVER_PROTO%://%SERVER_HOST%:%SERVER_PORT%/%SERVER_URI%/notificationservice com.iplanet.am.daemons=securid -# NOTE: HttpOnly cannot be enabled by default because the XUI reads the -# iPlanetDirectoryPro SSO cookie from document.cookie (see SessionToken.jsm, -# AMConfig.js, AuthNService.js) to track the session and set REST headers. -# Shipping HttpOnly=true here breaks XUI console login. Operators that do not -# use the XUI can safely override this to true. +# NOTE: both the classic UI and the XUI work with HttpOnly session cookies: the +# XUI relies on the automatically sent cookie rather than reading it from +# document.cookie (see SessionToken.jsm), and in HttpOnly mode the token is +# delivered only via Set-Cookie, not echoed as tokenId in the /json/authenticate +# body (override with org.openidentityplatform.openam.httponly.allowTokenInBody). +# The default stays false only to preserve the behaviour of existing integrations +# that read the cookie, or the body tokenId, from script. Enabling it is +# recommended for browser-facing deployments. Two caveats: this value is read +# once at startup (a change needs a server restart), and the OIDC session +# management iframe (/oauth2/connect/checkSession) reads the cookie from +# JavaScript and so cannot observe the session while HttpOnly is enabled. com.sun.identity.cookie.httponly=false com.iplanet.am.cookie.name=iPlanetDirectoryPro com.iplanet.am.cookie.secure=@SECURE_COOKIE@