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
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
if(!hasValidCSRFToken(request)) {
|
||||||
|
respondCSRFError(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String serverName = request.getServerName();
|
String serverName = request.getServerName();
|
||||||
|
|
||||||
|
@ -93,12 +93,6 @@ public class GetLanguagesCommand extends Command {
|
|||||||
@Override
|
@Override
|
||||||
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
doPost(request, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
|
||||||
throws ServletException, IOException {
|
|
||||||
|
|
||||||
String modname = request.getParameter("module");
|
String modname = request.getParameter("module");
|
||||||
if (modname == null) {
|
if (modname == null) {
|
||||||
|
@ -62,11 +62,16 @@ public class LoadLanguageCommand extends Command {
|
|||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
doPost(request, response);
|
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
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
|
||||||
String modname = request.getParameter("module");
|
String modname = request.getParameter("module");
|
||||||
if (modname == null) {
|
if (modname == null) {
|
||||||
modname = "core";
|
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: []
|
actionAreas: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Requests a CSRF token and calls the supplied callback
|
||||||
|
// with the token
|
||||||
Refine.wrapCSRF = function(onCSRF) {
|
Refine.wrapCSRF = function(onCSRF) {
|
||||||
$.get(
|
$.get(
|
||||||
"command/core/get-csrf-token",
|
"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.postCSRF = function(url, data, success, dataType) {
|
||||||
Refine.wrapCSRF(function(token) {
|
Refine.wrapCSRF(function(token) {
|
||||||
var fullData = data || {};
|
var fullData = data || {};
|
||||||
data['csrf_token'] = token;
|
fullData['csrf_token'] = token;
|
||||||
$.post(url, fulldata, success, dataType);
|
$.post(url, fullData, success, dataType);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var lang = (navigator.language|| navigator.userLanguage).split("-")[0];
|
var lang = (navigator.language|| navigator.userLanguage).split("-")[0];
|
||||||
var dictionary = "";
|
var dictionary = "";
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -59,16 +59,16 @@ Refine.OpenProjectUI = function(elmt) {
|
|||||||
|
|
||||||
$('#projects-workspace-open').text($.i18n('core-index-open/browse'));
|
$('#projects-workspace-open').text($.i18n('core-index-open/browse'));
|
||||||
$('#projects-workspace-open').click(function() {
|
$('#projects-workspace-open').click(function() {
|
||||||
$.ajax({
|
Refine.postCSRF(
|
||||||
type: "POST",
|
"command/core/open-workspace-dir",
|
||||||
url: "command/core/open-workspace-dir",
|
{},
|
||||||
dataType: "json",
|
function (data) {
|
||||||
success: function (data) {
|
|
||||||
if (data.code != "ok" && "message" in data) {
|
if (data.code != "ok" && "message" in data) {
|
||||||
alert(data.message);
|
alert(data.message);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
"json"
|
||||||
|
);
|
||||||
});
|
});
|
||||||
Refine.TagsManager.allProjectTags = [];
|
Refine.TagsManager.allProjectTags = [];
|
||||||
this._buildTagsAndFetchProjects();
|
this._buildTagsAndFetchProjects();
|
||||||
|
@ -421,8 +421,8 @@ Refine.wrapCSRF = function(onCSRF) {
|
|||||||
Refine.postCSRF = function(url, data, success, dataType) {
|
Refine.postCSRF = function(url, data, success, dataType) {
|
||||||
Refine.wrapCSRF(function(token) {
|
Refine.wrapCSRF(function(token) {
|
||||||
var fullData = data || {};
|
var fullData = data || {};
|
||||||
data['csrf_token'] = token;
|
fullData['csrf_token'] = token;
|
||||||
$.post(url, fulldata, success, dataType);
|
$.post(url, fullData, success, dataType);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user