1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
From: Markus Koschany <apo@debian.org>
Date: Sat, 27 Sep 2025 17:51:56 +0200
Subject: CVE-2024-49760
Bug-Debian: https://bugs.debian.org/1086041
Origin: https://github.com/OpenRefine/OpenRefine/commit/478285afffea59c893ac472faa74898ab9e5e95a
---
.../com/google/refine/commands/lang/LoadLanguageCommand.java | 9 ++++++++-
.../refine/commands/lang/LoadLanguageCommandTests.java | 12 ++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/main/src/com/google/refine/commands/lang/LoadLanguageCommand.java b/main/src/com/google/refine/commands/lang/LoadLanguageCommand.java
index 002b908..85bf2e0 100644
--- a/main/src/com/google/refine/commands/lang/LoadLanguageCommand.java
+++ b/main/src/com/google/refine/commands/lang/LoadLanguageCommand.java
@@ -126,7 +126,14 @@ public class LoadLanguageCommand extends Command {
static ObjectNode loadLanguage(RefineServlet servlet, String modname, String lang) throws UnsupportedEncodingException {
ButterflyModule module = servlet.getModule(modname);
- File langFile = new File(module.getPath(), "langs" + File.separator + "translation-" + lang + ".json");
+ String strLangFile = "translation-" + lang + ".json";
+ File langsDir = new File(module.getPath(), "langs");
+ File langFile = new File(langsDir, strLangFile);
+ if (!langFile.toPath().normalize().toAbsolutePath().startsWith(langsDir.toPath().normalize().toAbsolutePath())) {
+ logger.error("Security: Attempt to escape the langs directory to read another file");
+ return null;
+ }
+
try {
Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(langFile), "UTF-8"));
return ParsingUtilities.mapper.readValue(reader, ObjectNode.class);
diff --git a/main/tests/server/src/com/google/refine/commands/lang/LoadLanguageCommandTests.java b/main/tests/server/src/com/google/refine/commands/lang/LoadLanguageCommandTests.java
index ce569b5..0e073d3 100644
--- a/main/tests/server/src/com/google/refine/commands/lang/LoadLanguageCommandTests.java
+++ b/main/tests/server/src/com/google/refine/commands/lang/LoadLanguageCommandTests.java
@@ -77,6 +77,18 @@ public class LoadLanguageCommandTests extends CommandTestBase {
assertEquals(response.get("lang").asText(), "en");
}
+ @Test
+ public void testLoadLanguageWithDirectorySlip() throws JsonParseException, JsonMappingException, IOException, ServletException {
+ when(request.getParameter("module")).thenReturn("core");
+ when(request.getParameterValues("lang")).thenReturn(new String[] { "../../../secrets" });
+
+ command.doPost(request, response);
+
+ JsonNode response = ParsingUtilities.mapper.readValue(writer.toString(), JsonNode.class);
+ assertTrue(response.has("dictionary"));
+ assertEquals(response.get("lang").asText(), "en");
+ }
+
@Test
public void testLanguageFallback() throws JsonParseException, JsonMappingException, IOException {
String fallbackJson = "{"
|