Safeguard
Security Guides•

Is it safe to parse uploaded Excel or XML files with openpyxl or pandas?

openpyxl does not guard against billion laughs or quadratic blowup XML attacks by default. What to do with uploaded xlsx and XML files in data pipelines.

Safeguard Security Team
4 min read

Treat them with care. The openpyxl documentation says it does not guard against quadratic blowup or billion laughs XML attacks by default, and advises installing defusedxml. An xlsx file is a zip of XML, so untrusted uploads can exhaust memory or CPU. Parse them in a limited, throwaway process.

Why xlsx counts as XML

An xlsx workbook is a package of XML parts inside a zip archive. When a pipeline calls openpyxl, or pandas with an Excel engine, an XML parser reads those parts. If the parser is willing to expand entities without limits, a small file can inflate into a huge one.

The openpyxl security section is short. By default it does not guard against quadratic blowup or billion laughs attacks, and to guard against them you install defusedxml. The page does not say whether the risk applies specifically to untrusted files, but that is where the concern lives.

What about read_xml

The pandas page for read_xml supports two parsers, lxml and etree. It accepts a path or buffer, and the string can be a URL with schemes such as http, ftp, s3 and file. With lxml you can also use an XSLT stylesheet, which can be a URL or a file, with XSLT 1.0 supported.

The page does not discuss security. That gap is a reason to be deliberate, not a sign that it is safe. If the input comes from outside, do not let a user choose the URL or the stylesheet, and review the lxml and standard library XML security notes before parsing hostile documents.

A pipeline checklist for uploaded files

  1. Install defusedxml in any environment that parses spreadsheets or XML from outside.
  2. Limit the file size before parsing, and reject files that exceed it.
  3. Run the parse in a separate process or container with a memory limit and a time limit.
  4. Give that process no credentials and no network access.
  5. Fix the parser choice in code. Do not let the file or the user pick a stylesheet or a remote location.
  6. Write the cleaned result to a plain format such as Parquet or CSV and let downstream jobs read only that.
  7. Keep the parsing libraries on your update list, because parser fixes ship in package releases.

What to log

EventWhy
Rejected for sizeA spike can signal probing
Parse killed by timeout or memory limitThe limit worked, and someone should look at the source
Source of each fileYou need to know who sent a hostile one

A worked example

Imagine a finance intake job that picks up spreadsheets from a partner portal each night and loads them into a warehouse. The safe version has three stages. A first container downloads the file, checks its size and type, and refuses anything above the limit. A second container, with defusedxml installed, no credentials and a strict memory cap, reads the workbook and writes a Parquet file. A third job validates the schema of that Parquet file and loads it.

If a hostile workbook arrives, the second container fails or is killed, the alert names the source, and nothing with credentials ever touched the file. The cost is a little more plumbing. The benefit is that a parser flaw or an XML bomb becomes a failed job instead of an incident.

Where Safeguard fits

Safeguard's dependency scanning and SBOM generation show which services use openpyxl, lxml or pandas, and which versions, so you can check them against advisories. A free scan is a quick start.

Quick check

Does defusedxml fix everything?

It addresses the XML attack classes named in the openpyxl docs. You still need size limits, isolation and updates.

Is reading xlsx from a trusted internal export a problem?

The concern is mostly files from outside your control. Internal files from a controlled process carry far less risk.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.