Safeguard
Vulnerability Analysis•

CVE-2026-24009: docling-core YAML Deserialization RCE, Fix 2.48.4

CVE-2026-24009: docling-core 2.21.0 to before 2.48.4 can run code when loading untrusted YAML with old PyYAML. Upgrade to 2.48.4 and PyYAML 5.4 or later.

Safeguard Security Team
5 min read

CVE-2026-24009 is a deserialization flaw (CVSS 8.1) in docling-core, the data types library behind Docling. It affects versions from 2.21.0 before 2.48.4, but only when PyYAML is older than 5.4 and load_from_yaml receives untrusted data. Version 2.48.4 switches to a safe loader. Upgrade it, and PyYAML.

What's affected

docling-core from 2.21.0 up to but not including 2.48.4. The advisory is specific about the conditions: the app must use PyYAML before 5.4, and it must call DoclingDocument.load_from_yaml() on untrusted YAML data. If either condition is false, the described path is not reachable.

The underlying PyYAML issue is CVE-2020-14343.

How to check if you're exposed

pip show docling-core pyyaml
pip list --format=freeze | grep -i -E "docling-core|pyyaml"

Check lock files too, such as poetry.lock, uv.lock, requirements.txt and Pipfile.lock, since the installed environment may differ from what you deploy. Then search your code for load_from_yaml calls and see where the input comes from. If it comes only from files you create, the risk is low. If users upload YAML or you fetch it from the network, it matters.

What to do now

  1. Upgrade docling-core to 2.48.4 or later.
  2. Upgrade PyYAML to 5.4 or later, regardless of this issue.
  3. Do not pass untrusted YAML to load_from_yaml in versions you cannot yet upgrade. Prefer JSON for exchange with outside parties.
  4. Review other code for yaml.load or FullLoader on external data, and replace with safe_load.
  5. Scan your container images, since this library may be present as a transitive dependency of document processing tools.

Why it matters

The weakness is CWE-502, deserialization of untrusted data. Older PyYAML versions with FullLoader could build arbitrary Python objects from YAML tags, which can lead to code execution. The fix in docling-core changes the loader from FullLoader to SafeLoader, so untrusted input can only produce plain data types.

This is a good example of a vulnerability that depends on a combination of facts: a library version, a second library version and a code path. A tool that only reports versions will flag it for everyone. A tool that checks whether your code calls the vulnerable function can tell you whether it is reachable. The record does not list this CVE as known exploited.

Reading the severity score

The record gives a CVSS base score of 8.1, published 2026-01-22. In the vector, the attacker works over the network, needs no account, and the attack is high in complexity. User interaction is not needed. Impact on confidentiality is high, on integrity high and on availability high.

A base score describes the flaw in general, not your risk. Weigh it against how exposed your instance is and what it can reach. The Gold page for the CVE keeps the score, weakness and references together.

Hardening beyond the patch

Unsafe YAML loading is a pattern worth finding everywhere, not only in this library.

Search your code for yaml.load and for loaders such as FullLoader and UnsafeLoader. Replace them with safe_load for any data that does not come from a source you fully control. In PyYAML 5.4 and later, the default loaders no longer construct arbitrary Python objects, but explicit use of unsafe loaders still brings the risk back, so a code search is still worthwhile.

Next, look at how data crosses your trust boundaries. Document processing pipelines take files from users, email, shared drives and partner systems. YAML is a convenient format for configuration and exchange, but as a format for untrusted input it is risky. JSON is a safer choice when the other side is not under your control.

Check transitive dependencies. The advisory says the exposure depends on the PyYAML version in the environment, which may be pulled in by another package. Use pip show and your lock file to find the resolved version, and set a minimum version for PyYAML in your constraints file so that old copies cannot come back through another package.

Make reachability part of triage. This case has three conditions: an old PyYAML, a docling-core version in the affected range, and a call to load_from_yaml with untrusted data. Many applications will meet the first two and not the third. Knowing whether you call the function lets you rank this against other open issues, though you should still upgrade, since it is a small change.

Finally, run document processing in an isolated environment with limited privileges, without access to credentials, and with network egress limited to what the job needs. If a loader flaw is ever exploited, isolation is what limits the result.

Find it across your own code

To see which of your packages are affected, the free in-browser dependency scan at gold.safeguard.sh/scan takes a manifest and lists known vulnerabilities. Reachability analysis then helps you judge whether your code calls the vulnerable path, so you can order the work.

Try it yourself

Click through it at your own pace, or open it full screen.

Quick check

Which fix matters more, docling-core or PyYAML?

Either closes this specific path. The docling-core fix makes the loader safe by itself, and PyYAML 5.4 or later removes the underlying issue. Do both.

Is safe_load really safe?

It restricts YAML to basic types such as strings, numbers, lists and maps, which is why the advisory fix uses it.

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.