VYPR
High severityGHSA Advisory· Published Aug 26, 2025· Updated Sep 29, 2025

xml2rfc has an arbitrary file read vulnerability

CVE-2025-11058

Description

Impact

When generating PDF files, this vulnerability allows an attacker to read arbitrary files from the filesystem by injecting malicious link element into the XML.

Workarounds

Test untrusted input with link elements with rel="attachment" before processing.

Credits

This vulnerability was reported by Mohamed Ouad from Doyensec.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
xml2rfcPyPI
< 3.30.13.30.1

Affected products

1

Patches

1
f2b245bc0aee

Merge commit from fork

https://github.com/ietf-tools/xml2rfcKesara RathnayakeAug 25, 2025via ghsa
3 files changed · +46 1
  • test.py+33 0 modified
    @@ -14,6 +14,7 @@
     from xml2rfc.writers.base import default_options, BaseV3Writer, RfcWriterError
     from xml2rfc.writers import DatatrackerToBibConverter
     from xml2rfc.writers.text import MAX_WIDTH
    +from xml2rfc.utils import strip_link_attachments
     from xml2rfc.util.file import can_access, FileAccessError
     
     try:
    @@ -1069,5 +1070,37 @@ def test_allowed_access_template(self):
                                        access_templates=True))
     
     
    +class StripLinkAttachmentsTest(unittest.TestCase):
    +    def setUp(self):
    +        self.options = copy.deepcopy(default_options)
    +
    +    def test_strips_attachement(self):
    +        self.options.allow_local_file_access = False
    +        xml_tree = lxml.etree.fromstring("""
    +<rfc>
    +    <link rel="item" href="urn:issn:0000-0000" />
    +    <link rel="attachment" href="/etc/passwd" />
    +    <link rel="describedBy" href="doi:00.00000/rfc0000" />
    +    <link rel="prev" href="https://www.ietf.org/archive/id/draft-ietf-empire-death-star-00.txt" />
    +    <link rel="attachment" href="/home/vader/ds-1/schematics" />
    +    <link rel="alternate" href="https://www.ietf.org/ds-1" />
    +</rfc>""")
    +
    +        strip_link_attachments(xml_tree)
    +
    +        # keeps non rel="attachment" elements
    +        for rel in ["item", "describedBy", "prev", "alternate"]:
    +            links = xml_tree.xpath(f'//link[@rel="{rel}"]')
    +            self.assertEqual(len(links), 1)
    +
    +        # strip rel="attachment"
    +        attachments = xml_tree.xpath('//link[@rel="attachment"]')
    +        self.assertEqual(len(attachments), 0)
    +        xml_str = lxml.etree.tostring(xml_tree).decode()
    +        self.assertNotIn("attachment", xml_str)
    +        self.assertNotIn("/etc/passwd", xml_str)
    +        self.assertNotIn("/home/vader/ds-1/schematics", xml_str)
    +
    +
     if __name__ == '__main__':
         unittest.main()
    
  • xml2rfc/utils.py+9 0 modified
    @@ -362,6 +362,15 @@ def find_duplicate_attr_values(attr, tree):
                     seen.add(id)
         return dups
     
    +def strip_link_attachments(tree):
    +    """
    +    Find link tags with rel="attachment".
    +    """
    +    for attachment in tree.xpath('//link[@rel="attachment"]'):
    +        xml2rfc.log.warn(f"Removed {attachment}. link relationships type attachment is not allowed.")
    +        attachment.getparent().remove(attachment)
    +
    +
     # ----------------------------------------------------------------------
     # Unicode operations
     
    
  • xml2rfc/writers/base.py+4 1 modified
    @@ -28,7 +28,7 @@
     from xml2rfc.util.file import can_access, FileAccessError
     from xml2rfc.util.name import short_author_ascii_name_parts, full_author_name_expansion, short_author_name_parts
     from xml2rfc.util.unicode import is_svg
    -from xml2rfc.utils import namespaces, find_duplicate_ids, slugify
    +from xml2rfc.utils import namespaces, find_duplicate_ids, slugify, strip_link_attachments
     
     
     SUBSERIES = {
    @@ -2117,6 +2117,9 @@ def validate(self, when='', warn=False):
             # a duplicate xsd:ID attribute.  So we check all attributes with
             # content specified as xsd:ID first, and give better messages:
     
    +        # Strip link attachments
    +        strip_link_attachments(self.tree)
    +
             # Get the attributes we need to check
             if when and not when.startswith(' '):
                 when = ' '+when
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

3

News mentions

0

No linked articles in our index yet.