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
This commit is contained in:
jrandom
2004-08-23 17:11:38 +00:00
committed by zzz
parent 9f7320fa67
commit bce5b44275
6 changed files with 65 additions and 20 deletions

View File

@ -8,26 +8,11 @@ import net.i2p.router.ClientTunnelSettings;
* *
*/ */
public class ConfigServiceHandler extends FormHandler { public class ConfigServiceHandler extends FormHandler {
private String _action; public void ConfigNetHandler() {}
private String _nonce;
public void ConfigNetHandler() {
_action = null;
_nonce = null;
}
protected void processForm() { protected void processForm() {
if (_action == null) return; 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)) { if ("Shutdown gracefully".equals(_action)) {
_context.router().shutdownGracefully(); _context.router().shutdownGracefully();
addFormNotice("Graceful shutdown initiated"); addFormNotice("Graceful shutdown initiated");
@ -41,6 +26,4 @@ public class ConfigServiceHandler extends FormHandler {
addFormNotice("Blah blah blah. whatever. I'm not going to " + _action); 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; }
} }

View File

@ -19,14 +19,20 @@ import net.i2p.router.ClientTunnelSettings;
*/ */
public class FormHandler { public class FormHandler {
protected RouterContext _context; protected RouterContext _context;
private String _nonce;
protected String _action;
private List _errors; private List _errors;
private List _notices; private List _notices;
private boolean _processed; private boolean _processed;
private boolean _valid;
public FormHandler() { public FormHandler() {
_errors = new ArrayList(); _errors = new ArrayList();
_notices = new ArrayList(); _notices = new ArrayList();
_action = null;
_processed = false; _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 * Override this to perform the final processing (in turn, adding formNotice
* and formError messages, etc) * and formError messages, etc)
@ -72,6 +81,7 @@ public class FormHandler {
* *
*/ */
public String getErrors() { public String getErrors() {
validate();
return render(_errors); return render(_errors);
} }
@ -81,12 +91,43 @@ public class FormHandler {
* *
*/ */
public String getNotices() { public String getNotices() {
validate();
return render(_notices); 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) { private String render(List source) {
if (!_processed) { if (!_processed) {
processForm(); if (_valid)
processForm();
_processed = true; _processed = true;
} }
if (source.size() <= 0) { if (source.size() <= 0) {

View File

@ -22,6 +22,12 @@
<i><jsp:getProperty name="formhandler" property="notices" /></i> <i><jsp:getProperty name="formhandler" property="notices" /></i>
<form action="config.jsp" method="POST"> <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> <b>External hostname/IP address:</b>
<input name="hostname" type="text" size="32" value="<jsp:getProperty name="nethelper" property="hostname" />" /> <input name="hostname" type="text" size="32" value="<jsp:getProperty name="nethelper" property="hostname" />" />
<input type="submit" name="guesshost" value="Guess" /><br /> <input type="submit" name="guesshost" value="Guess" /><br />

View File

@ -23,6 +23,11 @@
<i><jsp:getProperty name="formhandler" property="notices" /></i> <i><jsp:getProperty name="formhandler" property="notices" /></i>
<form action="configadvanced.jsp" method="POST"> <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 /> <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 /> <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 <b>Force restart:</b> <input type="checkbox" name="restart" value="force" /> <i>(specify this

View File

@ -23,6 +23,11 @@
<i><jsp:getProperty name="formhandler" property="notices" /></i> <i><jsp:getProperty name="formhandler" property="notices" /></i>
<form action="configclients.jsp" method="POST"> <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> <b>Estimated number of clients/destinations:</b>
<jsp:getProperty name="clientshelper" property="clientCountSelectBox" /><br /> <jsp:getProperty name="clientshelper" property="clientCountSelectBox" /><br />
<b>Default number of inbound tunnels per client:</b> <b>Default number of inbound tunnels per client:</b>

View File

@ -22,6 +22,11 @@
<i><jsp:getProperty name="formhandler" property="notices" /></i> <i><jsp:getProperty name="formhandler" property="notices" /></i>
<form action="configlogging.jsp" method="POST"> <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> <b>Logging filename:</b>
<input type="text" name="logfilename" size="40" value="<jsp:getProperty name="logginghelper" property="logFilePattern" />" /><br /> <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 /> <i>(the symbol '#' will be replaced during log rotation)</i><br />