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
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ private static boolean hasCookieExpired(Cookie cookie, long whenCreated) {
}
}

// rfc6265#section-5.1.3
private static boolean domainsMatch(String cookieDomain, String requestDomain) {
return requestDomain.equals(cookieDomain) || requestDomain.endsWith('.' + cookieDomain);
}

// rfc6265#section-5.1.4
private static boolean pathsMatch(String cookiePath, String requestPath) {
return Objects.equals(cookiePath, requestPath) ||
Expand All @@ -175,6 +180,14 @@ private void add(String requestDomain, String requestPath, Cookie cookie) {
AbstractMap.SimpleEntry<String, Boolean> pair = cookieDomain(cookie.domain(), requestDomain);
String keyDomain = pair.getKey();
boolean hostOnly = pair.getValue();

// rfc6265#section-5.3 step 6: ignore a cookie whose Domain attribute is not
// domain-matched by the request host, otherwise a host can plant cookies for
// unrelated domains (cookie tossing).
if (!hostOnly && !domainsMatch(keyDomain, requestDomain)) {
return;
}

String keyPath = cookiePath(cookie.path(), requestPath);
CookieKey key = new CookieKey(cookie.name().toLowerCase(), keyPath);

Expand Down
9 changes: 9 additions & 0 deletions client/src/test/java/org/asynchttpclient/CookieStoreTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public void tearDownGlobal() {
public void runAllSequentiallyBecauseNotThreadSafe() throws Exception {
addCookieWithEmptyPath();
dontReturnCookieForAnotherDomain();
dontStoreCookieForUnrelatedDomainAttribute();
returnCookieWhenItWasSetOnSamePath();
returnCookieWhenItWasSetOnParentPath();
dontReturnCookieWhenDomainMatchesButPathIsDifferent();
Expand Down Expand Up @@ -100,6 +101,14 @@ private static void dontReturnCookieForAnotherDomain() {
assertTrue(store.get(Uri.create("http://www.bar.com")).isEmpty());
}

// rfc6265#section-5.3 step 6: a host must not be able to set a cookie for an unrelated domain
private static void dontStoreCookieForUnrelatedDomainAttribute() {
CookieStore store = new ThreadSafeCookieStore();
store.add(Uri.create("http://www.evil.com/"), ClientCookieDecoder.LAX.decode("SID=attacker; Domain=victim.com"));
assertTrue(store.get(Uri.create("https://victim.com/account")).isEmpty());
assertTrue(store.getAll().isEmpty());
}

private static void returnCookieWhenItWasSetOnSamePath() {
CookieStore store = new ThreadSafeCookieStore();
store.add(Uri.create("http://www.foo.com"), ClientCookieDecoder.LAX.decode("ALPHA=VALUE1; path=/bar/"));
Expand Down