diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7e51216..9693ae4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,9 +6,16 @@ UTC where a release record exists; older announcement/tag dates are labeled.
An open proposal is not a release. Historical tags, assets and signatures remain
unchanged. [1.4.1 is also available from Central](releases/1.4.1-central-publication.md).
-## Unreleased — 1.5.0
+## Unreleased
-Development builds use `1.5.0-SNAPSHOT`; this is not a published release.
+No changes are recorded after 1.5.0 yet.
+
+## 1.5.0 — 2026-09-28 UTC
+
+This is a security release for
+[GHSA-g8p6-7r8f-qrpv](https://github.com/OWASP/owasp-java-encoder/security/advisories/GHSA-g8p6-7r8f-qrpv).
+Signed artifact availability and independent verification are tracked in the
+[1.5.0 release record](releases/1.5.0.md).
* build: stop Dependabot from recreating already-reviewed incompatible API,
servlet-engine and build-tool version proposals. The ignores are limited to
diff --git a/README.md b/README.md
index e217467..bc674bd 100644
--- a/README.md
+++ b/README.md
@@ -9,21 +9,16 @@ has no runtime dependencies; optional JSP and Jakarta adapters provide view-laye
bindings. Encoding is one part of [XSS prevention][xss], alongside
safe templates, URL validation and other application controls.
-**Upgrade all Java Encoder artifacts to 1.4.1. Versions through 1.4.0 are affected
-by the [security issues fixed in 1.4.1](releases/1.4.1.md#security-fixes).**
-Version 1.4.1 is available from [Maven Central](https://repo.maven.apache.org/maven2/org/owasp/encoder/)
-and the signed [GitHub release][release]. All published artifacts and signatures
-[match the retained release](releases/1.4.1-central-publication.md). See
-[VERIFYING.md](VERIFYING.md) for verification instructions.
-
-`main` is **unreleased 1.5.0-SNAPSHOT**. Its JSON API, JavaScript template support,
-XML 1.1 tag bindings, and parser-boundary fixes are described below with version
-labels; they are not features of the signed 1.4.1 release. See
-[CHANGELOG.md](CHANGELOG.md).
+**Release preparation:** version 1.5.0 fixes parser-boundary vulnerabilities in
+JavaScript-in-HTML, CDATA, and XML-comment fragment composition. Versions through
+1.4.1 do not contain those fixes. The signed 1.5.0 artifacts are not available
+until the maintainers complete the release gates and update this notice with the
+verified GitHub and Maven Central links. See the [1.5.0 release notes](releases/1.5.0.md)
+and [VERIFYING.md](VERIFYING.md).
## Start using the OWASP Java Encoders
-Select the dependency you need; Maven resolves version 1.4.1 from Central.
+After 1.5.0 publication is independently verified, select the dependency you need.
The three supported artifacts use group ID `org.owasp.encoder`:
| Artifact ID | Purpose and runtime dependencies |
@@ -36,7 +31,7 @@ The three supported artifacts use group ID `org.owasp.encoder`:
org.owasp.encoder
encoder
- 1.4.1
+ 1.5.0
```
@@ -44,8 +39,8 @@ Replace `encoder` with one tag adapter artifact ID when needed; each adapter bri
in core. Keep separately managed core/adapter versions aligned. Use **one** of the
javax or Jakarta taglib JARs: they share `org.owasp.encoder.tag` and must not coexist
on the same classpath or module path. See the [runtime matrix](compatibility/README.md) and
-[dependency/license inventory](docs/dependencies.md). Development snapshots are
-not security releases or a substitute for the signed 1.4.1 artifacts.
+[dependency/license inventory](docs/dependencies.md). Do not use the example version
+until its signed artifacts and Central availability have been verified.
`encoder-esapi` was retired after 1.4.1 and will not be published or supported in
1.5.0. Applications using it must [migrate away from the adapter](docs/encoder-esapi-retirement.md).
@@ -111,7 +106,7 @@ Java source generation is not a JSP context. XML 1.1 bindings are new in 1.5.
## Migrating from forUri
-`Encode.forUri` is deprecated in the released API. **Unreleased 1.5** extends
+`Encode.forUri` is deprecated in the released API. Version 1.5.0 extends
that deprecation to `Encoders.URI`, both `ForUriTag` classes and the `forUri`
tag/function documentation. All of these entry points are retained through 1.x. Encoding a whole URI does not validate it:
`forUri("javascript:alert(1)")` returns it unchanged. Existing `%` signs are encoded
@@ -173,4 +168,4 @@ links distinguish maintainer support from OWASP Foundation donations.
[xss]: https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
[java-libraries]: https://devguide.owasp.org/en/05-implementation/03-secure-libraries/04-java-secure-libs/
[project]: https://owasp.org/projects/java-encoder
-[release]: https://github.com/OWASP/owasp-java-encoder/releases/tag/v1.4.1
+[release]: https://github.com/OWASP/owasp-java-encoder/releases/tag/v1.5.0
diff --git a/RELEASING.md b/RELEASING.md
index cf59fb2..b93f0dd 100644
--- a/RELEASING.md
+++ b/RELEASING.md
@@ -6,8 +6,9 @@ Do not tag, publish, or announce a 1.5 release until **all open issues and all
open pull requests have been handled**. Before considering release approval,
inventory the full open backlog and record the outcome and supporting review
or verification for every item. Completing a maintenance batch does not satisfy
-this gate on its own. Keep 1.5 development at `1.5.0-SNAPSHOT`; snapshot version
-changes and reviewed maintenance merges are not release approval.
+this gate on its own. Keep 1.5 development at `1.5.0-SNAPSHOT` until maintainers
+deliberately create the exact release commit after the technical gates pass.
+Changing that commit to `1.5.0` is release preparation, not release approval.
The [2026-09-26 maintenance closeout](releases/maintenance-closeout.md) records
the final backlog inventory and dispositions for #110 and #169. A closed tracker
diff --git a/SECURITY.md b/SECURITY.md
index 7f37ffc..92fb8aa 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,26 +2,29 @@
## Supported Versions
-Version **1.4.1** is available from [Maven Central](https://repo.maven.apache.org/maven2/org/owasp/encoder/)
-and as signed artifacts from the [GitHub security release](https://github.com/OWASP/owasp-java-encoder/releases/tag/v1.4.1).
-The Central artifacts and signatures [match the retained release](releases/1.4.1-central-publication.md).
+Version **1.5.0** is the prepared security release. Do not treat it as available
+until the signed GitHub artifacts and Maven Central publication have been
+independently verified and this paragraph is updated with the exact links and date.
Only the latest 1.x release receives security fixes. Fixes ship in a new release;
older release lines are not patched.
| Maven coordinate | Supported | Not supported |
| --------------------------------------- | --------- | ------------- |
-| `org.owasp.encoder:encoder` | 1.4.1 | < 1.4.1 |
-| `org.owasp.encoder:encoder-jsp` | 1.4.1 | < 1.4.1 |
-| `org.owasp.encoder:encoder-jakarta-jsp` | 1.4.1 | < 1.4.1 |
+| `org.owasp.encoder:encoder` | 1.5.0 | < 1.5.0 |
+| `org.owasp.encoder:encoder-jsp` | 1.5.0 | < 1.5.0 |
+| `org.owasp.encoder:encoder-jakarta-jsp` | 1.5.0 | < 1.5.0 |
The optional `org.owasp.encoder:encoder-esapi` artifact is retired. Version
1.4.1 is its final published release, no version is currently supported, and no
1.5.0 artifact will be published. See the [retirement and migration notice](docs/encoder-esapi-retirement.md).
-Upgrading the core `encoder` artifact to the latest 1.x release needs no code changes:
-no public API was removed between 1.2.3 and 1.4.1. It does need Java 8 or later;
-1.2.3 and earlier also ran on Java 5 through 7.
+The three retained artifacts (`encoder`, `encoder-jsp`, and
+`encoder-jakarta-jsp`) remove no public API in 1.5.0. The separately published
+`encoder-esapi` API ends at 1.4.1 as described above. Security corrections also
+intentionally change encoded output in several contexts. Read the [compatibility
+and migration record](docs/compatibility-decisions.md) before upgrading. Version
+1.5.0 needs Java 8 or later; 1.2.3 and earlier also ran on Java 5 through 7.
## Reporting a Vulnerability
@@ -81,7 +84,7 @@ release tag, then verify:
```sh
gpg --import KEYS
-gpg --verify encoder-1.4.1.jar.asc encoder-1.4.1.jar
+gpg --verify encoder-1.5.0.jar.asc encoder-1.5.0.jar
shasum -a 256 -c SHA256SUMS
shasum -a 512 -c SHA512SUMS
```
diff --git a/compatibility/README.md b/compatibility/README.md
index 342cc9a..485c57f 100644
--- a/compatibility/README.md
+++ b/compatibility/README.md
@@ -135,9 +135,9 @@ multi-release layout remain unchanged.
## Published identities and development import ranges
-The tables below describe the current **1.5 development** artifacts. The names
-are historical identities preserved in 1.x; the OSGi import floors reflect the
-new 1.5 calls and must not be projected onto older published JARs.
+The tables below describe the prepared **1.5.0** artifacts. The names are
+historical identities preserved in 1.x; the OSGi import floors reflect the new
+1.5 calls and must not be projected onto older published JARs.
### Java 9+ module names
diff --git a/core/pom.xml b/core/pom.xml
index 3b29f48..a7df0d7 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -42,7 +42,7 @@
org.owasp.encoder
encoder-parent
- 1.5.0-SNAPSHOT
+ 1.5.0
encoder
diff --git a/docs/contexts.md b/docs/contexts.md
index b41a3c9..fd2346e 100644
--- a/docs/contexts.md
+++ b/docs/contexts.md
@@ -1,12 +1,13 @@
# Output contexts and boundaries
-This guide describes current `main` (unreleased **1.5**); feature introductions
-are marked below. For production use, follow the [1.4.1 distribution and security
-notice](../README.md). The [Encode Javadoc source](../core/src/main/java/org/owasp/encoder/Encode.java)
-is the detailed per-method contract; each method has a String-returning and a
-`(Writer out, String input)` overload. `Encoders` exposes shared stateless
-encoders; `EncodedWriter` supports chunked input and must be closed to finish
-pending input. Use the facade Writer overload when encoding one String directly.
+This guide describes version **1.5.0**; feature introductions are marked below.
+Do not treat that version as available until the [release-preparation notice](../README.md)
+is updated with independently verified signed artifacts and Maven Central links.
+The [Encode Javadoc source](../core/src/main/java/org/owasp/encoder/Encode.java) is
+the detailed per-method contract; each method has a String-returning and a
+`(Writer out, String input)` overload. `Encoders` exposes shared stateless encoders;
+`EncodedWriter` supports chunked input and must be closed to finish pending input.
+Use the facade Writer overload when encoding one String directly.
## Encode for the parser that receives the value
@@ -60,8 +61,8 @@ continue to support single- and double-quoted strings in their documented contex
This does **not** support tagged templates such as `String.raw`, or insertion
inside a `${...}` expression. Tagged templates can observe raw escape text.
Do not use a 1.4.1 JavaScript encoder for template-literal text: this support is
-unreleased 1.5 behavior. The old IE grave-accent/`innerHTML` workaround is a
-separate historical browser issue, not a substitute for this contract. The
+introduced in 1.5.0. The old IE grave-accent/`innerHTML` workaround is a separate
+historical browser issue, not a substitute for this contract. The
[wiki archive](archive/wiki-2019/README.md) records why that advice was retired.
In 1.5, DEL/C1 controls use hex escapes and unpaired UTF-16 surrogates use Unicode
diff --git a/docs/dependencies.md b/docs/dependencies.md
index 7e15933..4e9bad4 100644
--- a/docs/dependencies.md
+++ b/docs/dependencies.md
@@ -17,7 +17,8 @@ unsupported; see the [retirement and migration notice](encoder-esapi-retirement.
## Consumer dependency inventory — 2026-09-27
Generated from dependency-plugin 3.11.0's resolved reactor `dependency:tree`
-JSON for current `1.5.0-SNAPSHOT`. This inventory includes the publishable
+JSON for the reviewed `1.5.0-SNAPSHOT` candidate. Release preparation does not
+change the published dependency graph. This inventory includes the publishable
modules' compile/runtime and provided scopes, excludes test/plugin dependencies
and this project's own BSD-3-Clause modules, and identifies the consuming module.
diff --git a/docs/usage.md b/docs/usage.md
index 5660dac..30a36ae 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -1,8 +1,9 @@
# Java and JSP examples
-Use the [verified signed 1.4.1 distribution](../README.md#start-using-the-owasp-java-encoders)
-for production. The examples here use APIs available in that release unless
-explicitly marked **1.5**. New features on `main` remain unreleased.
+These examples target version **1.5.0**. Do not use that coordinate until the
+[release-preparation notice](../README.md) is updated with independently verified
+signed artifacts and Maven Central links. Features marked **1.5** are new in this
+release.
## HTML and Writer output
@@ -128,7 +129,7 @@ and the [packaged JSP engine checks](../compatibility/jsp-engine/README.md).
## Java modules
The explicit module name for core is `owasp.encoder`. After verifying and obtaining
-`encoder-1.4.1.jar`, put that unchanged JAR in `lib/`, then create:
+`encoder-1.5.0.jar`, put that unchanged JAR in `lib/`, then create:
`src/example.app/module-info.java`:
diff --git a/jakarta-test/pom.xml b/jakarta-test/pom.xml
index 1c2b0a9..2c0f5ed 100644
--- a/jakarta-test/pom.xml
+++ b/jakarta-test/pom.xml
@@ -28,7 +28,7 @@
4.49.0
- 1.5.0-SNAPSHOT
+ 1.5.0
diff --git a/jakarta/pom.xml b/jakarta/pom.xml
index f1b6ce6..ce346b8 100644
--- a/jakarta/pom.xml
+++ b/jakarta/pom.xml
@@ -42,7 +42,7 @@
org.owasp.encoder
encoder-parent
- 1.5.0-SNAPSHOT
+ 1.5.0
encoder-jakarta-jsp
diff --git a/jsp/pom.xml b/jsp/pom.xml
index 97047c0..ee3829c 100644
--- a/jsp/pom.xml
+++ b/jsp/pom.xml
@@ -42,7 +42,7 @@
org.owasp.encoder
encoder-parent
- 1.5.0-SNAPSHOT
+ 1.5.0
encoder-jsp
diff --git a/pom.xml b/pom.xml
index df2fdd6..73c485d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,7 +41,7 @@
org.owasp.encoder
encoder-parent
- 1.5.0-SNAPSHOT
+ 1.5.0
pom
OWASP Java Encoder Project
@@ -78,7 +78,7 @@
scm:git:git@github.com:OWASP/owasp-java-encoder.git
scm:git:https://github.com/OWASP/owasp-java-encoder.git
https://github.com/OWASP/owasp-java-encoder
- HEAD
+ v1.5.0
@@ -114,8 +114,8 @@
-
- 2026-09-26T00:00:00Z
+
+ 2026-09-28T13:21:37Z
UTF-8
UTF-8
` tokens supplied partly by trusted
+ adjacent text. CDATA and XML-comment encoders likewise prevent cross-fragment
+ `]]>` and `--` formation. Versions through 1.4.1 do not contain these fixes.
+- `EncodedWriter` now has consistent close/finalization behavior and overflow-safe
+ array-slice validation.
+- JSON encoding and matching JSP/Jakarta tags and EL functions are added.
+- The optional `encoder-esapi` adapter is retired. Version 1.4.1 is its final
+ published release; it is unsupported and there is no `encoder-esapi:1.5.0`.
+
+This security release is tracked by
+[GHSA-g8p6-7r8f-qrpv](https://github.com/OWASP/owasp-java-encoder/security/advisories/GHSA-g8p6-7r8f-qrpv).
+The advisory must remain private until fixed artifacts are available, then be
+published before the public announcement.
+
+## Compatibility and migration
+
+The public Java APIs of `encoder`, `encoder-jsp`, and `encoder-jakarta-jsp` are
+binary and source compatible with 1.4.1. Runtime bytecode remains Java 8; packaged
+consumers are required on Java 8, 11, 17, 21, and 25. The release build requires
+the exact Eclipse Temurin 17.0.20.1+1 and Maven wrapper 3.9.16 toolchain.
+
+Security corrections intentionally change observable output:
+
+- HTML/general and block JavaScript output uses additional hexadecimal escapes
+ while preserving the JavaScript string value. It can grow materially; review
+ output-size budgets as well as byte snapshots, signatures, and cache keys.
+- CDATA preserves parsed text but can expand to 13 output characters per input
+ character and may change parser event boundaries.
+- XML-comment hyphens become `~`; comment text changes by documented policy.
+
+Review the [parser-boundary migration record](../docs/compatibility-decisions.md#15-parser-boundary-output-migration)
+and [context guide](../docs/contexts.md). Applications using `encoder-esapi` must
+follow the [retirement guide](../docs/encoder-esapi-retirement.md); mixing its 1.4.1
+artifact with the 1.5 core is not a supported migration.
+
+## Changes
+
+### Added
+
+- `Encode.forJson`, Writer/registry support, and JSP/Jakarta JSON bindings.
+- XML 1.1 JSP and Jakarta bindings.
+- Parser-oracle, boundary-partition, streaming, packaged-consumer, metadata, and
+ release-policy regressions.
+
+### Fixed
+
+- Cross-fragment outer-parser token formation in JavaScript-in-HTML, CDATA, and
+ XML comments.
+- `EncodedWriter` lifecycle, simultaneous-failure, and slice-validation behavior.
+- U+0085 handling, JavaScript surrogate/control handling, and OSGi import floors.
+- Public-API comparison baseline and child effective-POM SCM metadata.
+
+### Changed or deprecated
+
+- `encoder-esapi` is removed from the reactor and release inventory.
+- `Encoders.URI`, the URI tags, and their documentation now match the existing
+ `Encode.forUri` deprecation; use `forUriComponent` for one raw component.
+
+### Build and documentation
+
+- Active build-plugin dependency closures are updated and GitHub dependency
+ submission reports only tooling actually executed by each gate. No dependency
+ alert is dismissed or suppressed.
+- The JSP provided API is updated to 2.3.3 while a separate 2.2.1 minimum-consumer
+ fixture remains. Jakarta reactor tests use Servlet 6.1.0 and EL 6.0.1 while
+ their older compatibility inputs remain explicit for japicmp and Java 8 checks.
+- Dependabot scans the Maven reactor once. Scoped routine-version rules prevent
+ recreation of reviewed incompatible API, servlet-engine, and tool-major
+ proposals without suppressing security updates.
+- Release payload accounting is three libraries, nine binary/source/Javadoc JARs,
+ four POMs, 13 signed payloads, and 52 checksum files.
+
+See [CHANGELOG.md](../CHANGELOG.md) for the complete issue-linked list.
+
+## Coordinates and availability
+
+Group `org.owasp.encoder`, version `1.5.0`:
+
+- `encoder`
+- `encoder-jsp`
+- `encoder-jakarta-jsp`
+- parent `encoder-parent`
+
+The optional `jakarta-test` WAR and `encoder-esapi` are not published. Add exact
+Central and signed GitHub-release links only after those artifacts have been
+downloaded and verified independently.
+
+## Verification and evidence
+
+Run the following from the exact release commit, using clean private directories
+and the reference toolchain described in [RELEASING.md](../RELEASING.md):
+
+```sh
+python3 scripts/check-ci-version.py --ref refs/tags/v1.5.0
+python3 -m unittest discover -s scripts/tests
+./mvnw -B -ntp clean verify -PtestJakarta
+python3 scripts/check-effective-pom-scm.py
+python3 compatibility/consumers.py prepare --directory --repository
+python3 compatibility/consumers.py run --directory --runtime <8|11|17|21|25> --java-home
+python3 -m unittest discover -s compatibility/tests
+python3 scripts/check-reproducible.py --commit --directory
+git diff --check ^
+```
+
+The release owner must record the exact command environments, exits, test counts,
+CI URLs, dependency snapshots, artifact hashes, and reproducibility comparison.
+The signing identity is expected to be the independently verified full primary
+fingerprint `1C5F632B86809F2F5DB25092BEA0075F94074A9B`; verify it again rather than
+trusting this text.
+
+Before creating the release commit, replace the provisional
+`project.build.outputTimestamp` with that commit's exact UTC timestamp. Then
+record the exact release SHA in the external release evidence (and, if desired,
+in a later documentation commit), create and verify the signed `v1.5.0` tag on
+that SHA, assemble the signed bundle with `scripts/package-release.py`, and update
+this status only after GitHub and Central publication checks succeed.