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