KEYCLOAK-17033: Reflected XSS attack with referrer in new account
console
This commit is contained in:
parent
6e3dbfcb3d
commit
3b80eee5bf
2 changed files with 39 additions and 13 deletions
|
@ -37,6 +37,8 @@ import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals;
|
|||
public class ReferrerTest extends AbstractAccountTest {
|
||||
public static final String FAKE_CLIENT_ID = "fake-client-name";
|
||||
public static final String REFERRER_LINK_TEXT = "Back to " + LOCALE_CLIENT_NAME_LOCALIZED;
|
||||
public static final String FAKE_CLIENT_URL_CONTEXT = "auth/non-existing-page/";
|
||||
public static final String FAKE_CLIENT_URL_FRAGMENT = "?foo=bar&bar=foo#anchor";
|
||||
|
||||
@Page
|
||||
private WelcomeScreen welcomeScreen;
|
||||
|
@ -52,19 +54,36 @@ public class ReferrerTest extends AbstractAccountTest {
|
|||
ClientRepresentation testClient = new ClientRepresentation();
|
||||
testClient.setClientId(FAKE_CLIENT_ID);
|
||||
testClient.setName(LOCALE_CLIENT_NAME);
|
||||
testClient.setRedirectUris(Collections.singletonList(getFakeClientUrl()));
|
||||
|
||||
// Redirect URIs are no longer allowed to contain a fragment, so we
|
||||
// need the wildcard in order to use fragments in tests
|
||||
testClient.setRedirectUris(Collections.singletonList(getFakeClientUrl("*")));
|
||||
|
||||
testClient.setEnabled(true);
|
||||
|
||||
testRealm.setClients(Collections.singletonList(testClient));
|
||||
testRealm.setAccountTheme(LOCALIZED_THEME_PREVIEW); // using localized custom theme for the fake client localized name
|
||||
}
|
||||
|
||||
@Test
|
||||
// https://issues.redhat.com/browse/KEYCLOAK-17033
|
||||
// If the referrer is unescaped, this test will throw an exception.
|
||||
// org.openqa.selenium.UnhandledAlertException: unexpected alert open: {Alert text : XSS}
|
||||
public void reflectedXSSTest() {
|
||||
String attackUrl = getFakeClientUrl("'+alert('XSS')+'");
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, attackUrl);
|
||||
|
||||
welcomeScreen.header().clickLoginBtn();
|
||||
loginToAccount();
|
||||
welcomeScreen.clickPersonalInfoLink();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loggedInWelcomeScreenTest() {
|
||||
welcomeScreen.header().clickLoginBtn();
|
||||
loginToAccount();
|
||||
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl());
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
|
||||
welcomeScreen.header().assertLoginBtnVisible(false);
|
||||
welcomeScreen.header().assertLogoutBtnVisible(true);
|
||||
|
||||
|
@ -73,7 +92,7 @@ public class ReferrerTest extends AbstractAccountTest {
|
|||
|
||||
@Test
|
||||
public void loggedOutWelcomeScreenTest() {
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl());
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
|
||||
welcomeScreen.header().assertLoginBtnVisible(true);
|
||||
welcomeScreen.header().assertLogoutBtnVisible(false);
|
||||
|
||||
|
@ -85,7 +104,7 @@ public class ReferrerTest extends AbstractAccountTest {
|
|||
welcomeScreen.header().clickLoginBtn();
|
||||
loginToAccount();
|
||||
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl());
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
|
||||
welcomeScreen.clickPersonalInfoLink();
|
||||
|
||||
testReferrer(personalInfoPage.header(), true);
|
||||
|
@ -93,7 +112,7 @@ public class ReferrerTest extends AbstractAccountTest {
|
|||
|
||||
@Test
|
||||
public void loggedOutPageTest() {
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl());
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
|
||||
welcomeScreen.clickPersonalInfoLink();
|
||||
loginToAccount();
|
||||
|
||||
|
@ -102,10 +121,10 @@ public class ReferrerTest extends AbstractAccountTest {
|
|||
|
||||
@Test
|
||||
public void badClientNameTest() {
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID + "-bad", getFakeClientUrl());
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID + "-bad", getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
|
||||
testReferrer(welcomeScreen.header(), false);
|
||||
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID + "-bad", getFakeClientUrl());
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID + "-bad", getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
|
||||
welcomeScreen.clickPersonalInfoLink();
|
||||
loginToAccount();
|
||||
testReferrer(personalInfoPage.header(), false);
|
||||
|
@ -113,10 +132,10 @@ public class ReferrerTest extends AbstractAccountTest {
|
|||
|
||||
@Test
|
||||
public void badClientUriTest() {
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl() + "-bad");
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrlWithBadContext());
|
||||
testReferrer(welcomeScreen.header(), false);
|
||||
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrl() + "-bad");
|
||||
welcomeScreen.navigateTo(FAKE_CLIENT_ID, getFakeClientUrlWithBadContext());
|
||||
welcomeScreen.clickPersonalInfoLink();
|
||||
loginToAccount();
|
||||
testReferrer(personalInfoPage.header(), false);
|
||||
|
@ -126,17 +145,24 @@ public class ReferrerTest extends AbstractAccountTest {
|
|||
if (expectReferrerVisible) {
|
||||
assertEquals(REFERRER_LINK_TEXT, header.getReferrerLinkText());
|
||||
header.clickReferrerLink();
|
||||
assertCurrentUrlEquals(getFakeClientUrl());
|
||||
assertCurrentUrlEquals(getFakeClientUrl(FAKE_CLIENT_URL_FRAGMENT));
|
||||
}
|
||||
else {
|
||||
header.assertReferrerLinkVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private String getFakeClientUrl() {
|
||||
private String getFakeClientUrl(String suffix) {
|
||||
// we need to use some page which host exists – Firefox is throwing exceptions like crazy if we try to load
|
||||
// a page on a non-existing host, like e.g. http://non-existing-server/
|
||||
// also we need to do this here as getAuthServerRoot is not ready when firing this class' constructor
|
||||
return getAuthServerRoot() + "auth/non-existing-page/?foo=bar&bar=foo#anchor";
|
||||
return getAuthServerRoot() + FAKE_CLIENT_URL_CONTEXT + suffix;
|
||||
}
|
||||
|
||||
private String getFakeClientUrlWithBadContext() {
|
||||
// we need to use some page which host exists – Firefox is throwing exceptions like crazy if we try to load
|
||||
// a page on a non-existing host, like e.g. http://non-existing-server/
|
||||
// also we need to do this here as getAuthServerRoot is not ready when firing this class' constructor
|
||||
return getAuthServerRoot() + "bad/" + FAKE_CLIENT_URL_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
<#if referrer??>
|
||||
var referrer = '${referrer}';
|
||||
var referrerName = '${referrerName}';
|
||||
var referrerUri = '${referrer_uri?no_esc}';
|
||||
var referrerUri = '${referrer_uri}'.replace('&', '&');
|
||||
</#if>
|
||||
|
||||
<#if msg??>
|
||||
|
|
Loading…
Reference in a new issue