Adding reproducer
@@ -331,4 +331,65 @@ public class CSRFHandlerTest extends WebTestBase {
testRequest(HttpMethod.GET, "/xsrf", req -> req.putHeader("Origin", "http://myserver.com/"), null, 200, "OK", null);
testRequest(HttpMethod.GET, "/xsrf", req -> req.putHeader("Origin", "http://myserver.com:80"), null, 200, "OK", null);
}
+
+ @Test
+ public void testPostAfterPost() throws Exception {
+
+ final AtomicReference<String> cookieJar = new AtomicReference<>();
+
+ router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)));
+ router.route().handler(CSRFHandler.create(vertx, "Abracadabra"));
+ router.route().handler(rc -> rc.response().end());
+
+ testRequest(HttpMethod.GET, "/", null, resp -> {
+ List<String> cookies = resp.headers().getAll("set-cookie");
+ assertEquals(2, cookies.size());
+ String encodedCookie = "";
+ // save the cookies
+ for (String cookie : cookies) {
+ encodedCookie += cookie.substring(0, cookie.indexOf(';'));
+ encodedCookie += "; ";
+ if (cookie.startsWith(CSRFHandler.DEFAULT_COOKIE_NAME)) {
+ tmpCookie = cookie.substring(cookie.indexOf('=') + 1, cookie.indexOf(';'));
+ }
+ }
+ cookieJar.set(encodedCookie);
+ }, 200, "OK", null);
+
+ // POST shall be OK as the token is on the session
+ testRequest(HttpMethod.POST, "/", req -> {
+ req.putHeader("cookie", cookieJar.get());
+ req.putHeader(CSRFHandler.DEFAULT_HEADER_NAME, tmpCookie);
+ }, resp -> {
+ // re-extract the new cookie
+ List<String> cookies = resp.headers().getAll("set-cookie");
+ // only the XSRF cookie is updated
+ assertEquals(1, cookies.size());
+ String encodedCookie = "";
+ // save the cookie
+ for (String cookie : cookieJar.get().split(";")) {
+ cookie = cookie.trim();
+ if ("".equals(cookie)) {
+ continue;
+ }
+ if (cookie.startsWith(CSRFHandler.DEFAULT_COOKIE_NAME)) {
+ // replace with new one
+ tmpCookie = cookies.get(0).substring(cookies.get(0).indexOf('=') + 1, cookies.get(0).indexOf(';'));
+ encodedCookie += CSRFHandler.DEFAULT_COOKIE_NAME + "=" + tmpCookie;
+ } else {
+ encodedCookie += cookie;
+ }
+ encodedCookie += "; ";
+ }
+ // cookies must be different now
+ assertFalse(cookieJar.get().equals(encodedCookie));
+ cookieJar.set(encodedCookie);
+ }, 200, "OK", null);
+ // second POST should be fine
+ testRequest(HttpMethod.POST, "/", req -> {
+ req.putHeader("cookie", cookieJar.get());
+ req.putHeader(CSRFHandler.DEFAULT_HEADER_NAME, tmpCookie);
+ }, null, 200, "OK", null);
+
+ }
}
