diff options
author | Bogdan Udrescu <bogdan@vaadin.com> | 2014-07-09 18:40:26 +0300 |
---|---|---|
committer | Leif Åstrand <leif@vaadin.com> | 2014-07-15 08:50:38 +0000 |
commit | df13b061f2f6ba10beae64d9b358c0365736370e (patch) | |
tree | 0a2800b1e383f3f7fb648ea5ec9ec9512e54906d /server | |
parent | 9696e6c3e7e952b66ac3f5c9ddc3dfca4233451e (diff) | |
download | vaadin-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.java | 8 | ||||
-rw-r--r-- | server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java | 248 |
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)); + } + +} |