Skip to content

Set the Secure and HttpOnly cookie flags from creation - #1136

Open
vharseko wants to merge 1 commit into
OpenIdentityPlatform:masterfrom
vharseko:cookie-flags-from-creation
Open

vharseko wants to merge 1 commit into
OpenIdentityPlatform:masterfrom
vharseko:cookie-flags-from-creation

Conversation

@vharseko

Copy link
Copy Markdown
Member

The cookie cluster of the CodeQL medium triage: java/insecure-cookie ×19 and java/sensitive-cookie-not-httponly ×7.

What the findings are about

OpenAM sets Secure and HttpOnly from configuration (com.iplanet.am.cookie.secure, com.sun.identity.cookie.httponly), which CodeQL cannot follow as such: it accepts a cookie as secure only when it flows from setSecure(true) or setSecure(request.isSecure()), and as HttpOnly when it flows from a setHttpOnly(x) with x not literally false. Reading the sinks against that model turned up two real gaps rather than only a modelling mismatch:

  • CookieUtils.newCookie set Secure from the property but left HttpOnly to addCookieToResponse, which applied it by reflectionCookie.class.getMethod("setHttpOnly"), a Servlet 2.5 leftover that has been dead code since the move to Jakarta Servlet. 20 of the 26 sinks are cookies built by createCookienewCookie and handed straight to response.addCookie (mostly the logout deletions), which therefore went out without HttpOnly even when it is configured.
  • The LoginServlet and CDCServlet "reset" paths re-added the request's own Cookie object with an empty value. A request cookie carries no path, domain or flags, so the deletion the browser received did not match the cookie that had been set with path / (and, for CDC, the auth-URL cookie domain).

The change

  • CookieUtils.newCookie sets both flags on the cookie as it is created — if (isCookieSecure()) setSecure(true), if (isCookieHttpOnly()) setHttpOnly(true) — so every cookie the helper builds carries them whatever path adds it to the response. addCookieToResponse calls Cookie.setHttpOnly directly; the hand-built Set-Cookie header is kept for the SameSite case only, which the servlet Cookie cannot express. The IdP discovery war's copy of CookieUtils gets the same treatment (it used to write the header by hand for HttpOnly too).
  • LoginServlet: the host-only deletion is built with AuthUtils.createCookie(name, "", null) + maxAge 0, the same way the per-domain deletions next to it already are; the AMTESTCOOKIE probe goes through CookieUtils (only the server reads it back).
  • CDCServlet: the auth-URL cookie is cleared by name, path / and its configured domain instead of re-adding the request object.
  • The Oracle Access Manager and SiteMinder sample adapters (src/main/integrations, not part of the build but scanned under build-mode: none) set their session cookie Secure on an HTTPS request and HttpOnly; their agents read the cookie from the request header, not from script.

No configuration semantics change: a deployment that sets neither property gets exactly the cookies it got before, minus nothing.

Verification

Every new test was watched failing first (expected [true] but found [false] on the HttpOnly-from-creation and servlet-API assertions). openam-shared 1242 tests (6 new), openam-idpdiscovery 12 (4 new), openam-core 2130, openam-federation-library 177 — 0 failures; OpenFM and openam-server-auth-ui compile. The LoginServlet/CDCServlet wiring has no unit test (no servlet harness in those modules), and the two adapters cannot be compiled without the vendor SDKs.

Expected effect on the scan

All 19 insecure-cookie and 7 sensitive-cookie-not-httponly alerts should close: the cookies now flow from a literal setSecure(true) / setHttpOnly(true) in newCookie. Anything left after this PR's scan is a sink that receives a cookie built outside newCookie, to be looked at individually.

CookieUtils.newCookie set Secure from com.iplanet.am.cookie.secure but left
HttpOnly to addCookieToResponse, which applied it by reflection - a Servlet
2.5 leftover - so a cookie handed straight to response.addCookie, as every
logout deletion is, went out without it. Both flags are now set on the
cookie as it is created, from the same properties, and addCookieToResponse
calls Cookie.setHttpOnly directly. The IdP discovery copy of CookieUtils
follows suit.

The remaining cookies built by hand go the same way: the LoginServlet and
CDCServlet deletions are built with the name, path and domain the cookie
was set with instead of re-adding the request's Cookie object, the
AMTESTCOOKIE probe goes through CookieUtils, and the Oracle Access Manager
and SiteMinder sample adapters mark their session cookie Secure on an HTTPS
request and HttpOnly.
@vharseko vharseko added security Security fix or hardening (CVE, GHSA, XSS/CSRF/SSRF) java Pull requests that update java code tests Test suite: coverage, fixtures, or test infrastructure labels Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

java Pull requests that update java code security Security fix or hardening (CVE, GHSA, XSS/CSRF/SSRF) tests Test suite: coverage, fixtures, or test infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant