WICKET-7190 Encrypt URLs deterministically so they stay cacheable

Authenticated encryption draws a random nonce, so re-encrypting the same URL
produced different ciphertext every time. CryptoMapper worked around that with a
per-RequestCycle plaintext -> ciphertext memo: enough to keep URL normalisation
from redirecting endlessly, but it died with the request. Every page view
therefore handed the browser brand-new URLs for every JavaScript, CSS and image
resource. Those responses carry a one-year cache duration, and because the URL
itself changed the browser could not even issue a conditional request, so each
page view re-downloaded every resource; through CSS, whose body embeds resource
URLs, the effect compounded. Wicket 10 did not have this problem, as SunJceCrypt
derived its IV from a per-session salt and was thereby deterministic.

Add an explicit deterministic encryption path to the crypt API and use it for
URLs:

- ICrypt.encryptDeterministic and ICryptScheme.encryptDeterministic. Required
  rather than an opt-in with a random-nonce fallback, so that a scheme cannot
  silently reintroduce the redirect hazard. Both write the existing ciphertext
  format, so decryption is unchanged.
- AbstractAesGcmCryptScheme derives the nonce as
  HMAC(HMAC(key, "wicket-deterministic-nonce"), len(aad) || aad || plaintext)
  truncated to 96 bits, covering AES-256-GCM and AES-256-GCM-SIV alike.
- CryptoMapper encrypts with the deterministic path, which lets the entire memo
  go: ENCRYPTED_URL_CACHE, encryptString, rememberEncryption and
  getEncryptionMemo, along with the verification decrypt they required.

Determinism reveals that two ciphertexts encrypt equal plaintexts, and lets a
key holder confirm a guessed URL. With the default per-session key that stays
confined to a single session, and it is what Wicket 10 already did. The page
store, the "remember me" cookie and the upload token keep randomized nonces.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
12 files changed
tree: 53400a918f401e51ac6eb8da2a1eaeb6f61964c8
  1. .github/
  2. archetypes/
  3. licenses/
  4. testing/
  5. wicket/
  6. wicket-auth-roles/
  7. wicket-bean-validation/
  8. wicket-cdi/
  9. wicket-cdi-tests/
  10. wicket-core/
  11. wicket-core-tests/
  12. wicket-devutils/
  13. wicket-eclipse-settings/
  14. wicket-examples/
  15. wicket-experimental/
  16. wicket-extensions/
  17. wicket-extensions-tester/
  18. wicket-guice/
  19. wicket-ioc/
  20. wicket-jmx/
  21. wicket-migration/
  22. wicket-native-websocket/
  23. wicket-objectsizeof-agent/
  24. wicket-request/
  25. wicket-spring/
  26. wicket-tester/
  27. wicket-user-guide/
  28. wicket-util/
  29. wicket-velocity/
  30. .asf.yaml
  31. .gitignore
  32. build-changelog.sh
  33. build-versions.py
  34. CHANGELOG-10.x
  35. LICENSE
  36. NOTICE
  37. pom.xml
  38. README.md
  39. release.sh
  40. SECURITY.md
  41. wicket-assembly-all.xml
README.md

What is Apache Wicket?

Apache Wicket is an open source, java, component based, web application framework. With proper mark-up/logic separation, a POJO data model, and a refreshing lack of XML, Apache Wicket makes developing web-apps simple and enjoyable again. Swap the boilerplate, complex debugging and brittle code for powerful, reusable components written with plain Java and HTML.

Apache Wicket can be found at https://wicket.apache.org and is licensed under the Apache Software Foundation license, version 2.0.

Getting started

The Wicket project has several resources and projects where you can learn from, and get started quickly:

What does Wicket's download package contain?

You can download Wicket's source package here: https://wicket.apache.org/start/wicket-10.x.html . It contains the source code and the jars of the core projects of Wicket. If you are just starting out, you probably only need to include wicket-util-x.jar, wicket-request-x.jar and wicket-core-x.jar, where x stands for the version. As a rule, use just the jars you need.

You will find the source code here:

|-- apidocs
|   |-- org
|   `-- resources
|-- lib
|-- licenses
`-- src
    |-- archetypes
    |-- testing
    |-- wicket
    |-- wicket-auth-roles
    |-- wicket-bean-validation
    |-- wicket-cdi
    |-- wicket-cdi-tests
    |-- wicket-core
    |-- wicket-tester
    |-- wicket-core-tests
    |-- wicket-devutils
    |-- wicket-eclipse-settings
    |-- wicket-examples
    |-- wicket-experimental
    |   |-- wicket-metrics
    |   |-- wicket-http2
    |-- wicket-extensions
    |-- wicket-guice
    |-- wicket-ioc
    |-- wicket-jmx
    |-- wicket-native-websocket
    |-- wicket-objectssizeof-agent
    |-- wicket-request
    |-- wicket-spring
    |-- wicket-util
    |-- wicket-user-guide
    `-- wicket-velocity

Here is a list of projects in the distribution and what they do.

  • wicket-core: the core project, includes the framework and basic components;
  • wicket-tester: contains common classes for unit testing
  • wicket-core-tests: contains test cases for wicket-core module
  • wicket-extensions: contains utilities and more specialized components;
  • wicket-auth-roles: a basic authorization package based on roles;
  • wicket-jmx: registers JMX beans for managing things like your Wicket configuration and markup cache;
  • wicket-objectssizeof-agent: utility for making better estimates of object sizes in the JVM - most people probably never need this;
  • wicket-ioc: base project for IoC (aka DI) implementations such as Spring and Guice;
  • wicket-spring: support project for using Spring with Wicket and including Spring managed dependencies through using @SpringBean annotations;
  • wicket-guice: support project for using Google Guice with Wicket;
  • wicket-velocity: contains special components for rendering Velocity templates using Wicket components - most people probably don't need this, but it can be neat when you want to do CMS-like things;
  • wicket-examples: contains a basic component reference and many examples of how to use Wicket and Wicket components, including examples for subprojects such as wicket-spring, wicket-velocity and wicket-auth-roles.
  • wicket-devutils: provides small utilities which can help in development phase and during debugging
  • wicket-bean-validation: validates beans with annotation based on javax.validation;
  • wicket-cdi: the context and dependency injection of the jee standard for wicket;
  • wicket-experimental: experimental implementations for wicket;
  • wicket-native-websocket: wicket's native web sockets integration for several servers;
  • wicket-request: lightweight project which contains all classes dealing with request handlers and so on;
  • wicket-util: the util project for wicket;
  • wicket-eclipse-settings: specifies Eclipse settings for a uniform development environment. Most notably the formatting rules;
  • wicket-user-guide: the user guide of wicket
  • wicket-metrics: collects data of a running wicket application
  • wicket-http2: http/2 push support

Dependencies

The easiest way of getting the dependencies of your Wicket based projects right is to use Apache Maven (https://maven.apache.org) with your projects and include the wicket dependencies you want as outlined in the wicket-quickstart. Maven will then take care of including the appropriate dependencies.

If you do not want to use Maven, here is a break-down of the dependencies you need. For the complete and precise reference see the wicket-parent pom.xml in the root folder.

Building Wicket from source

Wicket's source distribution (download package mentioned above) contains also the binaries (jar files) for each of its modules (subprojects). You can use these directly in your applications. The Wicket project uploads the source and JavaDoc jars to the Maven repository used by the Maven build tool as well. So there is actually no specific need to build Wicket yourself from the distribution.

When building using Maven 3, execute one of the following in the root folder:

  • mvn package

    creates wicket-(subproject)-x.y.z.jar(s) in according target subdirectories.

  • mvn install

    creates wicket-(subproject)-x.y.z.jar(s) in according target subdirectories and installs the jar files into your local Maven repository for use in other projects.

Migrating from 9.x

This file is a copy of the migration guide available on our Wiki:

https://cwiki.apache.org/confluence/display/WICKET/Migration+to+Wicket+10.0

Getting help

  • Read the online documentation available on our website (https://wicket.apache.org)

  • Read the migration guide above

  • Read the mailing archives available on Nabble, GMane and Apache

  • Send a complete message containing your problem, stacktrace and problem you're trying to solve to our user list (users@wicket.apache.org)

  • Ask a question on IRC at freenode.net, channel ##wicket

License

Wicket is distributed under the terms of the Apache Software Foundation license, version 2.0. The text is included in the file LICENSE in the root of the project.

Java/Application server requirements

Wicket 10 requires at least Java 17. The application server for running your web application should adhere to the Jakarta Servlet 5 specification or newer.

Cryptographic Software Notice

This distribution includes cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check your country's laws, regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. See http://www.wassenaar.org for more information.

The U.S. Government Department of Commerce, Bureau of Industry and Security (BIS), has classified this software as Export Commodity Control Number (ECCN) 5D002.C.1, which includes information security software using or performing cryptographic functions with asymmetric algorithms. The form and manner of this Apache Software Foundation distribution makes it eligible for export under the License Exception ENC Technology Software Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Section 740.13) for both object code and source code.

The following provides more details on the included cryptographic software:

For encoding HTTP URL data (see org.apache.wicket.core.request.mapper.CryptoMapper) Wicket requires the Java Cryptography extensions (http://java.sun.com/javase/technologies/security/). Wicket does not include these libraries itself, but is designed to use them.