feat(libreoffice): block linked content from untrusted locations

This commit is contained in:
Julien Neuhart
2026-06-11 14:51:23 +02:00
parent 808a96f3d0
commit 98fc403478
6 changed files with 77 additions and 19 deletions
@@ -939,3 +939,28 @@ Feature: /forms/libreoffice/convert
Then the response header "Content-Type" should be "application/pdf"
Then there should be 1 PDF(s) in the response
Then the "foo.pdf" PDF should have 1 page(s)
# An embedded image is stored inside the document, not linked, so blocking
# untrusted linked content leaves it untouched. Guards against over-blocking.
@libreoffice-linked-content
Scenario: POST /forms/libreoffice/convert (Embedded Image Survives)
Given I have a default Gotenberg container
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
| files | testdata/libreoffice-embedded-image.fodt | file |
| Gotenberg-Output-Filename | foo | header |
Then the response status code should be 200
Then there should be 1 PDF(s) in the response
Then the "foo.pdf" PDF should have 1 image(s)
# An uploaded document always loads from an untrusted location, so soffice
# refuses to resolve any content it links (absolute file:// path or external
# URL). Closes the SSRF and local-file-read vector.
@libreoffice-linked-content
Scenario: POST /forms/libreoffice/convert (Linked External Resource Blocked)
Given I have a default Gotenberg container
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
| files | testdata/libreoffice-linked-external.fodt | file |
| Gotenberg-Output-Filename | foo | header |
Then the response status code should be 200
Then there should be 1 PDF(s) in the response
Then the "foo.pdf" PDF should have 0 image(s)
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
<office:body><office:text>
<text:p>An embedded image is stored in the document and must survive.</text:p>
<text:p><draw:frame text:anchor-type="as-char" svg:width="3cm" svg:height="3cm"><draw:image><office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC</office:binary-data></draw:image></draw:frame></text:p>
</office:text></office:body>
</office:document>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
<office:body><office:text>
<text:p>An image linked by absolute path outside the document folder must not load.</text:p>
<text:p><draw:frame text:anchor-type="as-char" svg:width="3cm" svg:height="3cm"><draw:image xlink:href="file:///usr/lib/libreoffice/share/gallery/backgrounds/giraffe.png" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/></draw:frame></text:p>
</office:text></office:body>
</office:document>