Skip to content

Commit 83ec004

Browse files
authored
Update redirect policy to clear auth header (Azure#27838)
1 parent f8047b1 commit 83ec004

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

sdk/core/azure-core/src/main/java/com/azure/core/http/policy/RedirectPolicy.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,13 @@ private Mono<HttpResponse> attemptRedirect(final HttpPipelineCallContext context
6262
if (redirectStrategy.shouldAttemptRedirect(context, httpResponse, redirectAttempt,
6363
attemptedRedirectUrls)) {
6464
HttpRequest redirectRequestCopy = redirectStrategy.createRedirectRequest(httpResponse);
65-
return httpResponse.getBody()
65+
66+
// Clear the authorization header to avoid the client to be redirected to an untrusted third party server
67+
// causing it to leak your authorization token to.
68+
httpResponse.getHeaders().remove("Authorization");
69+
70+
return httpResponse
71+
.getBody()
6672
.ignoreElements()
6773
.then(attemptRedirect(context, next, redirectRequestCopy, redirectAttempt + 1, attemptedRedirectUrls));
6874
} else {

sdk/core/azure-core/src/test/java/com/azure/core/http/policy/RedirectPolicyTest.java

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import com.azure.core.http.MockHttpResponse;
1414
import com.azure.core.http.clients.NoOpHttpClient;
1515
import org.junit.jupiter.api.Test;
16+
import org.junit.jupiter.params.ParameterizedTest;
17+
import org.junit.jupiter.params.provider.ValueSource;
1618
import reactor.core.publisher.Mono;
1719

1820
import java.net.MalformedURLException;
@@ -25,6 +27,7 @@
2527
import java.util.function.Function;
2628

2729
import static org.junit.jupiter.api.Assertions.assertEquals;
30+
import static org.junit.jupiter.api.Assertions.assertNull;
2831

2932
public class RedirectPolicyTest {
3033

@@ -53,14 +56,16 @@ public Mono<HttpResponse> send(HttpRequest request) {
5356
assertEquals(308, response.getStatusCode());
5457
}
5558

56-
@Test
57-
public void defaultRedirectWhen308() throws Exception {
59+
@ParameterizedTest
60+
@ValueSource(ints = {308, 307, 301, 302})
61+
public void defaultRedirectExpectedStatusCodes(int statusCode) throws Exception {
5862
RecordingHttpClient httpClient = new RecordingHttpClient(request -> {
5963
if (request.getUrl().toString().equals("http://localhost/")) {
6064
Map<String, String> headers = new HashMap<>();
6165
headers.put("Location", "http://redirecthost/");
66+
headers.put("Authorization", "12345");
6267
HttpHeaders httpHeader = new HttpHeaders(headers);
63-
return Mono.just(new MockHttpResponse(request, 308, httpHeader));
68+
return Mono.just(new MockHttpResponse(request, statusCode, httpHeader));
6469
} else {
6570
return Mono.just(new MockHttpResponse(request, 200));
6671
}
@@ -74,8 +79,8 @@ public void defaultRedirectWhen308() throws Exception {
7479
HttpResponse response = pipeline.send(new HttpRequest(HttpMethod.GET,
7580
new URL("http://localhost/"))).block();
7681

77-
// assertEquals(2, httpClient.getCount());
7882
assertEquals(200, response.getStatusCode());
83+
assertNull(response.getHeaders().getValue("Authorization"));
7984
}
8085

8186
@Test
@@ -326,6 +331,32 @@ public Mono<HttpResponse> send(HttpRequest request) {
326331
assertEquals(401, response.getStatusCode());
327332
}
328333

334+
@Test
335+
public void defaultRedirectAuthorizationHeaderCleared() throws Exception {
336+
RecordingHttpClient httpClient = new RecordingHttpClient(request -> {
337+
if (request.getUrl().toString().equals("http://localhost/")) {
338+
Map<String, String> headers = new HashMap<>();
339+
headers.put("Location", "http://redirecthost/");
340+
headers.put("Authorization", "12345");
341+
HttpHeaders httpHeader = new HttpHeaders(headers);
342+
return Mono.just(new MockHttpResponse(request, 308, httpHeader));
343+
} else {
344+
return Mono.just(new MockHttpResponse(request, 200));
345+
}
346+
});
347+
348+
HttpPipeline pipeline = new HttpPipelineBuilder()
349+
.httpClient(httpClient)
350+
.policies(new RedirectPolicy())
351+
.build();
352+
353+
HttpResponse response = pipeline.send(new HttpRequest(HttpMethod.GET,
354+
new URL("http://localhost/"))).block();
355+
356+
assertEquals(200, response.getStatusCode());
357+
assertNull(response.getHeaders().getValue("Authorization"));
358+
}
359+
329360
static class RecordingHttpClient implements HttpClient {
330361

331362
private final AtomicInteger count = new AtomicInteger();

0 commit comments

Comments
 (0)