From 87344e802f21b8f87ac429d61737fbff3ce31119 Mon Sep 17 00:00:00 2001
From: "pixeebot[bot]" <104101892+pixeebot[bot]@users.noreply.github.com>
Date: Wed, 13 Aug 2025 03:43:07 +0000
Subject: [PATCH] Sandboxed URL creation to prevent SSRF attacks
---
core/pom.xml | 4 ++++
.../main/java/org/libreoffice/lots/WollMuxFiles.java | 8 +++++---
.../java/org/libreoffice/lots/WollMuxSingleton.java | 4 +++-
.../java/org/libreoffice/lots/config/ConfigThingy.java | 4 +++-
.../lots/config/generator/xml/XMLGenerator.java | 10 ++++++----
.../org/libreoffice/lots/config/scanner/Scanner.java | 5 +++--
.../java/org/libreoffice/lots/db/ThingyDatasource.java | 4 +++-
.../org/libreoffice/lots/document/DocumentLoader.java | 4 +++-
.../org/libreoffice/lots/event/handlers/OnSaveAs.java | 4 +++-
.../libreoffice/lots/func/Dateinamensanpassungen.java | 4 +++-
.../lots/mailmerge/sidebar/MailMergeController.java | 4 +++-
pom.xml | 6 ++++++
12 files changed, 45 insertions(+), 16 deletions(-)
diff --git a/core/pom.xml b/core/pom.xml
index 1136316b8..94752e880 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -235,5 +235,9 @@
com.googlecode.gettext-commons
gettext-maven-plugin
+
+ io.github.pixee
+ java-security-toolkit
+
diff --git a/core/src/main/java/org/libreoffice/lots/WollMuxFiles.java b/core/src/main/java/org/libreoffice/lots/WollMuxFiles.java
index 7d602948d..70f45bcf3 100755
--- a/core/src/main/java/org/libreoffice/lots/WollMuxFiles.java
+++ b/core/src/main/java/org/libreoffice/lots/WollMuxFiles.java
@@ -22,6 +22,8 @@
*/
package org.libreoffice.lots;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
@@ -395,7 +397,7 @@ public static URL getDefaultContext()
*/
public static URL makeURL(String urlStr) throws MalformedURLException
{
- return new URL(WollMuxFiles.getDefaultContext(), ConfigThingy.urlEncode(urlStr));
+ return Urls.create(WollMuxFiles.getDefaultContext(), ConfigThingy.urlEncode(urlStr), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
}
/**
@@ -438,7 +440,7 @@ public static void determineDefaultContext()
{
defaultContextURL = file.toURI().toURL();
}
- defaultContextURL = new URL(defaultContextURL, urlVerzStr);
+ defaultContextURL = Urls.create(defaultContextURL, urlVerzStr, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
} catch (MalformedURLException e)
{
LOGGER.error("", e);
@@ -615,7 +617,7 @@ private static void dumpJVMSettings(OutputStream outStream, BufferedWriter out)
{
XStringSubstitution subst = UNO
.XStringSubstitution(UnoComponent.createComponentWithContext(UnoComponent.CSS_UTIL_PATH_SUBSTITUTION));
- String jConfPath = new URL(subst.substituteVariables("$(user)/config", true)).toURI()
+ String jConfPath = Urls.create(subst.substituteVariables("$(user)/config", true), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS).toURI()
.getPath();
File[] jConfFiles = new File(jConfPath).listFiles();
Pattern p = Pattern.compile("^javasettings_.*\\.xml$", Pattern.CASE_INSENSITIVE);
diff --git a/core/src/main/java/org/libreoffice/lots/WollMuxSingleton.java b/core/src/main/java/org/libreoffice/lots/WollMuxSingleton.java
index 3d279e604..fc1fc168a 100644
--- a/core/src/main/java/org/libreoffice/lots/WollMuxSingleton.java
+++ b/core/src/main/java/org/libreoffice/lots/WollMuxSingleton.java
@@ -22,6 +22,8 @@
*/
package org.libreoffice.lots;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
@@ -314,7 +316,7 @@ private static void registerDatasources(ConfigThingy conf, URL context)
String parsedUrl;
try
{
- URL url = new URL(context, ConfigThingy.urlEncode(urlStr));
+ URL url = Urls.create(context, ConfigThingy.urlEncode(urlStr), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
parsedUrl = UNO.getParsedUNOUrl(url.toExternalForm()).Complete;
} catch (Exception x)
{
diff --git a/core/src/main/java/org/libreoffice/lots/config/ConfigThingy.java b/core/src/main/java/org/libreoffice/lots/config/ConfigThingy.java
index 3f7e5e13b..d595a4807 100644
--- a/core/src/main/java/org/libreoffice/lots/config/ConfigThingy.java
+++ b/core/src/main/java/org/libreoffice/lots/config/ConfigThingy.java
@@ -22,6 +22,8 @@
*/
package org.libreoffice.lots.config;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
@@ -267,7 +269,7 @@ protected void childrenFromUrl(URL url, Reader read) throws IOException,
{
try
{
- URL includeURL = new URL(url, urlEncode(token2.contentString()));
+ URL includeURL = Urls.create(url, urlEncode(token2.contentString()), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
stack.peek().childrenFromUrl(includeURL,
new InputStreamReader(includeURL.openStream(), CHARSET));
}
diff --git a/core/src/main/java/org/libreoffice/lots/config/generator/xml/XMLGenerator.java b/core/src/main/java/org/libreoffice/lots/config/generator/xml/XMLGenerator.java
index 5a97a6bee..7f8d96f50 100644
--- a/core/src/main/java/org/libreoffice/lots/config/generator/xml/XMLGenerator.java
+++ b/core/src/main/java/org/libreoffice/lots/config/generator/xml/XMLGenerator.java
@@ -22,6 +22,8 @@
*/
package org.libreoffice.lots.config.generator.xml;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
@@ -325,7 +327,7 @@ private void createFile(final Token token) throws MalformedURLException
element.setTextContent(token.getContent());
files.peek().appendChild(element);
}
- URL context = new URL("file:" + files.peek().getAttribute(FILE_NAME));
+ URL context = Urls.create("file:" + files.peek().getAttribute(FILE_NAME), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
String newFile = PathProcessor.processInclude(token.getContent());
Path path = Paths.get(newFile);
element = document.createElement(XMLTags.FILE.getName());
@@ -334,16 +336,16 @@ private void createFile(final Token token) throws MalformedURLException
{
if(path.toFile().exists())
{
- element.setAttribute(FILE_NAME, new URL(context, "/" + newFile).getPath());
+ element.setAttribute(FILE_NAME, Urls.create(context, "/" + newFile, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS).getPath());
}
else
{
- element.setAttribute(FILE_NAME, new URL(context, newFile).getPath());
+ element.setAttribute(FILE_NAME, Urls.create(context, newFile, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS).getPath());
}
}
else
{
- element.setAttribute(FILE_NAME, new URL(context, newFile).getPath());
+ element.setAttribute(FILE_NAME, Urls.create(context, newFile, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS).getPath());
}
config.appendChild(element);
files.push(element);
diff --git a/core/src/main/java/org/libreoffice/lots/config/scanner/Scanner.java b/core/src/main/java/org/libreoffice/lots/config/scanner/Scanner.java
index 5cd16a158..d952c55f9 100644
--- a/core/src/main/java/org/libreoffice/lots/config/scanner/Scanner.java
+++ b/core/src/main/java/org/libreoffice/lots/config/scanner/Scanner.java
@@ -22,6 +22,8 @@
*/
package org.libreoffice.lots.config.scanner;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
@@ -117,8 +119,7 @@ public Token next()
{
try
{
- stack.push(new Tokenizer(new URL(stack.peek().getFilename(),
- PathProcessor.processInclude(token.getContent()))));
+ stack.push(new Tokenizer(Urls.create(stack.peek().getFilename(), PathProcessor.processInclude(token.getContent()), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS)));
} catch (final IOException e)
{
LOGGER.error("Could not open file for token {}.", token.getContent(), e);
diff --git a/core/src/main/java/org/libreoffice/lots/db/ThingyDatasource.java b/core/src/main/java/org/libreoffice/lots/db/ThingyDatasource.java
index 381fddfa2..eea820347 100644
--- a/core/src/main/java/org/libreoffice/lots/db/ThingyDatasource.java
+++ b/core/src/main/java/org/libreoffice/lots/db/ThingyDatasource.java
@@ -22,6 +22,8 @@
*/
package org.libreoffice.lots.db;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
@@ -67,7 +69,7 @@ public ThingyDatasource(Map nameToDatasource, ConfigThingy s
try
{
- URL url = new URL(context, ConfigThingy.urlEncode(urlStr));
+ URL url = Urls.create(context, ConfigThingy.urlEncode(urlStr), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
ConfigThingy conf = new ConfigThingy(name, url);
ConfigThingy schemaDesc = conf.get("Schema");
diff --git a/core/src/main/java/org/libreoffice/lots/document/DocumentLoader.java b/core/src/main/java/org/libreoffice/lots/document/DocumentLoader.java
index 1d652be2e..b38e18f40 100644
--- a/core/src/main/java/org/libreoffice/lots/document/DocumentLoader.java
+++ b/core/src/main/java/org/libreoffice/lots/document/DocumentLoader.java
@@ -22,6 +22,8 @@
*/
package org.libreoffice.lots.document;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@@ -91,7 +93,7 @@ public ByteBuffer load(String url) throws Exception
private ByteBuffer downloadDocument(String url)
{
byte[] buf = null;
- try (InputStream in = new URL(url).openStream())
+ try (InputStream in = Urls.create(url, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS).openStream())
{
buf = IOUtils.toByteArray(in);
} catch (IOException e)
diff --git a/core/src/main/java/org/libreoffice/lots/event/handlers/OnSaveAs.java b/core/src/main/java/org/libreoffice/lots/event/handlers/OnSaveAs.java
index edb36c501..feba119ed 100644
--- a/core/src/main/java/org/libreoffice/lots/event/handlers/OnSaveAs.java
+++ b/core/src/main/java/org/libreoffice/lots/event/handlers/OnSaveAs.java
@@ -22,6 +22,8 @@
*/
package org.libreoffice.lots.event.handlers;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
@@ -131,7 +133,7 @@ private File getDefaultFile(Function func)
try
{
Object ps = UnoComponent.createComponentWithContext(UnoComponent.CSS_UTIL_PATH_SETTINGS);
- URL dir = new URL(AnyConverter.toString(Utils.getProperty(ps, UnoProperty.WORK)));
+ URL dir = Urls.create(AnyConverter.toString(Utils.getProperty(ps, UnoProperty.WORK)), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
return new File(dir.getPath(), filename);
} catch (com.sun.star.lang.IllegalArgumentException
| MalformedURLException e)
diff --git a/core/src/main/java/org/libreoffice/lots/func/Dateinamensanpassungen.java b/core/src/main/java/org/libreoffice/lots/func/Dateinamensanpassungen.java
index 1b76d7910..1aa7b1187 100644
--- a/core/src/main/java/org/libreoffice/lots/func/Dateinamensanpassungen.java
+++ b/core/src/main/java/org/libreoffice/lots/func/Dateinamensanpassungen.java
@@ -22,6 +22,8 @@
*/
package org.libreoffice.lots.func;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
@@ -109,7 +111,7 @@ public static String lhmDateinamensanpassung(String fileName)
{
// gets the working directory path from LO
Object ps = UnoComponent.createComponentWithContext(UnoComponent.CSS_UTIL_PATH_SETTINGS);
- URL dir = new URL(AnyConverter.toString(UnoProperty.getProperty(ps, UnoProperty.WORK)));
+ URL dir = Urls.create(AnyConverter.toString(UnoProperty.getProperty(ps, UnoProperty.WORK)), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
f = new File(dir.getPath(), fileName);
} catch (MalformedURLException | UnoHelperException e)
{
diff --git a/core/src/main/java/org/libreoffice/lots/mailmerge/sidebar/MailMergeController.java b/core/src/main/java/org/libreoffice/lots/mailmerge/sidebar/MailMergeController.java
index 230ff528f..32c88713d 100644
--- a/core/src/main/java/org/libreoffice/lots/mailmerge/sidebar/MailMergeController.java
+++ b/core/src/main/java/org/libreoffice/lots/mailmerge/sidebar/MailMergeController.java
@@ -22,6 +22,8 @@
*/
package org.libreoffice.lots.mailmerge.sidebar;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
@@ -781,7 +783,7 @@ private void openCalcFromSettings(ConfigThingy datenquelle)
String model = "";
try
{
- String[] splittedURL = Paths.get(new URL(url).toURI()).toFile().getName().split("\\.");
+ String[] splittedURL = Paths.get(Urls.create(url, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS).toURI()).toFile().getName().split("\\.");
model = splittedURL[splittedURL.length - 2];
} catch (MalformedURLException | URISyntaxException e)
{
diff --git a/pom.xml b/pom.xml
index 136bbc715..187f2b945 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,6 +18,7 @@
${project.build.directory}/config/.lots/lots.conf
${project.build.directory}/office
false
+ 1.2.1
@@ -397,6 +398,11 @@
0.8.5
test
+
+ io.github.pixee
+ java-security-toolkit
+ ${versions.java-security-toolkit}
+