You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Bug: exports.vulns(cve_id=...) rejects the PHP2Shell CVEs, blocking vulnerability exports filtered by CVE #1050
Vulnerability exports can't be filtered by the PHP2Shell CVEs, CVE-2026-109618 and CVE-2026-109619, through pyTenable. tio.exports.vulns(cve_id=[...]) raises a pydantic ValidationError before any request is sent:
cve_id.0
String should match pattern '^CVE-\d{4}-\d{1,5}$' [type=string_pattern_mismatch, input_value='CVE-2026-109618', input_type=str]
The CVEId pattern in tenable/io/exports/models.py allows only one to five digits after the year. CVE sequence numbers have had four or more digits, with no upper limit, since the 2014 CVE ID syntax change, and six- and seven-digit IDs are now common. As a result:
Valid IDs are rejected: every CVE with a sequence number of six or more digits, including both PHP2Shell CVEs and Node2Shell (CVE-2026-111497).
Invalid IDs are accepted: IDs with one to three digits, such as CVE-2024-123, pass validation, and the API then rejects them with 400 BAD_REQUEST_INVALID_VALUE.
exports.vulns() has no way around the validation, so pyTenable users can't export PHP2Shell findings by CVE.
To Reproduce
Runs offline; nothing is sent to the API:
fromtenable.ioimportTenableIOtio=TenableIO(url='https://cloud.example.invalid', access_key='a'*64, secret_key='b'*64)
tio.exports.vulns(cve_id=['CVE-2026-109618', 'CVE-2026-109619'], iterator=None)
# pydantic_core.ValidationError: String should match pattern '^CVE-\d{4}-\d{1,5}$'
Expected behavior
The export request is sent with {"filters": {"cve_id": ["CVE-2026-109618", "CVE-2026-109619"], ...}}. The API accepts these IDs: a direct POST /vulns/export with them finishes and echoes the filter in the export status.
IDs that aren't valid CVE IDs, such as CVE-2024-123, should still be rejected locally.
Workaround
Send the export request directly. This skips pyTenable's validation:
Then poll vulns/export/{export_uuid}/status and download each chunk listed in chunks_available.
System Information:
OS: any
Architecture: any
Version: pyTenable 26.10.1 (and every earlier release with this pattern)
Additional context
The API's own validation accepts sequence numbers of four to seven digits, and rejects shorter or longer ones with 400 BAD_REQUEST_INVALID_VALUE. It also accepts lowercase IDs but matches no findings with them, so pyTenable's existing uppercase requirement is useful and should stay.
Activity