]> WPIA git - gigi.git/commitdiff
Implement CSRF check on "Assure someone"
authorFelix Dörre <felix@dogcraft.de>
Sat, 5 Jul 2014 00:03:16 +0000 (02:03 +0200)
committerFelix Dörre <felix@dogcraft.de>
Sat, 5 Jul 2014 00:03:16 +0000 (02:03 +0200)
(and implement it in test)

src/org/cacert/gigi/output/Form.java
src/org/cacert/gigi/pages/wot/AssuranceForm.java
src/org/cacert/gigi/pages/wot/AssurePage.java
tests/org/cacert/gigi/pages/wot/TestAssurance.java
tests/org/cacert/gigi/testUtils/ManagedTest.java

index b86b6dcb7ea62d5f9301ee87b177eb2b3aa58339..69fb22878e3fa6a76b8944e8c0d586c62717d870 100644 (file)
@@ -22,12 +22,12 @@ public abstract class Form implements Outputable {
                        Map<String, Object> vars) {
                out.println("<form method='POST' autocomplete='off'>");
                outputContent(out, l, vars);
-               out.println("<input type='csrf' value='");
+               out.print("<input type='csrf' value='");
                out.print(getCSRFToken());
                out.println("'></form>");
        }
 
-       public abstract void outputContent(PrintWriter out, Language l,
+       protected abstract void outputContent(PrintWriter out, Language l,
                        Map<String, Object> vars);
 
        protected void outputError(PrintWriter out, ServletRequest req, String text) {
@@ -36,8 +36,16 @@ public abstract class Form implements Outputable {
                out.println("</div>");
        }
 
-       public String getCSRFToken() {
+       protected String getCSRFToken() {
                return csrf;
        }
+       protected void checkCSRF(HttpServletRequest req) {
+               if (!csrf.equals(req.getParameter("csrf"))) {
+                       throw new CSRFError();
+               }
+       }
+
+       public class CSRFError extends Error {
 
+       }
 }
index 5819eb4d8b508a40e3c27b7aca9186cecc4df705..be7be71699fddaa8cf3136745a96126a517726c5 100644 (file)
@@ -48,6 +48,8 @@ public class AssuranceForm extends Form {
 
        @Override
        public boolean submit(PrintWriter out, HttpServletRequest req) {
+               checkCSRF(req);
+
                out.println("<div class='formError'>");
                boolean failed = false;
 
@@ -117,4 +119,5 @@ public class AssuranceForm extends Form {
                out.println("</div>");
                return false;
        }
+
 }
index 8862535c97aa6a6ffd404ae49e4c48c562bb8ee9..015029601bbaeab65177fe572d1b890141bf3632 100644 (file)
@@ -16,6 +16,7 @@ import org.cacert.gigi.User;
 import org.cacert.gigi.database.DatabaseConnection;
 import org.cacert.gigi.output.DateSelector;
 import org.cacert.gigi.output.Template;
+import org.cacert.gigi.output.Form.CSRFError;
 import org.cacert.gigi.pages.LoginPage;
 import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.util.Notary;
@@ -79,7 +80,12 @@ public class AssurePage extends Page {
                                out.println("No form found. This is an Error. Fill in the form again.");
                                return;
                        }
-                       form.submit(out, req);
+                       try {
+                               form.submit(out, req);
+                       } catch (CSRFError e) {
+                               resp.sendError(500, "CSRF Failed");
+                               out.println(translate(req, "CSRF Token failed."));
+                       }
 
                        return;
                }
index 54a85d8bd964b34321a20a87601e251ed212fa72..769767cd76f41b1ff329fb17cf150d429aa0fa1e 100644 (file)
@@ -141,10 +141,11 @@ public class TestAssurance extends ManagedTest {
                                + assuree);
                URLConnection uc = u.openConnection();
                uc.addRequestProperty("Cookie", cookie);
-               uc.getInputStream();// request form
+               String csrf = getCSRF(uc);
                uc = u.openConnection();
                uc.addRequestProperty("Cookie", cookie);
                uc.setDoOutput(true);
+               uc.getOutputStream().write(("csrf=" + csrf + "&").getBytes());
                return uc;
        }
 
index a9e1001569763b24bb0885011e9510e3521ed509..2d164f580b11ea6beab2f0e7a01cf6c72d4d7600 100644 (file)
@@ -13,6 +13,7 @@ import java.io.UnsupportedEncodingException;
 import java.net.HttpURLConnection;
 import java.net.InetSocketAddress;
 import java.net.URL;
+import java.net.URLConnection;
 import java.net.URLEncoder;
 import java.nio.file.Files;
 import java.nio.file.Paths;
@@ -20,6 +21,8 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.cacert.gigi.DevelLauncher;
 import org.cacert.gigi.database.DatabaseConnection;
@@ -273,4 +276,14 @@ public class ManagedTest {
                headerField = headerField.substring(0, headerField.indexOf(';'));
                return headerField;
        }
+
+       public String getCSRF(URLConnection u) throws IOException {
+               String content = IOUtils.readURL(u);
+               Pattern p = Pattern.compile("<input type='csrf' value='([^']+)'>");
+               Matcher m = p.matcher(content);
+               if (!m.find()) {
+                       throw new Error("New CSRF Token");
+               }
+               return m.group(1);
+       }
 }