You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by el...@apache.org on 2014/05/28 22:51:56 UTC
[23/32] git commit: ACCUMULO-2785 Create a random string in the
session, and provide it in requests to mitigate CSRF.
ACCUMULO-2785 Create a random string in the session, and provide it in requests to mitigate CSRF.
Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/5d4cf3b4
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/5d4cf3b4
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/5d4cf3b4
Branch: refs/heads/ACCUMULO-378
Commit: 5d4cf3b425c291ce1a3133f1637145b51bf276cf
Parents: 2526f0a
Author: Josh Elser <el...@apache.org>
Authored: Fri May 23 20:19:58 2014 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Fri May 23 20:19:58 2014 -0400
----------------------------------------------------------------------
.../server/monitor/servlets/ShellServlet.java | 44 +++++++++++++++-----
1 file changed, 34 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/accumulo/blob/5d4cf3b4/server/src/main/java/org/apache/accumulo/server/monitor/servlets/ShellServlet.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/monitor/servlets/ShellServlet.java b/server/src/main/java/org/apache/accumulo/server/monitor/servlets/ShellServlet.java
index 07cf029..e2fe1cf 100644
--- a/server/src/main/java/org/apache/accumulo/server/monitor/servlets/ShellServlet.java
+++ b/server/src/main/java/org/apache/accumulo/server/monitor/servlets/ShellServlet.java
@@ -23,6 +23,7 @@ import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
+import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -40,7 +41,9 @@ public class ShellServlet extends BasicServlet {
private static final long serialVersionUID = 1L;
private Map<String,ShellExecutionThread> userShells = new HashMap<String,ShellExecutionThread>();
private ExecutorService service = Executors.newCachedThreadPool();
-
+
+ public static final String CSRF_KEY = "csrf_token";
+
@Override
protected String getTitle(HttpServletRequest req) {
return "Shell";
@@ -49,6 +52,19 @@ public class ShellServlet extends BasicServlet {
@Override
protected void pageBody(HttpServletRequest req, HttpServletResponse response, StringBuilder sb) throws IOException {
HttpSession session = req.getSession(true);
+ final String CSRF_TOKEN;
+ if (null == session.getAttribute(CSRF_KEY)) {
+ // No token, make one
+ CSRF_TOKEN = UUID.randomUUID().toString();
+ session.setAttribute(CSRF_KEY, CSRF_TOKEN);
+ } else {
+ // Pull the token out of the session
+ CSRF_TOKEN = (String) session.getAttribute(CSRF_KEY);
+ if (null == CSRF_TOKEN) {
+ throw new RuntimeException("No valid CSRF token exists in session");
+ }
+ }
+
String user = (String) session.getAttribute("user");
if (user == null) {
// user attribute is null, check to see if username and password are passed as parameters
@@ -57,7 +73,7 @@ public class ShellServlet extends BasicServlet {
String mock = req.getParameter("mock");
if (user == null || pass == null) {
// username or password are null, re-authenticate
- sb.append(authenticationForm(req.getRequestURI()));
+ sb.append(authenticationForm(req.getRequestURI(), CSRF_TOKEN));
return;
}
try {
@@ -67,16 +83,17 @@ public class ShellServlet extends BasicServlet {
userShells.put(session.getId(), shellThread);
} catch (IOException e) {
// error validating user, reauthenticate
- sb.append("<div id='loginError'>Invalid user/password</div>" + authenticationForm(req.getRequestURI()));
+ sb.append("<div id='loginError'>Invalid user/password</div>" + authenticationForm(req.getRequestURI(), CSRF_TOKEN));
return;
}
session.setAttribute("user", user);
}
if (!userShells.containsKey(session.getId())) {
// no existing shell for this user, re-authenticate
- sb.append(authenticationForm(req.getRequestURI()));
+ sb.append(authenticationForm(req.getRequestURI(), UUID.randomUUID().toString()));
return;
}
+
ShellExecutionThread shellThread = userShells.get(session.getId());
shellThread.getOutput();
shellThread.printInfo();
@@ -121,7 +138,7 @@ public class ShellServlet extends BasicServlet {
sb.append(" document.getElementById('shellResponse').innerHTML += history.join('\\n');\n");
sb.append(" return\n");
sb.append(" }\n");
- sb.append(" xmlhttp.open('POST',url+'?cmd='+cmd,false);\n");
+ sb.append(" xmlhttp.open('POST',url+'?cmd='+cmd+'&'+'").append(CSRF_KEY).append("=").append(CSRF_TOKEN).append("',false);\n");
sb.append(" xmlhttp.send();\n");
sb.append(" var text = xmlhttp.responseText;\n");
sb.append(" var index = text.lastIndexOf('\\n');\n");
@@ -148,15 +165,21 @@ public class ShellServlet extends BasicServlet {
sb.append("</script>\n");
sb.append("<script type='text/javascript'>window.onload = function() { document.getElementById('cmd').select(); }</script>\n");
}
-
+
+ @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- HttpSession session = req.getSession(true);
+ final HttpSession session = req.getSession(true);
String user = (String) session.getAttribute("user");
if (user == null || !userShells.containsKey(session.getId())) {
// no existing shell for user, re-authenticate
doGet(req, resp);
return;
}
+ final String CSRF_TOKEN = (String) session.getAttribute(CSRF_KEY);
+ if (null == CSRF_TOKEN) {
+ // no csrf token, need to re-auth
+ doGet(req, resp);
+ }
ShellExecutionThread shellThread = userShells.get(session.getId());
String cmd = req.getParameter("cmd");
if (cmd == null) {
@@ -187,12 +210,13 @@ public class ShellServlet extends BasicServlet {
resp.getWriter().append(sb.toString());
resp.getWriter().flush();
}
-
- private String authenticationForm(String requestURI) {
+
+ private String authenticationForm(String requestURI, String csrfToken) {
return "<div id='login'><form method=POST action='" + requestURI + "'>"
+ "<table><tr><td>Mock: </td><td><input type='checkbox' name='mock' value='mock'></td></tr>"
+ "<tr><td>Username: </td><td><input type='text' name='user'></td></tr>"
- + "<tr><td>Password: </td><td><input type='password' name='pass'></td><td><input type='submit' value='Enter'></td></tr></table></form></div>";
+ + "<tr><td>Password: </td><td><input type='password' name='pass'></td><td>"
+ + "<input type='hidden' name='" + CSRF_KEY + "' value='" + csrfToken + "'/><input type='submit' value='Enter'></td></tr></table></form></div>";
}
private static class StringBuilderOutputStream extends OutputStream {