Hello,

I've prepared inkscape 1.2.2-2+deb12u1 for bookworm-security, and it's ready 
for review.

Inkscape 1.4-6 in Trixie already has this fix, because it went into upstream 
1.3 and 1.4 shipped with it, so the Bookworm upload is the one left to review. 
The debdiff against 1.2.2-2 is attached.

This is CVE-2026-4980. Inkscape 1.2.2 expands xi:include on every file it 
reads, which means an SVG opened from the command line can embed a local file, 
and upstream 5b7e540900eb limits that expansion to shortcut key files with one 
call to xmlXIncludeProcessFlags after the single readXml() in 
sp_repr_read_file. Inkscape 1.2.2 in Bookworm can parse that file twice, 
freeing the first document and reading again when the root is ns:svg, and the 
document from the second parse is the one returned, so the same check follows 
both reads. Inkscape 1.4 in Trixie repairs an ns:svg root during the first 
parse, which is why that patch has the one call.

Upstream added the XInclude flag as a default argument on sp_repr_read_file, 
and a default is filled in at compile time, so the symbol that would remain is 
the three-argument one. I kept the two-argument symbol as its own function, 
which calls a new three-argument overload with false, and the shortcut reader 
is the caller that passes true, so an SVG opened through the old symbol keeps 
the xi:include element and its fallback. libinkscape_base.so is private to 
/usr/bin/inkscape, and the packages that depend on inkscape call that binary.

I built this in a Bookworm schroot, and the package's own test suite passed; 
all 343 tests. I compared the archive binary, 1.2.2-2+b1, with this package. On 
the archive binary, an SVG that uses xi:include to point at a local file embeds 
that file in the export, and a file whose root element is ns:svg does the same. 
On this package, the export keeps the xi:include element and the fallback text, 
and a plain SVG exports as usual. The Adobe Illustrator shortcut preset is a 
file that includes inkscape.xml, and loading that file works.

The Salsa fork will be here: https://salsa.debian.org/tsimonq2/inkscape

Here is the Debusine work request: 
https://debusine.debian.net/debian/developers/work-request/1515746/

Feedback is welcome. If nothing showstopping comes up, I'll upload this and 
issue the DLA on Monday morning (October 26th, 2026).

Best regards,
Simon Quigley
[email protected]
diff -Nru inkscape-1.2.2/debian/changelog inkscape-1.2.2/debian/changelog
--- inkscape-1.2.2/debian/changelog     2023-01-09 19:09:18.000000000 -0600
+++ inkscape-1.2.2/debian/changelog     2026-10-22 15:52:21.000000000 -0500
@@ -1,3 +1,10 @@
+inkscape (1.2.2-2+deb12u1) bookworm-security; urgency=high
+
+  * Team upload.
+  * CVE-2026-4980: only process XInclude in shortcut key files.
+
+ -- Simon Quigley <[email protected]>  Thu, 22 Oct 2026 15:52:21 -0500
+
 inkscape (1.2.2-2) unstable; urgency=medium
 
   * Add several patches skipping several tests that fail across varying
diff -Nru inkscape-1.2.2/debian/patches/CVE-2026-4980.patch 
inkscape-1.2.2/debian/patches/CVE-2026-4980.patch
--- inkscape-1.2.2/debian/patches/CVE-2026-4980.patch   1969-12-31 
18:00:00.000000000 -0600
+++ inkscape-1.2.2/debian/patches/CVE-2026-4980.patch   2026-10-20 
18:49:07.000000000 -0500
@@ -0,0 +1,118 @@
+Origin: 
https://gitlab.com/inkscape/inkscape/-/commit/5b7e540900ebdfa6a5d6c5475193f5025160dbc5
+Reviewed-by: Simon Quigley <[email protected]>
+Last-Update: 2026-10-20
+
+Backported to 1.2.2. The two-argument symbol is unchanged.
+The three-argument overload is new. The Adobe ns:svg reread
+honors the same flag.
+
+From 5b7e540900ebdfa6a5d6c5475193f5025160dbc5 Mon Sep 17 00:00:00 2001
+From: Jeremy Stashewsky <[email protected]>
+Date: Mon, 1 May 2023 10:36:40 -0700
+Subject: [PATCH] Limit XInclude processing to shortcut keys files.
+
+This patch fixes a security vulnerability when using the batch or
+command-line processing features of Inkscape. The flaw allows an author
+of a malicious SVG file to trivially specify the href of a local or
+remote file to bring in as a `<text>` body or other element. The exact impact
+to security will depend a lot on the context in which inkscape is being
+run, but in the worst-case scenario this can lead to leaking of private
+information, credentials, etc. Formally, this is a Local File Inclusion
+(LFI) and Server Side Request Forgery (SSRF) vulnerability vector.
+
+XInclude processing is retained for shortcut "keys" files _only_, which
+seems to have been the original intent behind the commit that introduced
+the vulnerability:
+https://gitlab.com/inkscape/inkscape/-/commit/e6eee384cc7202d63136a3a1a8a5ccb990989d78
+
+diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp
+--- a/src/xml/repr-io.cpp
++++ b/src/xml/repr-io.cpp
+@@ -224,10 +224,6 @@
+     auto doc = xmlReadIO( readCb, closeCb, this,
+                       filename, getEncoding(), parse_options);
+ 
+-    if (doc && doc->properties && xmlXIncludeProcessFlags(doc, 
XML_PARSE_NOXINCNODE) < 0) {
+-        g_warning("XInclude processing failed for %s", filename);
+-    }
+-
+     return doc;
+ }
+ 
+@@ -321,9 +317,21 @@
+ /**
+  * Reads XML from a file, and returns the Document.
+  * The default namespace can also be specified, if desired.
++ * XIncude is dangerous to support during use-cases like automated file 
format conversion, so it is off by default.
++ *
++ * \param filename The actual file to read from.
++ *
++ * \param default_ns Default namespace for the document, can be nullptr.
++ *
++ * \param xinclude Process XInclude directives, which is off by default for 
security.
+  */
+ Document *sp_repr_read_file (const gchar * filename, const gchar *default_ns)
+ {
++    return sp_repr_read_file(filename, default_ns, false);
++}
++
++Document *sp_repr_read_file (const gchar * filename, const gchar *default_ns, 
bool xinclude)
++{
+     xmlDocPtr doc = nullptr;
+     Document * rdoc = nullptr;
+ 
+@@ -352,6 +360,9 @@
+ 
+     if (src.setFile(filename) == 0) {
+         doc = src.readXml();
++        if (xinclude && doc && doc->properties && 
xmlXIncludeProcessFlags(doc, XML_PARSE_NOXINCNODE) < 0) {
++            g_warning("XInclude processing failed for %s", filename);
++        }
+         rdoc = sp_repr_do_read(doc, default_ns);
+         // For some reason, failed ns loading results in this
+         // We try a system check version of load with NOENT for adobe
+@@ -359,6 +370,9 @@
+             xmlFreeDoc(doc);
+             src.setFile(filename, true);
+             doc = src.readXml();
++            if (xinclude && doc && doc->properties && 
xmlXIncludeProcessFlags(doc, XML_PARSE_NOXINCNODE) < 0) {
++                g_warning("XInclude processing failed for %s", filename);
++            }
+             rdoc = sp_repr_do_read(doc, default_ns);
+         }
+     }
+
+diff --git a/src/xml/repr.h b/src/xml/repr.h
+--- a/src/xml/repr.h
++++ b/src/xml/repr.h
+@@ -53,6 +53,7 @@
+ /* IO */
+ 
+ Inkscape::XML::Document *sp_repr_read_file(char const *filename, char const 
*default_ns);
++Inkscape::XML::Document *sp_repr_read_file(char const *filename, char const 
*default_ns, bool xinclude);
+ Inkscape::XML::Document *sp_repr_read_mem(char const *buffer, int length, 
char const *default_ns);
+ void sp_repr_write_stream(Inkscape::XML::Node *repr, Inkscape::IO::Writer 
&out,
+                           int indent_level,  bool add_whitespace, 
Glib::QueryQuark elide_prefix,
+
+diff --git a/src/ui/shortcuts.cpp b/src/ui/shortcuts.cpp
+--- a/src/ui/shortcuts.cpp
++++ b/src/ui/shortcuts.cpp
+@@ -225,7 +225,7 @@
+         return false;
+     }
+ 
+-    XML::Document *document = sp_repr_read_file(file->get_path().c_str(), 
nullptr);
++    XML::Document *document = sp_repr_read_file(file->get_path().c_str(), 
nullptr, true);
+     if (!document) {
+         std::cerr << "Shortcut::read: could not parse file: " << 
file->get_path() << std::endl;
+         return false;
+@@ -715,7 +715,7 @@
+         std::string label = Glib::path_get_basename(filename);
+         Glib::ustring filename_relative = 
sp_relative_path_from_path(filename, std::string(get_path(SYSTEM, KEYS)));
+ 
+-        XML::Document *document = sp_repr_read_file(filename.c_str(), 
nullptr);
++        XML::Document *document = sp_repr_read_file(filename.c_str(), 
nullptr, true);
+         if (!document) {
+             std::cerr << "Shortcut::get_file_names: could not parse file: " 
<< filename << std::endl;
+             continue;
+
diff -Nru inkscape-1.2.2/debian/patches/series 
inkscape-1.2.2/debian/patches/series
--- inkscape-1.2.2/debian/patches/series        2023-01-09 19:08:16.000000000 
-0600
+++ inkscape-1.2.2/debian/patches/series        2026-10-20 18:18:37.000000000 
-0500
@@ -8,3 +8,4 @@
 skip-test-librevenge.patch
 skip-test-glyph-big-endian.patch
 skip-test-use.patch
+CVE-2026-4980.patch

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to