From bce5b442757ec2914953ea37a01feb47f963fe58 Mon Sep 17 00:00:00 2001
From: jrandom <jrandom>
Date: Mon, 23 Aug 2004 17:11:38 +0000
Subject: [PATCH] standardized the spoof prevention: - set the nonce and
 noncePrev for the handler when rendering the form - include the current nonce
 in the hidden parameter "nonce" - include an "action" parameter (so we know
 we want to execute something and hence, validate the nonce, rather than just
 display the page) - if the nonce submitted doesnt match what is set in the
 nonce or noncePrev when validating, its invalid.  refuse to process

---
 .../i2p/router/web/ConfigServiceHandler.java  | 21 +--------
 .../src/net/i2p/router/web/FormHandler.java   | 43 ++++++++++++++++++-
 apps/routerconsole/jsp/config.jsp             |  6 +++
 apps/routerconsole/jsp/configadvanced.jsp     |  5 +++
 apps/routerconsole/jsp/configclients.jsp      |  5 +++
 apps/routerconsole/jsp/configlogging.jsp      |  5 +++
 6 files changed, 65 insertions(+), 20 deletions(-)

diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java
index 60ea04742d..7d23aafa00 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java
@@ -8,26 +8,11 @@ import net.i2p.router.ClientTunnelSettings;
  *
  */
 public class ConfigServiceHandler extends FormHandler {
-    private String _action;
-    private String _nonce;
-    
-    public void ConfigNetHandler() {
-        _action = null;
-        _nonce = null;
-    }
+    public void ConfigNetHandler() {}
     
     protected void processForm() {
         if (_action == null) return;
-        if (_nonce == null) {
-            addFormError("You trying to mess with me?  Huh?  Are you?");
-            return;
-        }
-        String nonce = System.getProperty(ConfigServiceHandler.class.getName() + ".nonce");
-        String noncePrev = System.getProperty(ConfigServiceHandler.class.getName() + ".noncePrev");
-        if ( (!_nonce.equals(nonce)) && (!_nonce.equals(noncePrev)) ) {
-            addFormError("Invalid nonce?  Hmmm, someone is spoofing you.  prev=["+ noncePrev + "] nonce=[" + nonce + "] param=[" + _nonce + "]");
-            return;
-        }
+        
         if ("Shutdown gracefully".equals(_action)) {
             _context.router().shutdownGracefully();
             addFormNotice("Graceful shutdown initiated");
@@ -41,6 +26,4 @@ public class ConfigServiceHandler extends FormHandler {
             addFormNotice("Blah blah blah.  whatever.  I'm not going to " + _action);
         }
     }
-    public void setAction(String action) { _action = action; }
-    public void setNonce(String nonce) { _nonce = nonce; }
 }
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/FormHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/FormHandler.java
index 73b12f4dd7..02acc1b9cc 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/FormHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/FormHandler.java
@@ -19,14 +19,20 @@ import net.i2p.router.ClientTunnelSettings;
  */
 public class FormHandler {
     protected RouterContext _context;
+    private String _nonce;
+    protected String _action;
     private List _errors;
     private List _notices;
     private boolean _processed;
+    private boolean _valid;
     
     public FormHandler() {
         _errors = new ArrayList();
         _notices = new ArrayList();
+        _action = null;
         _processed = false;
+        _valid = true;
+        _nonce = null;
     }
     
     /**
@@ -43,6 +49,9 @@ public class FormHandler {
         }
     }
 
+    public void setNonce(String val) { _nonce = val; }
+    public void setAction(String val) { _action = val; }
+    
     /**
      * Override this to perform the final processing (in turn, adding formNotice
      * and formError messages, etc)
@@ -72,6 +81,7 @@ public class FormHandler {
      *
      */
     public String getErrors() { 
+        validate();
         return render(_errors);
     }
     
@@ -81,12 +91,43 @@ public class FormHandler {
      *
      */
     public String getNotices() { 
+        validate();
         return render(_notices);
     }
     
+    /**
+     * Make sure the nonce was set correctly, otherwise someone could just 
+     * create a link like /confignet.jsp?hostname=localhost and break the
+     * user's node (or worse).
+     *
+     */
+    private void validate() {
+        if (_processed) return;
+        
+        _valid = true;
+        if (_action == null) {
+            // not a form submit
+            _valid = false;
+            return;
+        }
+        if (_nonce == null) {
+            addFormError("You trying to mess with me?  Huh?  Are you?");
+            _valid = false;
+            return;
+        }
+        String nonce = System.getProperty(getClass().getName() + ".nonce");
+        String noncePrev = System.getProperty(getClass().getName() + ".noncePrev");
+        if ( ( (nonce == null) || (!_nonce.equals(nonce)) ) &&
+             ( (noncePrev == null) || (!_nonce.equals(noncePrev)) ) ) {
+            addFormError("Invalid nonce, are you being spoofed?");
+            _valid = false;
+        }
+    }
+    
     private String render(List source) {
         if (!_processed) {
-            processForm();
+            if (_valid)
+                processForm();
             _processed = true;
         }
         if (source.size() <= 0) {
diff --git a/apps/routerconsole/jsp/config.jsp b/apps/routerconsole/jsp/config.jsp
index 7558e9ddcc..55350b1a89 100644
--- a/apps/routerconsole/jsp/config.jsp
+++ b/apps/routerconsole/jsp/config.jsp
@@ -22,6 +22,12 @@
  <i><jsp:getProperty name="formhandler" property="notices" /></i>
 
  <form action="config.jsp" method="POST">
+ <% String prev = System.getProperty("net.i2p.router.web.ConfigNetHandler.nonce");
+    if (prev != null) System.setProperty("net.i2p.router.web.ConfigNetHandler.noncePrev", prev);
+    System.setProperty("net.i2p.router.web.ConfigNetHandler.nonce", new java.util.Random().nextLong()+""); %>
+ <input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigNetHandler.nonce")%>" />
+ <input type="hidden" name="action" value="blah" />
+
  <b>External hostname/IP address:</b> 
     <input name="hostname" type="text" size="32" value="<jsp:getProperty name="nethelper" property="hostname" />" />
     <input type="submit" name="guesshost" value="Guess" /><br />
diff --git a/apps/routerconsole/jsp/configadvanced.jsp b/apps/routerconsole/jsp/configadvanced.jsp
index 5d10bdf2ec..473928e9bb 100644
--- a/apps/routerconsole/jsp/configadvanced.jsp
+++ b/apps/routerconsole/jsp/configadvanced.jsp
@@ -23,6 +23,11 @@
  <i><jsp:getProperty name="formhandler" property="notices" /></i>
  
  <form action="configadvanced.jsp" method="POST">
+ <% String prev = System.getProperty("net.i2p.router.web.ConfigAdvancedHandler.nonce");
+    if (prev != null) System.setProperty("net.i2p.router.web.ConfigAdvancedHandler.noncePrev", prev);
+    System.setProperty("net.i2p.router.web.ConfigAdvancedHandler.nonce", new java.util.Random().nextLong()+""); %>
+ <input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigAdvancedHandler.nonce")%>" />
+ <input type="hidden" name="action" value="blah" />
  <textarea rows="20" cols="100" name="config"><jsp:getProperty name="advancedhelper" property="settings" /></textarea><br />
  <input type="submit" name="shouldsave" value="Apply" /> <input type="reset" value="Cancel" /> <br />
  <b>Force restart:</b> <input type="checkbox" name="restart" value="force" /> <i>(specify this
diff --git a/apps/routerconsole/jsp/configclients.jsp b/apps/routerconsole/jsp/configclients.jsp
index 9ec0afbba7..f1ab29d97a 100644
--- a/apps/routerconsole/jsp/configclients.jsp
+++ b/apps/routerconsole/jsp/configclients.jsp
@@ -23,6 +23,11 @@
  <i><jsp:getProperty name="formhandler" property="notices" /></i>
  
  <form action="configclients.jsp" method="POST">
+ <% String prev = System.getProperty("net.i2p.router.web.ConfigClientsHandler.nonce");
+    if (prev != null) System.setProperty("net.i2p.router.web.ConfigClientsHandler.noncePrev", prev);
+    System.setProperty("net.i2p.router.web.ConfigClientsHandler.nonce", new java.util.Random().nextLong()+""); %>
+ <input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigClientsHandler.nonce")%>" />
+ <input type="hidden" name="action" value="blah" />
  <b>Estimated number of clients/destinations:</b> 
     <jsp:getProperty name="clientshelper" property="clientCountSelectBox" /><br />
  <b>Default number of inbound tunnels per client:</b>
diff --git a/apps/routerconsole/jsp/configlogging.jsp b/apps/routerconsole/jsp/configlogging.jsp
index 9a2041e2f0..aba7d34ca8 100644
--- a/apps/routerconsole/jsp/configlogging.jsp
+++ b/apps/routerconsole/jsp/configlogging.jsp
@@ -22,6 +22,11 @@
  <i><jsp:getProperty name="formhandler" property="notices" /></i>
   
  <form action="configlogging.jsp" method="POST">
+ <% String prev = System.getProperty("net.i2p.router.web.ConfigLoggingHandler.nonce");
+    if (prev != null) System.setProperty("net.i2p.router.web.ConfigLoggingHandler.noncePrev", prev);
+    System.setProperty("net.i2p.router.web.ConfigLoggingHandler.nonce", new java.util.Random().nextLong()+""); %>
+ <input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigLoggingHandler.nonce")%>" />
+ <input type="hidden" name="action" value="blah" />
  <b>Logging filename:</b> 
     <input type="text" name="logfilename" size="40" value="<jsp:getProperty name="logginghelper" property="logFilePattern" />" /><br />
     <i>(the symbol '#' will be replaced during log rotation)</i><br />
-- 
GitLab