summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorBogdan Udrescu <bogdan@vaadin.com>2014-07-09 18:40:26 +0300
committerLeif Åstrand <leif@vaadin.com>2014-07-15 08:50:38 +0000
commitdf13b061f2f6ba10beae64d9b358c0365736370e (patch)
tree0a2800b1e383f3f7fb648ea5ec9ec9512e54906d /server
parent9696e6c3e7e952b66ac3f5c9ddc3dfca4233451e (diff)
downloadvaadin-framework-df13b061f2f6ba10beae64d9b358c0365736370e.tar.gz
vaadin-framework-df13b061f2f6ba10beae64d9b358c0365736370e.zip
Remove csrfToken if disable-xsrf-protection is true (#14111)
If the server sends no token and the client value remains "init" then it's not sent back to the server. Change-Id: I74fc470c5c22d57c4a48eab3e4476ae4cc2dd242
Diffstat (limited to 'server')
-rw-r--r--server/src/com/vaadin/server/communication/ServerRpcHandler.java8
-rw-r--r--server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java248
2 files changed, 255 insertions, 1 deletions
diff --git a/server/src/com/vaadin/server/communication/ServerRpcHandler.java b/server/src/com/vaadin/server/communication/ServerRpcHandler.java
index 6f1d44d087..9107a4e049 100644
--- a/server/src/com/vaadin/server/communication/ServerRpcHandler.java
+++ b/server/src/com/vaadin/server/communication/ServerRpcHandler.java
@@ -78,7 +78,13 @@ public class ServerRpcHandler implements Serializable {
public RpcRequest(String jsonString, VaadinRequest request)
throws JSONException {
json = new JSONObject(jsonString);
- csrfToken = json.getString(ApplicationConstants.CSRF_TOKEN);
+
+ String csrfToken = json.optString(ApplicationConstants.CSRF_TOKEN);
+ if (csrfToken.equals("")) {
+ csrfToken = ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE;
+ }
+ this.csrfToken = csrfToken;
+
if (request.getService().getDeploymentConfiguration()
.isSyncIdCheckEnabled()) {
syncId = json.getInt(ApplicationConstants.SERVER_SYNC_ID);
diff --git a/server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java b/server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java
new file mode 100644
index 0000000000..30f1c85fef
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server;
+
+import java.util.UUID;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.easymock.EasyMock;
+import org.json.JSONException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.server.ServiceException;
+import com.vaadin.server.VaadinService;
+import com.vaadin.server.VaadinServlet;
+import com.vaadin.server.VaadinServletRequest;
+import com.vaadin.server.VaadinServletService;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.server.communication.ServerRpcHandler.RpcRequest;
+import com.vaadin.shared.ApplicationConstants;
+import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.tests.util.MockDeploymentConfiguration;
+
+/**
+ * Test the actual csrf token validation by the server.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class CsrfTokenMissingTestServer {
+
+ // Dummy fields just to run the test.
+ private VaadinServlet mockServlet;
+
+ // The mock deployment configuration.
+ private MockDeploymentConfiguration mockDeploymentConfiguration;
+
+ private VaadinServletService mockService;
+
+ // The mock UI session.
+ private VaadinSession mockSession;
+
+ // The mock vaadin request.
+ private VaadinServletRequest vaadinRequest;
+
+ /**
+ * Initialize the mock servlet and other stuff for our tests.
+ */
+ @Before
+ public void initMockStuff() throws ServiceException {
+ mockServlet = new VaadinServlet();
+ mockDeploymentConfiguration = new MockDeploymentConfiguration();
+
+ mockService = new VaadinServletService(mockServlet,
+ mockDeploymentConfiguration);
+
+ mockSession = new AlwaysLockedVaadinSession(mockService);
+
+ vaadinRequest = new VaadinServletRequest(
+ EasyMock.createMock(HttpServletRequest.class), mockService);
+
+ }
+
+ private enum TokenType {
+ MISSING, INVALID, VALID
+ }
+
+ private TokenType tokenType;
+
+ private String invalidToken;
+
+ public String getInvalidToken() {
+ if (invalidToken == null) {
+ // Just making sure this will never be in the same format as a valid
+ // token.
+ invalidToken = UUID.randomUUID().toString().substring(1);
+ }
+ return invalidToken;
+ }
+
+ private String getValidToken() {
+ return mockSession.getCsrfToken();
+ }
+
+ /*
+ * Gets the payload with the default token.
+ */
+ private String getPayload() {
+ switch (tokenType) {
+ case MISSING:
+ return getPayload(null);
+
+ case INVALID:
+ return getPayload(getInvalidToken());
+
+ case VALID:
+ return getPayload(getValidToken());
+ }
+
+ return null;
+ }
+
+ /*
+ * Gets the payload with the specified token.
+ */
+ private String getPayload(String token) {
+ return "{"
+ + (token != null ? "\"csrfToken\":" + "\"" + token + "\", "
+ : "")
+ + "\"rpc\":[[\"0\",\"com.vaadin.shared.ui.ui.UIServerRpc\",\"resize\",[\"449\",\"1155\",\"1155\",\"449\"]],[\"4\",\"com.vaadin.shared.ui.button.ButtonServerRpc\",\"click\",[{\"clientY\":\"53\", \"clientX\":\"79\", \"shiftKey\":false, \"button\":\"LEFT\", \"ctrlKey\":false, \"type\":\"1\", \"metaKey\":false, \"altKey\":false, \"relativeY\":\"17\", \"relativeX\":\"61\"}]]], \"syncId\":1}";
+ }
+
+ /*
+ * Init the test parameters.
+ */
+ private void initTest(boolean enableSecurity, TokenType tokenType) {
+ mockDeploymentConfiguration.setXsrfProtectionEnabled(enableSecurity);
+ this.tokenType = tokenType;
+ }
+
+ /*
+ * Create the requets.
+ */
+ private RpcRequest createRequest() {
+ try {
+ return new RpcRequest(getPayload(), vaadinRequest);
+ } catch (JSONException e) {
+ LOGGER.log(Level.SEVERE, "", e);
+
+ Assert.assertTrue(false);
+ return null;
+ }
+ }
+
+ /*
+ * Gets whether the token from the request is the default one.
+ */
+ private boolean isDefaultToken(RpcRequest rpcRequest) {
+ return ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE.equals(rpcRequest
+ .getCsrfToken());
+ }
+
+ /*
+ * Gets whether the token from the request is the invalid one.
+ */
+ private boolean isInvalidToken(RpcRequest rpcRequest) {
+ return getInvalidToken().equals(rpcRequest.getCsrfToken());
+ }
+
+ /*
+ * Gets whether the token from the request is the valid one.
+ */
+ private boolean isValidToken(RpcRequest rpcRequest) {
+ return getValidToken().equals(rpcRequest.getCsrfToken());
+ }
+
+ /*
+ * Gets whether the token from the request is valid.
+ */
+ private boolean isRequestValid(RpcRequest rpcRequest) {
+ return VaadinService.isCsrfTokenValid(mockSession,
+ rpcRequest.getCsrfToken());
+ }
+
+ private static Logger LOGGER = Logger
+ .getLogger(CsrfTokenMissingTestServer.class.getName());
+ static {
+ LOGGER.setLevel(Level.ALL);
+ }
+
+ @Test
+ public void securityOnAndNoToken() {
+ initTest(true, TokenType.MISSING);
+
+ RpcRequest rpcRequest = createRequest();
+
+ Assert.assertTrue(isDefaultToken(rpcRequest));
+ Assert.assertFalse(isRequestValid(rpcRequest));
+ }
+
+ @Test
+ public void securityOffAndNoToken() {
+ initTest(false, TokenType.MISSING);
+
+ RpcRequest rpcRequest = createRequest();
+
+ Assert.assertTrue(isDefaultToken(rpcRequest));
+ Assert.assertTrue(isRequestValid(rpcRequest));
+ }
+
+ @Test
+ public void securityOnAndInvalidToken() {
+ initTest(true, TokenType.INVALID);
+
+ RpcRequest rpcRequest = createRequest();
+
+ Assert.assertTrue(isInvalidToken(rpcRequest));
+ Assert.assertFalse(isRequestValid(rpcRequest));
+ }
+
+ @Test
+ public void securityOffAndInvalidToken() {
+ initTest(false, TokenType.INVALID);
+
+ RpcRequest rpcRequest = createRequest();
+
+ Assert.assertTrue(isInvalidToken(rpcRequest));
+ Assert.assertTrue(isRequestValid(rpcRequest));
+ }
+
+ @Test
+ public void securityOnAndValidToken() {
+ initTest(true, TokenType.VALID);
+
+ RpcRequest rpcRequest = createRequest();
+
+ Assert.assertTrue(isValidToken(rpcRequest));
+ Assert.assertTrue(isRequestValid(rpcRequest));
+ }
+
+ @Test
+ public void securityOffAndValidToken() {
+ initTest(false, TokenType.VALID);
+
+ RpcRequest rpcRequest = createRequest();
+
+ Assert.assertTrue(isValidToken(rpcRequest));
+ Assert.assertTrue(isRequestValid(rpcRequest));
+ }
+
+}