Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,42 @@
<!-- This file is generated, please add to it using `knope document-change` in the client-library-templates repo -->
# Changelog

## 9.10.0 (2026-10-06)

### Features

#### Reject request paths that would leave the configured base URL

The low-level request path was joined onto the configured base URL with a resolving
join, which follows a path the way a browser follows a link. An absolute URL
(`https://host/x`) or a scheme-relative one (`//host/x`) replaced the configured
origin outright while the Authorization header was still attached, so an application
that passed untrusted input as a path could send its API token to a host of someone
else's choosing.

A path that is not a relative reference is now rejected before the join. Paths
containing dot segments remain valid: they resolve against the base URL and cannot
leave its origin.

#### Reject URL parameters that could change which endpoint is addressed

A URL parameter is a single path segment — a resource identity — but the escaping
applied to one varied by language, and in Go, Node, PHP and .NET there was none at
all. A value carrying path syntax could move a request to an endpoint the caller
never asked for: `find("../mandates")` reached the mandates collection, and
`find("?limit=500")` injected a query parameter.

Escaping alone cannot fix this, because `.` and `..` are dot segments that a path
resolver strips whether or not they are encoded, and an empty value addresses the
collection rather than one resource. Values that could change which endpoint is
addressed are therefore rejected rather than escaped: `/`, `?`, `#`, control
characters, `.`, `..` and the empty string now raise an error instead of producing a
request that quietly 404s. Everything else is escaped as before.

No valid GoCardless resource identity contains any of these characters, so correct
code is unaffected. Ruby and Java previously encoded `/` as `%2F` and sent the
request; they now raise.

## 9.9.0 (2026-10-05)

### Features
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ With Maven:
<dependency>
<groupId>com.gocardless</groupId>
<artifactId>gocardless-pro</artifactId>
<version>9.9.0</version>
<version>9.10.0</version>
</dependency>
```

With Gradle:

```
implementation 'com.gocardless:gocardless-pro:9.9.0'
implementation 'com.gocardless:gocardless-pro:9.10.0'
```

## Initializing the client
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ plugins {
sourceCompatibility = 1.8
targetCompatibility = 1.8
group = 'com.gocardless'
version = '9.9.0'
version = '9.10.0'

apply plugin: 'ch.raffael.pegdown-doclet'

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/gocardless/http/HttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class HttpClient {
private static final String DISALLOWED_USER_AGENT_CHARACTERS =
"[^\\w!#$%&'\\*\\+\\-\\.\\^`\\|~]";
private static final String USER_AGENT =
String.format("gocardless-pro-java/9.9.0 java/%s %s/%s %s/%s",
String.format("gocardless-pro-java/9.10.0 java/%s %s/%s %s/%s",
cleanUserAgentToken(System.getProperty("java.vm.specification.version")),
cleanUserAgentToken(System.getProperty("java.vm.name")),
cleanUserAgentToken(System.getProperty("java.version")),
Expand All @@ -49,7 +49,7 @@ public class HttpClient {
builder.put("GoCardless-Version", "2015-07-06");
builder.put("Accept", "application/json");
builder.put("GoCardless-Client-Library", "gocardless-pro-java");
builder.put("GoCardless-Client-Version", "9.9.0");
builder.put("GoCardless-Client-Version", "9.10.0");
HEADERS = builder.build();
}
private final OkHttpClient rawClient;
Expand Down
Loading