diff --git a/pom.xml b/pom.xml
index 230865e0cd..cdb5f4ef7b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1430,6 +1430,9 @@
Vladimir Babin
vovababin@gmail.com
+
+ Vidya m
+
diff --git a/src/main/java/org/htmlunit/WebClient.java b/src/main/java/org/htmlunit/WebClient.java
index 29a8be9e7e..87b8032fe8 100644
--- a/src/main/java/org/htmlunit/WebClient.java
+++ b/src/main/java/org/htmlunit/WebClient.java
@@ -153,6 +153,7 @@
* @author René Schwietzke
* @author Sven Strickroth
* @author Ashutosh Panda
+ * @author Vidya m
*/
@SuppressWarnings("PMD.TooManyFields")
public class WebClient implements Serializable, AutoCloseable {
@@ -1711,6 +1712,8 @@ && getOptions().isRedirectEnabled()
+ webResponse.getWebRequest().getUrl(), webResponse);
}
+ final boolean crossOriginRedirect = !UrlUtils.isSameOrigin(url, newUrl);
+
if (status == HttpStatus.MOVED_PERMANENTLY_301
|| status == HttpStatus.FOUND_302
|| status == HttpStatus.SEE_OTHER_303) {
@@ -1723,6 +1726,10 @@ && getOptions().isRedirectEnabled()
for (final Map.Entry entry : webRequest.getAdditionalHeaders().entrySet()) {
wrs.setAdditionalHeader(entry.getKey(), entry.getValue());
}
+ if (crossOriginRedirect) {
+ // credentials are not forwarded to another origin
+ wrs.removeAdditionalHeader("Authorization");
+ }
wrs.setFetchDestination(webRequest.getFetchDestination());
wrs.setFetchModeOverride(webRequest.getFetchModeOverride());
wrs.setRequestingUrl(webRequest.getRequestingUrl());
@@ -1751,6 +1758,10 @@ else if (status == HttpStatus.TEMPORARY_REDIRECT_307
for (final Map.Entry entry : webRequest.getAdditionalHeaders().entrySet()) {
wrs.setAdditionalHeader(entry.getKey(), entry.getValue());
}
+ if (crossOriginRedirect) {
+ // credentials are not forwarded to another origin
+ wrs.removeAdditionalHeader("Authorization");
+ }
return loadWebResponseFromWebConnection(wrs, allowedRedirects - 1);
}
diff --git a/src/main/java/org/htmlunit/html/HtmlPage.java b/src/main/java/org/htmlunit/html/HtmlPage.java
index eb10ac6724..5a0cbe7bf7 100644
--- a/src/main/java/org/htmlunit/html/HtmlPage.java
+++ b/src/main/java/org/htmlunit/html/HtmlPage.java
@@ -143,6 +143,7 @@
* @author Ronny Shapiro
* @author Lai Quang Duong
* @author Sven Strickroth
+ * @author Vidya m
*/
@SuppressWarnings("PMD.TooManyFields")
public class HtmlPage extends SgmlPage {
@@ -1105,6 +1106,10 @@ private Object loadJavaScriptFromUrl(final URL url, final Charset scriptCharset,
final WebRequest request = new WebRequest(url);
// copy all headers from the referring request
request.setAdditionalHeaders(new HashMap<>(referringRequest.getAdditionalHeaders()));
+ if (!UrlUtils.isSameOrigin(referringRequest.getUrl(), url)) {
+ // credentials are not forwarded to another origin
+ request.removeAdditionalHeader("Authorization");
+ }
// at least overwrite this headers
request.setAdditionalHeader(HttpHeader.ACCEPT, client.getBrowserVersion().getScriptAcceptHeader());
diff --git a/src/test/java/org/htmlunit/WebClientTest.java b/src/test/java/org/htmlunit/WebClientTest.java
index 92ae189b2f..a34c483c75 100644
--- a/src/test/java/org/htmlunit/WebClientTest.java
+++ b/src/test/java/org/htmlunit/WebClientTest.java
@@ -74,6 +74,7 @@
* @author Ronald Brill
* @author Carsten Steul
* @author Joerg Werner
+ * @author Vidya m
*/
public class WebClientTest extends SimpleWebTestCase {
@@ -526,6 +527,39 @@ private void redirection_AdditionalHeadersMaintained(final int statusCode) throw
assertEquals("bar", conn.getLastAdditionalHeaders().get("foo"));
}
+ /**
+ * Verifies that the "Authorization" header of the original {@link WebRequest} is only
+ * sent to the redirect location if the redirect does not leave the origin.
+ * @throws Exception if an error occurs
+ */
+ @Test
+ public void redirection_AuthorizationHeaderDroppedForCrossOrigin() throws Exception {
+ for (final int statusCode : new int[] {301, 302, 303, 307, 308}) {
+ redirection_AuthorizationHeader(statusCode, URL_SECOND, "Bearer secret");
+ redirection_AuthorizationHeader(statusCode, URL_THIRD, null);
+ }
+ }
+
+ private void redirection_AuthorizationHeader(final int statusCode, final URL redirectUrl,
+ final String expectedAuthorization) throws Exception {
+ final WebClient client = getWebClient();
+ final MockWebConnection conn = new MockWebConnection();
+ client.setWebConnection(conn);
+
+ final List headers = asList(new NameValuePair("Location", redirectUrl.toString()));
+ conn.setResponse(URL_FIRST, "", statusCode, "", MimeType.TEXT_HTML, headers);
+ conn.setResponse(redirectUrl, DOCTYPE_HTML + "abc");
+
+ final WebRequest request = new WebRequest(URL_FIRST);
+ request.setAdditionalHeader("Authorization", "Bearer secret");
+ request.setAdditionalHeader("foo", "bar");
+ client.getPage(request);
+
+ assertEquals(redirectUrl, conn.getLastWebRequest().getUrl());
+ assertEquals(expectedAuthorization, conn.getLastAdditionalHeaders().get("Authorization"));
+ assertEquals("bar", conn.getLastAdditionalHeaders().get("foo"));
+ }
+
/**
* Basic logic for all the redirection tests.
*
diff --git a/src/test/java/org/htmlunit/html/HtmlScriptTest.java b/src/test/java/org/htmlunit/html/HtmlScriptTest.java
index 729106bcaa..cf5bb989d2 100644
--- a/src/test/java/org/htmlunit/html/HtmlScriptTest.java
+++ b/src/test/java/org/htmlunit/html/HtmlScriptTest.java
@@ -25,6 +25,7 @@
import org.htmlunit.MockWebConnection;
import org.htmlunit.SimpleWebTestCase;
import org.htmlunit.WebClient;
+import org.htmlunit.WebRequest;
import org.htmlunit.junit.annotation.Alerts;
import org.htmlunit.util.MimeType;
import org.junit.jupiter.api.Test;
@@ -37,6 +38,7 @@
* @author Ahmed Ashour
* @author Ronald Brill
* @author Ronny Shapiro
+ * @author Vidya m
*/
public class HtmlScriptTest extends SimpleWebTestCase {
@@ -83,6 +85,41 @@ public void badExternalScriptReference() throws Exception {
}
}
+ /**
+ * Verifies that the "Authorization" header of the page request is only sent
+ * with the request for an external script if the script has the same origin.
+ * @throws Exception if an error occurs
+ */
+ @Test
+ public void authorizationHeaderNotSentToCrossOriginScript() throws Exception {
+ externalScriptAuthorizationHeader(new URL(URL_FIRST, "script.js"), "Bearer secret");
+ externalScriptAuthorizationHeader(new URL(URL_THIRD, "script.js"), null);
+ }
+
+ private void externalScriptAuthorizationHeader(final URL scriptUrl,
+ final String expectedAuthorization) throws Exception {
+ final String html = DOCTYPE_HTML
+ + "foo\n"
+ + "\n"
+ + "";
+
+ final WebClient client = getWebClient();
+
+ final MockWebConnection webConnection = new MockWebConnection();
+ webConnection.setResponse(URL_FIRST, html);
+ webConnection.setResponse(scriptUrl, "var i = 7;", MimeType.TEXT_JAVASCRIPT);
+ client.setWebConnection(webConnection);
+
+ final WebRequest request = new WebRequest(URL_FIRST);
+ request.setAdditionalHeader("Authorization", "Bearer secret");
+ request.setAdditionalHeader("foo", "bar");
+ client.getPage(request);
+
+ assertEquals(scriptUrl, webConnection.getLastWebRequest().getUrl());
+ assertEquals(expectedAuthorization, webConnection.getLastAdditionalHeaders().get("Authorization"));
+ assertEquals("bar", webConnection.getLastAdditionalHeaders().get("foo"));
+ }
+
/**
* @throws Exception if an error occurs
*/