CSRF protection for OpenWorkspaceDirCommand and language loading
This commit is contained in:
parent
f7177e670d
commit
a340c137d0
@ -48,6 +48,10 @@ public class OpenWorkspaceDirCommand extends Command {
|
||||
@Override
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
if(!hasValidCSRFToken(request)) {
|
||||
respondCSRFError(response);
|
||||
return;
|
||||
}
|
||||
|
||||
String serverName = request.getServerName();
|
||||
|
||||
|
@ -93,12 +93,6 @@ public class GetLanguagesCommand extends Command {
|
||||
@Override
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
doPost(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
|
||||
String modname = request.getParameter("module");
|
||||
if (modname == null) {
|
||||
|
@ -63,10 +63,15 @@ public class LoadLanguageCommand extends Command {
|
||||
doPost(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST is supported but does not actually change any state so we do
|
||||
* not add CSRF protection to it. This ensures existing extensions will not
|
||||
* have to be updated to add a CSRF token to their requests (2019-11-10)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
|
||||
String modname = request.getParameter("module");
|
||||
if (modname == null) {
|
||||
modname = "core";
|
||||
|
@ -0,0 +1,23 @@
|
||||
package com.google.refine.commands;
|
||||
import com.google.refine.commands.CommandTestBase;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class OpenWorkspaceDirCommandTests extends CommandTestBase {
|
||||
|
||||
@BeforeMethod
|
||||
public void setUpCommand() {
|
||||
command = new OpenWorkspaceDirCommand();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCSRFProtection() throws ServletException, IOException {
|
||||
command.doPost(request, response);
|
||||
assertCSRFCheckFailed();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
package com.google.refine.commands.lang;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.google.refine.RefineServlet;
|
||||
import com.google.refine.commands.CommandTestBase;
|
||||
import com.google.refine.util.ParsingUtilities;
|
||||
|
||||
import edu.mit.simile.butterfly.ButterflyModule;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class LoadLanguageCommandTests extends CommandTestBase {
|
||||
|
||||
@BeforeMethod
|
||||
public void setUpCommand() {
|
||||
command = new LoadLanguageCommand();
|
||||
ButterflyModule coreModule = mock(ButterflyModule.class);
|
||||
|
||||
when(coreModule.getName()).thenReturn("core");
|
||||
when(coreModule.getPath()).thenReturn(new File("webapp/modules/core"));
|
||||
RefineServlet servlet = mock(RefineServlet.class);
|
||||
when(servlet.getModule("core")).thenReturn(coreModule);
|
||||
command.init(servlet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadLanguages() throws ServletException, IOException {
|
||||
when(request.getParameter("module")).thenReturn("core");
|
||||
when(request.getParameterValues("lang")).thenReturn(new String[] {"en"});
|
||||
|
||||
command.doPost(request, response);
|
||||
|
||||
JsonNode response = ParsingUtilities.mapper.readValue(writer.toString(), JsonNode.class);
|
||||
assertTrue(response.has("dictionary"));
|
||||
assertTrue(response.has("lang"));
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ var Refine = {
|
||||
actionAreas: []
|
||||
};
|
||||
|
||||
// Requests a CSRF token and calls the supplied callback
|
||||
// with the token
|
||||
Refine.wrapCSRF = function(onCSRF) {
|
||||
$.get(
|
||||
"command/core/get-csrf-token",
|
||||
@ -48,15 +50,17 @@ Refine.wrapCSRF = function(onCSRF) {
|
||||
);
|
||||
};
|
||||
|
||||
// Performs a POST request where an additional CSRF token
|
||||
// is supplied in the POST data. The arguments match those
|
||||
// of $.post().
|
||||
Refine.postCSRF = function(url, data, success, dataType) {
|
||||
Refine.wrapCSRF(function(token) {
|
||||
var fullData = data || {};
|
||||
data['csrf_token'] = token;
|
||||
$.post(url, fulldata, success, dataType);
|
||||
fullData['csrf_token'] = token;
|
||||
$.post(url, fullData, success, dataType);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var lang = (navigator.language|| navigator.userLanguage).split("-")[0];
|
||||
var dictionary = "";
|
||||
$.ajax({
|
||||
|
@ -59,16 +59,16 @@ Refine.OpenProjectUI = function(elmt) {
|
||||
|
||||
$('#projects-workspace-open').text($.i18n('core-index-open/browse'));
|
||||
$('#projects-workspace-open').click(function() {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "command/core/open-workspace-dir",
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
Refine.postCSRF(
|
||||
"command/core/open-workspace-dir",
|
||||
{},
|
||||
function (data) {
|
||||
if (data.code != "ok" && "message" in data) {
|
||||
alert(data.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
"json"
|
||||
);
|
||||
});
|
||||
Refine.TagsManager.allProjectTags = [];
|
||||
this._buildTagsAndFetchProjects();
|
||||
|
@ -421,8 +421,8 @@ Refine.wrapCSRF = function(onCSRF) {
|
||||
Refine.postCSRF = function(url, data, success, dataType) {
|
||||
Refine.wrapCSRF(function(token) {
|
||||
var fullData = data || {};
|
||||
data['csrf_token'] = token;
|
||||
$.post(url, fulldata, success, dataType);
|
||||
fullData['csrf_token'] = token;
|
||||
$.post(url, fullData, success, dataType);
|
||||
});
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user