This is more like a booby-trapped badge reader on an admin desk than an open front door
CVE-2026-10275 is a buffer overflow in OpenSC's pkcs11-tool, specifically the test_kpgen_certwrite() path used during key-generation testing. The vulnerable code copies a token-returned CKA_ID into a fixed 100-byte global buffer without a length check. Public reporting pegs affected versions at OpenSC 0.26.1 and earlier, and the trigger path is tied to pkcs11-tool test flows such as --test-kpgen, --test-ec, or similar key-generation operations rather than normal passive library loading.
The vendor-style MEDIUM baseline is too generous for enterprise patch priority because the real attack path is *not* unauthenticated network exposure. The attacker needs a victim to run a niche admin/testing utility against a malicious PKCS#11 module or hostile smart card/token, which means post-delivery social engineering, lab/admin interaction, or supply-chain tampering. That's real risk, but it is workstation-local, operator-dependent, and has a tiny exposed population compared with the CVSS vector's AV:N framing.
4 steps from start to impact.
Deliver a hostile token or PKCS#11 module
pkcs11-tool talks to. The public issue describes two practical routes: a malicious PKCS#11 shared library/dll presented as a legitimate driver, or a malicious smart card/token firmware that returns oversized CKA_ID data during key-generation handling.- Attacker can get a custom PKCS#11 module or malicious token in front of the victim
- Victim environment allows loading nonstandard PKCS#11 modules or using untrusted hardware
- This is not internet-reachable by itself
- Enterprise users rarely install arbitrary PKCS#11 middleware without admin intent
- Hardware-token supply-chain attacks are possible but low-frequency
pkcs11-tool --module <path> execution, unsigned library loading, or abnormal smart-card tooling launched outside build/admin workflows.Induce an operator to run the test path
pkcs11-tool key-generation test logic, not in every OpenSC code path. The operator must invoke a test or provisioning-style workflow that reaches test_kpgen_certwrite(), typically while debugging, initializing, or validating a token.- A user or admin runs
pkcs11-toolmanually - The command path reaches key-generation test logic
- Most enterprise endpoints with OpenSC never run this path
- This is concentrated among smart-card admins, developers, or support engineers
- Routine browser auth or background middleware use does not obviously hit this function
Return an oversized object ID
CKA_ID longer than the 100-byte destination buffer. The vulnerable code trusts the returned length and performs memcpy into the fixed global buffer, producing an out-of-bounds write.- Malicious token/module controls
C_GetAttributeValueor equivalent return data - Returned
CKA_IDlength exceeds the internal buffer size
- Requires custom malicious implementation, not commodity drive-by traffic
- Exploit reliability may vary by build flags and platform hardening
Crash or corrupt the admin workstation process
pkcs11-tool process. Public reporting claims possible code execution, but the demonstrated condition is a controllable global-buffer overflow in a short-lived CLI tool, so the most defensible enterprise expectation is process crash or narrow local compromise on the operator's host.- Overflow lands in a useful memory layout
- Platform mitigations do not fully blunt exploitation
- Short-lived CLI tools are harder to weaponize than always-on services
- Modern compiler and OS mitigations reduce exploit reliability
- Blast radius is typically one admin box, not a fleet-wide service tier
pkcs11-tool crashes, core dumps, Defender/EDR memory-corruption alerts, or unusual child-process spawning from smart-card tooling.The supporting signals.
| In-the-wild status | No evidence found of active exploitation, and it is not listed in CISA KEV as of 2026-06-02. |
|---|---|
| Public exploit / repro | A public GitHub issue includes a reproduction path using a malicious PKCS#11 module and an ASan trace; I did not find a mature weaponized PoC repo. |
| EPSS | 0.00064 (~0.064%), very low expected exploitation probability. |
| KEV status | No; no KEV listing date because it is absent from the catalog. |
| CVSS vector reality check | CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:L overstates reachability. The public reporter describes the attack vector as Local / Physical, which better matches the actual chain. |
| Affected versions | Public reporting and the issue state OpenSC 0.26.1 and earlier, focused on src/tools/pkcs11-tool.c key-generation test logic. |
| Fixed version | A fix exists as commit 814f745. I could not confirm a released version carrying that fix from the available release metadata, so release-level remediation status is unclear. |
| Exposure surface | OpenSC is middleware and command-line tooling for smart cards/PKCS#11, not a listening network service. Shodan/Censys-style exposure is effectively not relevant here; the reachable population is operators who actively use pkcs11-tool. |
| Disclosure timeline | User-provided disclosure date is 2026-06-01; the public GitHub issue was opened on 2026-05-11, which suggests researcher report first, CVE publication later. |
| Researcher / reporter | The fix commit credits @HMF2021 / hippofu999 as reporter. |
noisgate verdict.
The decisive downgrade factor is attacker position: this bug requires a victim to actively use a niche smart-card admin tool against a malicious module or token, which is a far cry from true unauthenticated remote exposure. The blast radius is usually one operator workstation and one short-lived process, with no evidence of active exploitation or broad internet exposure.
Why this verdict
- Attacker position is much worse than CVSS suggests: the public report itself describes the vector as
Local / Physical, because the victim must load a malicious PKCS#11 module or interact with a hostile token. - The vulnerable code path is niche: exploitation requires the
pkcs11-toolkey-generation test flow, which sharply limits exposed hosts to smart-card admins, developers, and provisioning workflows. - Reachable population is tiny: OpenSC is not a public-facing daemon, so this is not a scan-and-own internet problem across 10,000 hosts.
- No exploitation signal: no KEV listing, no in-the-wild reporting found, and the EPSS is extremely low.
- Blast radius is local and bounded: even if exploited, the expected impact is a local admin workstation process, not a server-side fleet-wide compromise.
Why not higher?
A higher rating would require broad, low-friction reachability or strong evidence that attackers are already using it. We have neither: this is not externally exposed, requires user/admin action, and sits behind a very specific operational workflow. The memory-corruption primitive matters technically, but severity in enterprise patching is driven by *how many systems can realistically be hit*, not just what happens in a debugger.
Why not lower?
It is still a real out-of-bounds write in security tooling, with a public reproducer and a vendor fix commit. Environments that provision tokens, test PKCS#11 modules, or ingest third-party smart-card middleware do have a plausible path to host compromise on admin systems. That keeps it above IGNORE.
What to do — in priority order.
- Restrict PKCS#11 module loading — Allow only approved module paths, signed vendor middleware, and managed package sources for OpenSC tooling. This directly cuts off the easiest abuse path described in the public issue; for a LOW verdict there is no SLA, so treat it as backlog hygiene and fold it into your normal endpoint-hardening cycle.
- Fence smart-card admin workflows — Run
pkcs11-toolprovisioning and troubleshooting only on dedicated admin workstations or disposable lab VMs, not general-purpose user endpoints. That contains the blast radius to a small, monitored population; for LOW, treat this as backlog hygiene rather than emergency action. - Monitor smart-card tooling execution — Create detections for
pkcs11-toolwith--module, key-generation test flags, unexpected library paths, and crash signatures. This will not prevent the bug, but it gives you visibility into the exact high-friction workflow required for exploitation; again, LOW means no formal SLA. - Prefer packaged or backported fixes — Where OpenSC is centrally managed, consume the vendor/distro package once a release or backport carrying the fix is available, or backport commit
814f745in controlled builds if you own the package pipeline. Because this is LOW, handle it through regular maintenance rather than disruption-driven change windows.
- A perimeter firewall does not help because
pkcs11-toolis not being exploited as a listening network service. - WAF rules are irrelevant; there is no HTTP transaction or web parser in the attack path.
- MFA does not meaningfully reduce risk here because the vulnerability lives in the local smart-card tooling used during token interaction.
Crowdsourced verification payload.
Run this on the target host or gold image where OpenSC is installed. Invoke it with python3 check_opensc_cve_2026_10275.py as a standard user; no admin rights are needed unless your package manager hides version data. The script tries pkcs11-tool --version first and falls back to common package managers, then prints VULNERABLE, PATCHED, or UNKNOWN.
#!/usr/bin/env python3
# check_opensc_cve_2026_10275.py
# Determine likely exposure to CVE-2026-10275 based on installed OpenSC version.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
import os
import re
import sys
import shutil
import subprocess
from typing import Optional, Tuple
def run(cmd):
try:
p = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=10)
return p.returncode, p.stdout.strip()
except Exception:
return 999, ""
def parse_version(text: str) -> Optional[Tuple[int, ...]]:
# Match versions like 0.26.1 or 0.27.0
m = re.search(r'(\d+)\.(\d+)\.(\d+)', text)
if not m:
return None
return tuple(int(x) for x in m.groups())
def version_to_str(v):
return '.'.join(str(x) for x in v)
def get_version_from_pkcs11_tool() -> Optional[Tuple[int, ...]]:
exe = shutil.which('pkcs11-tool')
if not exe:
return None
for args in ([exe, '--version'], [exe, '-V']):
rc, out = run(args)
v = parse_version(out)
if v:
return v
return None
def get_version_from_linux_pkg() -> Optional[Tuple[int, ...]]:
checks = [
['dpkg-query', '-W', '-f=${Version}', 'opensc'],
['rpm', '-q', 'opensc'],
['dnf', 'info', 'opensc'],
['apt-cache', 'policy', 'opensc'],
['pacman', '-Qi', 'opensc'],
['zypper', 'info', 'opensc'],
]
for cmd in checks:
if not shutil.which(cmd[0]):
continue
rc, out = run(cmd)
v = parse_version(out)
if v:
return v
return None
def get_version_from_macos_pkg() -> Optional[Tuple[int, ...]]:
checks = [
['brew', 'list', '--versions', 'opensc'],
['port', 'installed', 'opensc'],
['pkgutil', '--pkgs'],
]
for cmd in checks:
if not shutil.which(cmd[0]):
continue
rc, out = run(cmd)
if cmd[0] == 'pkgutil' and 'org.opensc' not in out.lower():
continue
v = parse_version(out)
if v:
return v
return None
def get_version_from_windows() -> Optional[Tuple[int, ...]]:
# Try pkcs11-tool first via PATH
v = get_version_from_pkcs11_tool()
if v:
return v
# Common install paths
candidates = [
r'C:\Program Files\OpenSC Project\OpenSC\tools\pkcs11-tool.exe',
r'C:\Program Files (x86)\OpenSC Project\OpenSC\tools\pkcs11-tool.exe',
]
for exe in candidates:
if os.path.exists(exe):
for args in ([exe, '--version'], [exe, '-V']):
rc, out = run(args)
v = parse_version(out)
if v:
return v
return None
def get_installed_version() -> Optional[Tuple[int, ...]]:
v = get_version_from_pkcs11_tool()
if v:
return v
if sys.platform.startswith('linux'):
return get_version_from_linux_pkg()
if sys.platform == 'darwin':
return get_version_from_macos_pkg()
if os.name == 'nt':
return get_version_from_windows()
return None
def main():
v = get_installed_version()
if not v:
print('UNKNOWN - OpenSC version not detected')
sys.exit(2)
# Based on currently available public reporting, 0.26.1 and earlier are affected.
# If your distro backports the fix without changing the version, manually verify changelog/patch metadata.
affected_max = (0, 26, 1)
fixed_min = (0, 27, 0)
if v <= affected_max:
print(f'VULNERABLE - detected OpenSC {version_to_str(v)} (publicly reported affected range is <= 0.26.1)')
sys.exit(1)
elif v >= fixed_min:
print(f'PATCHED - detected OpenSC {version_to_str(v)} (outside publicly reported affected range)')
sys.exit(0)
else:
print(f'UNKNOWN - detected OpenSC {version_to_str(v)}; unable to map confidently')
sys.exit(2)
if __name__ == '__main__':
main()
If you remember one thing.
pkcs11-tool is actually present and where smart-card provisioning or PKCS#11 testing happens; fence those workflows to managed admin hosts and block unapproved PKCS#11 modules as backlog hygiene. Because this is a LOW reassessment, there is no noisgate mitigation SLA and noisgate remediation SLA is also not formalized for LOW severity: treat it as normal maintenance backlog, patching or backporting the fix in the next routine cycle after validating package availability.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.