Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8CD2F18B46 for ; Wed, 16 Dec 2015 17:57:23 +0000 (UTC) Received: (qmail 11485 invoked by uid 500); 16 Dec 2015 17:57:23 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 11425 invoked by uid 500); 16 Dec 2015 17:57:23 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 11407 invoked by uid 99); 16 Dec 2015 17:57:23 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 16 Dec 2015 17:57:23 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 001D4E00BB; Wed, 16 Dec 2015 17:57:22 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: coheigea@apache.org To: commits@cxf.apache.org Date: Wed, 16 Dec 2015 17:57:22 -0000 Message-Id: <8f89a53e3d874377a9641f1d592e523c@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [1/2] cxf-fediz git commit: Moving IdP specific tests out into a separate module Repository: cxf-fediz Updated Branches: refs/heads/master ae4b6613b -> eccd097ab http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/eccd097a/systests/tests/src/test/java/org/apache/cxf/fediz/integrationtests/AbstractTests.java ---------------------------------------------------------------------- diff --git a/systests/tests/src/test/java/org/apache/cxf/fediz/integrationtests/AbstractTests.java b/systests/tests/src/test/java/org/apache/cxf/fediz/integrationtests/AbstractTests.java index 9a28760..c8c7df2 100644 --- a/systests/tests/src/test/java/org/apache/cxf/fediz/integrationtests/AbstractTests.java +++ b/systests/tests/src/test/java/org/apache/cxf/fediz/integrationtests/AbstractTests.java @@ -28,9 +28,13 @@ import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.html.DomElement; import com.gargoylesoftware.htmlunit.html.DomNodeList; +import com.gargoylesoftware.htmlunit.html.HtmlForm; import com.gargoylesoftware.htmlunit.html.HtmlPage; +import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput; import com.gargoylesoftware.htmlunit.xml.XmlPage; +import java.net.URLEncoder; + import org.apache.cxf.fediz.core.ClaimTypes; import org.apache.cxf.fediz.core.FederationConstants; import org.apache.cxf.fediz.core.util.DOMUtils; @@ -42,13 +46,13 @@ import org.apache.xml.security.signature.XMLSignature; import org.junit.Assert; import org.junit.Test; -public abstract class AbstractTests extends AbstractAttackTests { - - static final String TEST_WREQ = +public abstract class AbstractTests { + + static final String TEST_WREQ = "" + "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV3.0" + ""; - + static { WSSConfig.init(); } @@ -58,21 +62,21 @@ public abstract class AbstractTests extends AbstractAttackTests { } public abstract String getServletContextName(); - + public abstract String getIdpHttpsPort(); public abstract String getRpHttpsPort(); @Test public void testAlice() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/fedservlet"; String user = "alice"; String password = "ecila"; - - final String bodyTextContent = + + final String bodyTextContent = HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); - + Assert.assertTrue("Principal not " + user, bodyTextContent.contains("userPrincipal=" + user)); Assert.assertTrue("User " + user + " does not have role Admin", @@ -81,7 +85,7 @@ public abstract class AbstractTests extends AbstractAttackTests { bodyTextContent.contains("role:Manager=false")); Assert.assertTrue("User " + user + " must have role User", bodyTextContent.contains("role:User=true")); - + String claim = ClaimTypes.FIRSTNAME.toString(); Assert.assertTrue("User " + user + " claim " + claim + " is not 'Alice'", bodyTextContent.contains(claim + "=Alice")); @@ -93,15 +97,15 @@ public abstract class AbstractTests extends AbstractAttackTests { bodyTextContent.contains(claim + "=alice@realma.org")); } - + @Test public void testAliceUser() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/user/fedservlet"; String user = "alice"; String password = "ecila"; - - final String bodyTextContent = + + final String bodyTextContent = HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); Assert.assertTrue("Principal not " + user, @@ -113,14 +117,14 @@ public abstract class AbstractTests extends AbstractAttackTests { Assert.assertTrue("User " + user + " must have role User", bodyTextContent.contains("role:User=true")); } - + @Test public void testAliceAdminNoAccess() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/admin/fedservlet"; String user = "alice"; String password = "ecila"; - + try { HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); Assert.fail("Exception expected"); @@ -128,14 +132,14 @@ public abstract class AbstractTests extends AbstractAttackTests { Assert.assertEquals(ex.getStatusCode(), 403); } } - + @Test public void testAliceManagerNoAccess() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/manager/fedservlet"; String user = "alice"; String password = "ecila"; - + try { HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); Assert.fail("Exception expected"); @@ -146,11 +150,11 @@ public abstract class AbstractTests extends AbstractAttackTests { @Test public void testAliceWrongPasswordNoAccess() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/fedservlet"; String user = "alice"; String password = "alice"; - + try { HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); Assert.fail("Exception expected"); @@ -161,12 +165,12 @@ public abstract class AbstractTests extends AbstractAttackTests { @Test public void testBob() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/fedservlet"; String user = "bob"; String password = "bob"; - - final String bodyTextContent = + + final String bodyTextContent = HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); Assert.assertTrue("Principal not " + user, @@ -188,15 +192,15 @@ public abstract class AbstractTests extends AbstractAttackTests { Assert.assertTrue("User " + user + " claim " + claim + " is not 'bobwindsor@realma.org'", bodyTextContent.contains(claim + "=bobwindsor@realma.org")); } - + @Test public void testBobUser() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/user/fedservlet"; String user = "bob"; String password = "bob"; - - final String bodyTextContent = + + final String bodyTextContent = HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); Assert.assertTrue("Principal not " + user, @@ -208,15 +212,15 @@ public abstract class AbstractTests extends AbstractAttackTests { Assert.assertTrue("User " + user + " must have role User", bodyTextContent.contains("role:User=true")); } - + @Test public void testBobManager() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/manager/fedservlet"; String user = "bob"; String password = "bob"; - - final String bodyTextContent = + + final String bodyTextContent = HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); Assert.assertTrue("Principal not " + user, @@ -228,15 +232,15 @@ public abstract class AbstractTests extends AbstractAttackTests { Assert.assertTrue("User " + user + " must have role User", bodyTextContent.contains("role:User=true")); } - + @Test public void testBobAdmin() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/admin/fedservlet"; String user = "bob"; String password = "bob"; - - final String bodyTextContent = + + final String bodyTextContent = HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); Assert.assertTrue("Principal not " + user, @@ -251,12 +255,12 @@ public abstract class AbstractTests extends AbstractAttackTests { @Test public void testTed() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/fedservlet"; String user = "ted"; String password = "det"; - - final String bodyTextContent = + + final String bodyTextContent = HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); Assert.assertTrue("Principal not " + user, @@ -278,14 +282,14 @@ public abstract class AbstractTests extends AbstractAttackTests { Assert.assertTrue("User " + user + " claim " + claim + " is not 'tcooper@realma.org'", bodyTextContent.contains(claim + "=tcooper@realma.org")); } - + @Test public void testTedUserNoAccess() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/user/fedservlet"; String user = "ted"; String password = "det"; - + try { HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); Assert.fail("Exception expected"); @@ -296,11 +300,11 @@ public abstract class AbstractTests extends AbstractAttackTests { @Test public void testTedAdminNoAccess() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/admin/fedservlet"; String user = "ted"; String password = "det"; - + try { HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); Assert.fail("Exception expected"); @@ -308,14 +312,14 @@ public abstract class AbstractTests extends AbstractAttackTests { Assert.assertEquals(ex.getStatusCode(), 403); } } - + @Test public void testTedManagerNoAccess() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/manager/fedservlet"; String user = "ted"; String password = "det"; - + try { HTTPTestUtils.login(url, user, password, getIdpHttpsPort()); Assert.fail("Exception expected"); @@ -326,7 +330,7 @@ public abstract class AbstractTests extends AbstractAttackTests { @Test public void testRPMetadata() throws Exception { - String url = "https://localhost:" + getRpHttpsPort() + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/FederationMetadata/2007-06/FederationMetadata.xml"; final WebClient webClient = new WebClient(); @@ -337,105 +341,39 @@ public abstract class AbstractTests extends AbstractAttackTests { final XmlPage rpPage = webClient.getPage(url); final String xmlContent = rpPage.asXml(); Assert.assertTrue(xmlContent.startsWith(" results = idpPage.getElementsByTagName("input"); - String wresult = null; for (DomElement result : results) { if ("wresult".equals(result.getAttributeNS(null, "name"))) { - wresult = result.getAttributeNS(null, "value"); - break; + // Now modify the Signature + String value = result.getAttributeNS(null, "value"); + value = value.replace("alice", "bob"); + result.setAttributeNS(null, "value", value); } } - - Assert.assertNotNull(wresult); - + + // Invoke back on the RP + + final HtmlForm form = idpPage.getFormByName("signinresponseform"); + final HtmlSubmitInput button = form.getInputByName("_eventId_submit"); + + try { + button.click(); + Assert.fail("Failure expected on a modified signature"); + } catch (FailingHttpStatusCodeException ex) { + // expected + Assert.assertTrue(ex.getMessage().contains("401 Unauthorized") + || ex.getMessage().contains("401 Authentication Failed") + || ex.getMessage().contains("403 Forbidden")); + } + webClient.close(); } - + + @Test + public void testConcurrentRequests() throws Exception { + + String url1 = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/fedservlet"; + String url2 = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/test.html"; + String user = "bob"; + String password = "bob"; + + // Get the initial token + CookieManager cookieManager = new CookieManager(); + final WebClient webClient = new WebClient(); + webClient.setCookieManager(cookieManager); + webClient.getOptions().setUseInsecureSSL(true); + webClient.getCredentialsProvider().setCredentials( + new AuthScope("localhost", Integer.parseInt(getIdpHttpsPort())), + new UsernamePasswordCredentials(user, password)); + + webClient.getOptions().setJavaScriptEnabled(false); + final HtmlPage idpPage1 = webClient.getPage(url1); + final HtmlPage idpPage2 = webClient.getPage(url2); + webClient.getOptions().setJavaScriptEnabled(true); + Assert.assertEquals("IDP SignIn Response Form", idpPage1.getTitleText()); + Assert.assertEquals("IDP SignIn Response Form", idpPage2.getTitleText()); + + // Invoke back on the page1 RP + final HtmlForm form = idpPage1.getFormByName("signinresponseform"); + final HtmlSubmitInput button = form.getInputByName("_eventId_submit"); + final HtmlPage rpPage1 = button.click(); + Assert.assertTrue("WS Federation Systests Examples".equals(rpPage1.getTitleText()) + || "WS Federation Systests Spring Examples".equals(rpPage1.getTitleText())); + + String bodyTextContent1 = rpPage1.getBody().getTextContent(); + + Assert.assertTrue("Principal not " + user, + bodyTextContent1.contains("userPrincipal=" + user)); + + // Invoke back on the page2 RP + final HtmlForm form2 = idpPage2.getFormByName("signinresponseform"); + final HtmlSubmitInput button2 = form2.getInputByName("_eventId_submit"); + final HtmlPage rpPage2 = button2.click(); + String bodyTextContent2 = rpPage2.getBody().getTextContent(); + + Assert.assertTrue("Unexpected content of RP page", bodyTextContent2.contains("Secure Test")); + + webClient.close(); + } + + @org.junit.Test + public void testMaliciousRedirect() throws Exception { + String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/secure/fedservlet"; + String user = "alice"; + String password = "ecila"; + + CookieManager cookieManager = new CookieManager(); + + // 1. Login + HTTPTestUtils.loginWithCookieManager(url, user, password, getIdpHttpsPort(), cookieManager); + + // 2. Now we should have a cookie from the RP and IdP and should be able to do + // subsequent requests without authenticate again. Lets test this first. + WebClient webClient = new WebClient(); + webClient.setCookieManager(cookieManager); + webClient.getOptions().setUseInsecureSSL(true); + HtmlPage rpPage = webClient.getPage(url); + Assert.assertTrue("WS Federation Systests Examples".equals(rpPage.getTitleText()) + || "WS Federation Systests Spring Examples".equals(rpPage.getTitleText())); + + // 3. Now a malicious user sends the client a URL with a bad "wreply" address to the IdP + String maliciousURL = "https://www.apache.org/attack"; + String idpUrl + = "https://localhost:" + getIdpHttpsPort() + "/fediz-idp/federation"; + idpUrl += "?wa=wsignin1.0&wreply=" + URLEncoder.encode(maliciousURL, "UTF-8"); + idpUrl += "&wtrealm=urn%3Aorg%3Aapache%3Acxf%3Afediz%3Afedizhelloworld"; + idpUrl += "&whr=urn%3Aorg%3Aapache%3Acxf%3Afediz%3Aidp%3Arealm-A"; + webClient.close(); + + final WebClient webClient2 = new WebClient(); + webClient2.setCookieManager(cookieManager); + webClient2.getOptions().setUseInsecureSSL(true); + webClient2.getCredentialsProvider().setCredentials( + new AuthScope("localhost", Integer.parseInt(getIdpHttpsPort())), + new UsernamePasswordCredentials(user, password)); + + webClient2.getOptions().setJavaScriptEnabled(false); + try { + webClient2.getPage(idpUrl); + Assert.fail("Failure expected on a bad wreply address"); + } catch (FailingHttpStatusCodeException ex) { + Assert.assertEquals(ex.getStatusCode(), 400); + } + webClient2.close(); + } }