Skip to content

Commit a08bb95

Browse files
committed
Backport: reject set-cookie domain that doesn't match the request host
1 parent 9e52c0c commit a08bb95

2 files changed

Lines changed: 22 additions & 0 deletions

File tree

client/src/main/java/org/asynchttpclient/cookie/ThreadSafeCookieStore.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,11 @@ private boolean hasCookieExpired(Cookie cookie, long whenCreated) {
154154
return false;
155155
}
156156

157+
// rfc6265#section-5.1.3
158+
private boolean domainsMatch(String cookieDomain, String requestDomain) {
159+
return requestDomain.equals(cookieDomain) || requestDomain.endsWith('.' + cookieDomain);
160+
}
161+
157162
// rfc6265#section-5.1.4
158163
private boolean pathsMatch(String cookiePath, String requestPath) {
159164
return Objects.equals(cookiePath, requestPath) ||
@@ -164,6 +169,14 @@ private void add(String requestDomain, String requestPath, Cookie cookie) {
164169
AbstractMap.SimpleEntry<String, Boolean> pair = cookieDomain(cookie.domain(), requestDomain);
165170
String keyDomain = pair.getKey();
166171
boolean hostOnly = pair.getValue();
172+
173+
// rfc6265#section-5.3 step 6: ignore a cookie whose Domain attribute is not
174+
// domain-matched by the request host, otherwise a host can plant cookies for
175+
// unrelated domains (cookie tossing).
176+
if (!hostOnly && !domainsMatch(keyDomain, requestDomain)) {
177+
return;
178+
}
179+
167180
String keyPath = cookiePath(cookie.path(), requestPath);
168181
CookieKey key = new CookieKey(cookie.name().toLowerCase(), keyPath);
169182

client/src/test/java/org/asynchttpclient/CookieStoreTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public void tearDownGlobal() {
5555
public void runAllSequentiallyBecauseNotThreadSafe() throws Exception {
5656
addCookieWithEmptyPath();
5757
dontReturnCookieForAnotherDomain();
58+
dontStoreCookieForUnrelatedDomainAttribute();
5859
returnCookieWhenItWasSetOnSamePath();
5960
returnCookieWhenItWasSetOnParentPath();
6061
dontReturnCookieWhenDomainMatchesButPathIsDifferent();
@@ -93,6 +94,14 @@ private void addCookieWithEmptyPath() {
9394
assertTrue(store.get(uri).size() > 0);
9495
}
9596

97+
// rfc6265#section-5.3 step 6: a host must not be able to set a cookie for an unrelated domain
98+
private void dontStoreCookieForUnrelatedDomainAttribute() {
99+
CookieStore store = new ThreadSafeCookieStore();
100+
store.add(Uri.create("http://www.evil.com/"), ClientCookieDecoder.LAX.decode("SID=attacker; Domain=victim.com"));
101+
assertTrue(store.get(Uri.create("https://victim.com/account")).isEmpty());
102+
assertTrue(store.getAll().isEmpty());
103+
}
104+
96105
private void dontReturnCookieForAnotherDomain() {
97106
CookieStore store = new ThreadSafeCookieStore();
98107
store.add(Uri.create("http://www.foo.com"), ClientCookieDecoder.LAX.decode("ALPHA=VALUE1; path="));

0 commit comments

Comments
 (0)