Skip to content

Validate ID-FF forward targets, FilesRepo identity names and SAML1 POST target - #1128

Open
vharseko wants to merge 2 commits into
OpenIdentityPlatform:masterfrom
vharseko:fix/idff-forward-filesrepo-saml-oauth
Open

vharseko wants to merge 2 commits into
OpenIdentityPlatform:masterfrom
vharseko:fix/idff-forward-filesrepo-saml-oauth

Conversation

@vharseko

@vharseko vharseko commented Sep 14, 2026

Copy link
Copy Markdown
Member

Four independent hardenings from the CodeQL high triage, grouped because each is a few lines.

ID-FF forwards (java/unvalidated-url-forward #196, #197, #198)

FSSingleLogoutServlet (/liberty-logout, unauthenticated) and FSReturnLogoutServlet append the metaAlias request parameter to the /ProcessLogout/metaAlias dispatcher path unchecked, and FSUtils.forwardRequest forwards to any same-host path taken from goto/LRURL. A RequestDispatcher can reach /WEB-INF and does not run the web.xml filters, so metaAlias=/../../WEB-INF/web.xml served the file.

New ForwardPathValidator: no .. segments (path parameters stripped the way the container does), no backslashes or control characters, not under /WEB-INF or /META-INF. The logout servlets answer 400 for a traversing alias, and forwardRequest answers 400 when the target is not a plain in-app path (a rejected target is never a legitimate flow).

FilesRepo (java/path-injection #208, #209; java/regex-injection #164)

constructFile built new File(typeDir, name) straight from the identity name; with a Files data store configured an identity could be created, read or deleted outside the repository. Names containing path separators, NUL, . or .. (or empty/null) now raise IdRepoException(ILLEGAL_ARGUMENTS). FileRepoFileFilter compiled the search pattern as a regex after replacing only *; literal parts are now Pattern.quote()d (a(b no longer throws, user.1 no longer matches userx1).

SAML 1.x POST profile (java/xss #120)

SAMLUtils.postToTarget wrote the target URL into FORM ACTION unescaped; postYN() validates host, port and path but not the query string. Escaped with StringEscapeUtils.escapeHtml4 (commons-lang3, already on the module classpath; a sanitizer CodeQL models).

OAuth module (java/insecure-randomness #173, #174)

The CSRF state token id (CTS key, also the NONCE_TOKEN_ID cookie) came from RandomStringUtils.randomAlphanumeric (java.util.Random). newCsrfStateTokenId() now draws from the module's SecureRandom. The state value itself was already UUID.randomUUID().

CodeQL on this PR

The first revision drew two new findings on the changed lines: the FORM ACTION escaper was not one CodeQL recognises (#489) and the forward guard's redirect fallback reused the request URL (#488). 76ef05a switches to escapeHtml4 and to a 400 response respectively; both threads are answered inline.

Tests

ForwardPathValidatorTest (29 cases), SAMLUtilsTest, FilesRepoTest (13), OAuthTest +1. Full suites of openam-federation-library (73) and openam-auth-oauth2 (5) pass.

Closes CodeQL alerts #120, #164, #173, #174, #196, #197, #198, #208, #209.

…ST target

- FSSingleLogoutServlet (/liberty-logout, unauthenticated) and
  FSReturnLogoutServlet appended the metaAlias request parameter to the
  "/ProcessLogout/metaAlias" dispatcher path unchecked, and
  FSUtils.forwardRequest forwarded to any same-host path taken from
  goto/LRURL. A RequestDispatcher can reach /WEB-INF and skips the web.xml
  filters. Reject aliases with path traversal (400) and redirect instead of
  forwarding when the target is not a plain in-app path
  (ForwardPathValidator).
- FilesRepo built new File(typeDir, name) from the identity name; with a
  Files data store an identity could be created, read or deleted outside the
  repository. Names with path separators, NUL, "." or ".." now raise
  IdRepoException. The search filter quoted nothing but "*", so regex
  metacharacters were interpreted; literal parts are now Pattern.quote()d.
- SAMLUtils.postToTarget wrote the target URL into FORM ACTION unescaped;
  postYN() checks host, port and path but not the query string.
- The OAuth module's CSRF state token id (also the NONCE_TOKEN_ID cookie)
  came from RandomStringUtils.randomAlphanumeric (java.util.Random); use the
  module's SecureRandom.

Closes CodeQL alerts OpenIdentityPlatform#120, OpenIdentityPlatform#164, OpenIdentityPlatform#173, OpenIdentityPlatform#174, OpenIdentityPlatform#196, OpenIdentityPlatform#197, OpenIdentityPlatform#198, OpenIdentityPlatform#208, OpenIdentityPlatform#209
@vharseko vharseko added 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 saml SAML / SAML2 federation oauth2 OAuth2 / OpenID Connect labels Sep 14, 2026
…arget

- FSUtils.forwardRequest: answer 400 instead of redirecting when the forward
  target is rejected; the redirect reused the request-supplied URL.
- SAMLUtils.postToTarget: escape the FORM ACTION with
  StringEscapeUtils.escapeHtml4, which CodeQL recognises as a sanitizer.
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 oauth2 OAuth2 / OpenID Connect saml SAML / SAML2 federation 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.

2 participants