From: Felix Dörre Date: Tue, 11 Nov 2014 15:44:33 +0000 (+0100) Subject: ADD: prevent session stealing with the secure server. X-Git-Url: https://code.wpia.club/?p=gigi.git;a=commitdiff_plain;h=ccf3d903ed99ffe0a4ef32b317687b14698d6a75 ADD: prevent session stealing with the secure server. --- diff --git a/src/org/cacert/gigi/Gigi.java b/src/org/cacert/gigi/Gigi.java index 692eb3ed..cf75bf58 100644 --- a/src/org/cacert/gigi/Gigi.java +++ b/src/org/cacert/gigi/Gigi.java @@ -3,6 +3,7 @@ package org.cacert.gigi; import java.io.IOException; import java.io.PrintWriter; import java.security.KeyStore; +import java.security.cert.X509Certificate; import java.util.Calendar; import java.util.HashMap; import java.util.LinkedList; @@ -59,6 +60,8 @@ public class Gigi extends HttpServlet { public static final String LOGGEDIN = "loggedin"; + public static final String CERT_SERIAL = "org.cacert.gigi.serial"; + public static final String USER = "user"; private static final long serialVersionUID = -6386785421902852904L; @@ -227,6 +230,16 @@ public class Gigi extends HttpServlet { return; } HttpSession hs = req.getSession(); + String clientSerial = (String) hs.getAttribute(CERT_SERIAL); + if (clientSerial != null) { + X509Certificate[] cert = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate"); + if (cert == null || cert[0] == null || !cert[0].getSerialNumber().toString(16).toUpperCase().equals(clientSerial)) { + hs.invalidate(); + resp.sendError(403, "Certificate mismatch."); + return; + } + + } if (req.getParameter("lang") != null) { Locale l = Language.getLocaleFromString(req.getParameter("lang")); Language lu = Language.getInstance(l); diff --git a/src/org/cacert/gigi/pages/LoginPage.java b/src/org/cacert/gigi/pages/LoginPage.java index 8e920d09..7f34f071 100644 --- a/src/org/cacert/gigi/pages/LoginPage.java +++ b/src/org/cacert/gigi/pages/LoginPage.java @@ -115,6 +115,7 @@ public class LoginPage extends Page { GigiResultSet rs = ps.executeQuery(); if (rs.next()) { loginSession(req, User.getById(rs.getInt(1))); + req.getSession().setAttribute(CERT_SERIAL, serial); } rs.close(); } diff --git a/tests/org/cacert/gigi/TestCrossDomainAccess.java b/tests/org/cacert/gigi/TestCrossDomainAccess.java index 28c0b20a..26dc35fb 100644 --- a/tests/org/cacert/gigi/TestCrossDomainAccess.java +++ b/tests/org/cacert/gigi/TestCrossDomainAccess.java @@ -8,15 +8,8 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; import java.sql.SQLException; -import org.cacert.gigi.dbObjects.Certificate; -import org.cacert.gigi.dbObjects.Certificate.CSRType; -import org.cacert.gigi.dbObjects.CertificateProfile; -import org.cacert.gigi.dbObjects.User; import org.cacert.gigi.testUtils.IOUtils; import org.cacert.gigi.testUtils.ManagedTest; import org.cacert.gigi.util.ServerConstants; @@ -46,17 +39,7 @@ public class TestCrossDomainAccess extends ManagedTest { @Test public void testCorrectOriginHeaderFromHttpsToSecure() throws MalformedURLException, IOException, GeneralSecurityException, SQLException, InterruptedException, GigiApiException { - String email = createUniqueName() + "@b.ce"; - int id = createVerifiedUser("Kurti", "Hansel", email, TEST_PASSWORD); - KeyPair kp = generateKeypair(); - String key1 = generatePEMCSR(kp, "CN=" + email); - Certificate c = new Certificate(User.getById(id), Certificate.buildDN("CN", email), "sha256", key1, CSRType.CSR, CertificateProfile.getById(1)); - final PrivateKey pk = kp.getPrivate(); - c.issue(null, "2y").waitFor(60000); - final X509Certificate ce = c.cert(); - String cookie = login(pk, ce); URLConnection con = new URL("https://" + ServerConstants.getSecureHostNamePort()).openConnection(); - con.setRequestProperty("Cookie", cookie); con.setRequestProperty("Origin", "https://" + ServerConstants.getWwwHostNamePortSecure()); String contains = IOUtils.readURL(con); assertTrue( !contains.contains("No cross domain access allowed.")); diff --git a/tests/org/cacert/gigi/TestSeparateSessionScope.java b/tests/org/cacert/gigi/TestSeparateSessionScope.java index 20dd6ae9..ba5579ff 100644 --- a/tests/org/cacert/gigi/TestSeparateSessionScope.java +++ b/tests/org/cacert/gigi/TestSeparateSessionScope.java @@ -6,7 +6,9 @@ import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import java.security.GeneralSecurityException; +import java.security.KeyManagementException; import java.security.KeyPair; +import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.sql.SQLException; @@ -16,6 +18,7 @@ import org.cacert.gigi.dbObjects.Certificate.CSRType; import org.cacert.gigi.dbObjects.CertificateProfile; import org.cacert.gigi.dbObjects.User; import org.cacert.gigi.testUtils.ManagedTest; +import org.cacert.gigi.util.Job; import org.junit.Test; public class TestSeparateSessionScope extends ManagedTest { @@ -36,16 +39,36 @@ public class TestSeparateSessionScope extends ManagedTest { assertTrue(isLoggedin(cookie)); assertFalse(isLoggedin(scookie)); + checkCertLogin(c, pk, scookie, 200); + checkCertLogin(c, pk, cookie, 302); + } + + @Test + public void testSerialSteal() throws IOException, GeneralSecurityException, SQLException, InterruptedException, GigiApiException { + String mail = "thisgo" + createUniqueName() + "@example.com"; + int user = createAssuranceUser("test", "tugo", mail, TEST_PASSWORD); + KeyPair kp = generateKeypair(); + String csr = generatePEMCSR(kp, "CN=felix@dogcraft.de"); + Certificate c = new Certificate(User.getById(user), Certificate.buildDN("CN", "testmail@example.com"), "sha256", csr, CSRType.CSR, CertificateProfile.getById(1)); + Certificate c2 = new Certificate(User.getById(user), Certificate.buildDN("CN", "testmail@example.com"), "sha256", csr, CSRType.CSR, CertificateProfile.getById(1)); + final PrivateKey pk = kp.getPrivate(); + Job j1 = c.issue(null, "2y"); + c2.issue(null, "2y").waitFor(60000); + j1.waitFor(60000); + final X509Certificate ce = c.cert(); + String scookie = login(pk, ce); + + checkCertLogin(c, pk, scookie, 200); + checkCertLogin(c2, pk, scookie, 403); + checkCertLogin(c, pk, scookie, 302); + + } + + private void checkCertLogin(Certificate c2, final PrivateKey pk, String scookie, int expected) throws IOException, NoSuchAlgorithmException, KeyManagementException, GeneralSecurityException { URL u = new URL("https://" + getServerName().replaceAll("^www", "secure") + SECURE_REFERENCE); HttpURLConnection huc = (HttpURLConnection) u.openConnection(); - authenticateClientCert(pk, ce, huc); + authenticateClientCert(pk, c2.cert(), huc); huc.setRequestProperty("Cookie", scookie); - assertEquals(200, huc.getResponseCode()); - - HttpURLConnection huc2 = (HttpURLConnection) u.openConnection(); - authenticateClientCert(pk, ce, huc2); - huc2.setRequestProperty("Cookie", cookie); - assertEquals(302, huc2.getResponseCode()); - + assertEquals(expected, huc.getResponseCode()); } }