Title: How the EU created Electronic Invoices without considering Security

"Complexity is the worst enemy of security"

(Bruce Schneier, 1999)

YAGNI

You aren't gonna need it

DTSTTCPW

Do The Simplest Thing That Can Possibly Work

Not everyone agrees with these Radical Ideas

XML Icon XML Icon

eInvoicing Directive (2014/55/EU)

In principle, not a bad idea

  • Machine-readable invoices
  • Enable automation
  • Reduce tax fraud

We have standards, syntaxes, meta-standards, sub-standards, profiles, usage specifications, ... for electronic invoices

  • EN16931 is a set of standards developed by CEN/TC 434 for the EU
  • EN16931 has two mandatory syntaxes based on XML: CCI and UBL (+ optional syntax EDIFACT)
  • EN16931 can be restricted with a CIUS (Core Invoice Usage Specification) or have extensions
  • XRechnung is a CIUS and an extension
  • ZUGFeRD is a standard for electronic invoices, it has a profile "XRechnung", which makes it compatible with XRechnung
  • Factur-X is more or less the same as ZUGFeRD, just the french version

This is more complex than it should be

Unhealthy Ecosystem

Getting the standard EN 16931

https://ec.europa.eu/digital-building-blocks/sites/spaces/DIGITAL/pages/467108661/European+Standard+and+Specifications Link -> does not work https://standards.cencenelec.eu/dyn/www/f?p=CEN:110:0::::FSP_PROJECT,FSP_ORG_ID:71870,1883209&cs=18AD38D91FB33B5CBD300B5C8FC9AB681 german: https://www.dinmedia.de/en/standard/din-en-16931-1/327729047 swiss: https://www.dinmedia.de/en/standard/sn-en-16931-1-a1-ac/334318948 spanish: https://www.dinmedia.de/de/norm/une-en-16931-1-a1/331859894

EN 16931

  • Parts 1+2 are free
  • You cannot just download them, you have to buy them in a shop of one of the national standardization organizations
  • Each country has their own version of the standard, in its own language and translations of it, which are sometimes free

Other fun facts about electronic invoices

Let's say you want to create an invoice for a product with a price of € 99.99, sold in Germany (VAT 19%)

€ 99.99 is not allowed due to rounding rules

€ 84.02 ⋅ 1.19 ≈ € 99.98

€ 84.03 ⋅ 1.19 ≈ € 100.00

Raphael Michel at MRMCD25

FIXME add screenshot (min 25)

XML and Security

Billion Laughs

<!DOCTYPE billion [
<!ENTITY a "billion">
<!ENTITY b "&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;">
<!ENTITY c "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
<!ENTITY d "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
<!ENTITY e "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
<!ENTITY f "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
<!ENTITY g "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
<!ENTITY h "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
<!ENTITY i "&h;&h;&h;&h;&h;&h;&h;&h;&h;&h;&h;&h;&h;&h;&h;&h;">
<!ENTITY j "&i;&i;&i;&i;&i;&i;&i;&i;&i;&i;&i;&i;&i;&i;&i;&i;">
]>
<x>&j;</x>

Billion Laughs and Friends

  • Plenty of variations
  • New issues are discovered regularly (currently unfixed issue in Expat)
  • Prevented by various heuristics, not standardized
  • "Only" Denial of Service

XXE

XML external entity

XXE file exfiltration

<!DOCTYPE xxe [
<!ENTITY e SYSTEM "file:///etc/passwd">
]>
<x>&e;</x>

Blind XXE

Allows file exfiltration without seeing the output, but practical exploitability is rare

XXE is not a solved problem

Some implementations have secure defaults

Python (CVE-2013-1665), .NET (CVE-2016-3255), libxml2 (CVE-2013-0339), Expat (no URL handlers by default)

Others have chosen to stay Insecure by Default

https://docs.oracle.com/en/java/javase/21/docs/api/java.xml/javax/xml/XMLConstants.html#FEATURE_SECURE_PROCESSING

XML

  • Extremely complex
  • Has inherent security flaws
  • Preventing XXE and other XML security issues is non-trivial

Electronic Invoices

  • Exchanged between many different entities
  • Processed by many different pieces of software

Validating correctness

To allow (FIXME: for?) checking the correctness of electronic invoices, the EU provides validation artefacts written in ISO Schematron 2016, compiled to XSLT 2.0

https://github.com/ConnectingEurope/eInvoicing-EN16931

XSLT

XSLT 1.0: Widely supported

XSLT 2.0/3.0: Not widely supported (fake standard)

See also: https://github.com/w3ctag/obsoletion/issues/10

XSLT 3.0

One major implementation: Saxon

Written in Java, also usable from C, PHP, Python

How does Saxon deal with XXE?

Insecure by Default

EU electronic invoices are

  • a lot more complex than they should be
  • based on an inherently insecure document format (XML)
  • centered around ecosystems that are, by default, vulnerable to XXE

Not great...

screenshots...
It does not appear security was taken into account when developing these standards

Suggestions

Immediately: test implementations for XXE vulnerabilities (I am providing test cases, this should have been done by the standardization bodies)

Reduce unnecessary complexity

(e.g., there is absolutely no justification for two mandatory syntaxes)

Move away from XML to simpler, safer data formats

(JSON, while not perfect, is certainly better than XML)

Avoid fake standards like XSLT 2.0 and above

(make sure that standards are widely implemented before using them)

Implement good IT security practices: security considerations in standards, security contacts (security.txt), guidance and test cases for secure usage