Apr 11, 2026·7 min read·1 visit
A missing bounds check in Step CA's TPM attestation logic allows an attacker to crash the application via an empty Extended Key Usage (EKU) ASN.1 sequence.
Step CA versions prior to 0.30.0-rc3 contain a vulnerability (CWE-129) where processing a malformed TPM Attestation Key certificate results in a Go runtime panic. This flaw causes a Denial of Service condition when the device-attest-01 ACME challenge is enabled and triggered by an unauthenticated attacker.
Step CA functions as an online certificate authority providing secure, automated certificate management protocols including ACME. The software exposes specific endpoints to handle the device-attest-01 ACME challenge, which relies on TPM device attestation. This challenge verification process requires parsing and evaluating X.509 Attestation Key (AK) certificates provided by clients.
A flaw exists in the application's implementation of the ASN.1 decoding and validation logic for these certificates. Specifically, the vulnerability represents an Improper Validation of Array Index (CWE-129) within the code responsible for processing the Extended Key Usage (EKU) extension. The validation routine assumes that a successful ASN.1 parse operation always populates the resulting data structures.
Triggering this vulnerability results in an unrecoverable Go runtime panic. When the panic occurs, the active Step CA process terminates immediately, severing all active client connections. This termination causes a Denial of Service (DoS) condition for the entire certificate authority service until the process is manually or automatically restarted.
The attack surface is constrained by the required CA configuration. Deployments are only vulnerable if they explicitly enable the device-attest-01 ACME challenge. The attacker requires network access to the ACME endpoint but does not require prior authentication to submit the malformed payload.
The vulnerability originates within the validateAKCertificateExtendedKeyUsage function located in the acme/challenge.go file. This function verifies that the submitted Attestation Key (AK) certificate includes the mandatory TCG-defined Extended Key Usage OID tcg-kp-AIKCertificate (2.23.133.8.3). The routine relies on the standard Go encoding/asn1 package to decode the raw extension bytes.
The underlying mechanism decodes the DER-encoded X.509 extension value into a Go slice of Object Identifiers named ekus. According to ASN.1 syntax rules, a sequence can be structurally valid but contain zero elements. If an attacker provides a DER-encoded empty sequence (represented by the bytes 0x30 0x00), the asn1.Unmarshal function processes it without returning an error.
The application code contains a logical oversight following the unmarshaling step. It immediately attempts to access ekus[0] to perform an OID comparison against the expected TCG constant. The code lacks an intermediate step to verify that the length of the ekus slice is greater than zero.
In the Go runtime environment, accessing an index that exceeds the bounds of a slice triggers an immediate panic. This hardware-level exception bypasses standard Go error handling routines (unless explicitly recovered using a defer block, which is absent here). Consequently, the panic propagates up the call stack and terminates the main execution thread.
The original implementation in acme/challenge.go demonstrates the implicit assumption regarding slice length. The code performs the unmarshaling operation and the index evaluation within the same conditional statement. This structure guarantees a panic if the unmarshaling succeeds but produces an empty slice.
// Vulnerable Code (acme/challenge.go)
for _, ext := range c.Extensions {
if ext.Id.Equal(oidExtensionExtendedKeyUsage) {
if _, err := asn1.Unmarshal(ext.Value, &ekus); err != nil || !ekus[0].Equal(oidTCGKpAIKCertificate) {
return errors.New("AK certificate is missing Extended Key Usage value tcg-kp-AIKCertificate (2.23.133.8.3)")
}
valid = true
}
}The remediation applied in commit ffd31ac0a87e03b0224cb8363094bfe602242888 introduces an explicit boundary check. The developers added len(ekus) == 0 to the conditional evaluation block. Go evaluates logical OR operators (||) sequentially and stops at the first true condition, which prevents execution from reaching the out-of-bounds array access.
// Patched Code (acme/challenge.go)
for _, ext := range c.Extensions {
if ext.Id.Equal(oidExtensionExtendedKeyUsage) {
if _, err := asn1.Unmarshal(ext.Value, &ekus); err != nil || len(ekus) == 0 || !ekus[0].Equal(oidTCGKpAIKCertificate) {
return errors.New("AK certificate is missing Extended Key Usage value tcg-kp-AIKCertificate (2.23.133.8.3)")
}
valid = true
}
}This fix completely addresses the root cause for this specific code path. By relying on Go's short-circuit evaluation logic, the application correctly handles structurally valid but semantically empty ASN.1 sequences. The patch avoids introducing unnecessary error recovery blocks, maintaining the expected linear validation flow.
Reviewing the broader ACME package logic indicates no remaining variant vectors in this specific validation phase. The addition of explicit bounds checking aligns with standard security practices for managing runtime dynamic arrays constructed from untrusted X.509 extension data.
Exploitation necessitates a specific target environment configuration. The Step CA instance must be actively configured to serve the device-attest-01 ACME challenge type. Without this configuration, the routing logic drops the attacker's requests before reaching the vulnerable parsing function.
The attack sequence begins with the adversary initiating a standard ACME transaction against the target endpoint. During the TPM attestation phase of the transaction, the protocol requires the client to upload an Attestation Key (AK) X.509 certificate. The attacker provides a custom-crafted certificate instead of a legitimate TPM-generated identity.
The malicious certificate requires a single modification to its standard structure. The attacker constructs the Extended Key Usage (EKU) extension header but assigns the DER byte sequence 0x30 0x00 as the extension value. This byte sequence accurately represents an ASN.1 Sequence type (0x30) with a length of zero bytes (0x00).
Upon submission, the Step CA server ingests the payload, validates the basic X.509 syntax, and routes the extension payload to the validateAKCertificateExtendedKeyUsage function. The server immediately encounters the out-of-bounds error and halts execution. Public research confirms no active exploitation of this method in the wild.
The successful exploitation of CVE-2026-40097 imposes a Denial of Service (DoS) state upon the Step CA infrastructure. The termination of the primary process halts all pending and future certificate lifecycle operations. Clients requesting new certificates, renewals, or revocation status checks experience connection timeouts or reset errors.
The assigned CVSS v3.1 vector is CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L, yielding a base score of 3.7 (Low). The Attack Complexity (AC:H) reflects the stringent prerequisite that the device-attest-01 configuration must be actively deployed on the target environment. Confidentiality and Integrity metrics remain at None (C:N, I:N) as the memory violation results strictly in termination rather than arbitrary execution or data disclosure.
The Availability impact metric evaluates to Low (A:L). While the CA process terminates completely, modern deployment architectures typically utilize process managers like systemd or orchestrators like Kubernetes. These systems automatically restart the failed service, limiting the outage window to the time required for process initialization.
Exploitability intelligence data supports a low prioritization for immediate emergency response in non-TPM environments. The Exploit Prediction Scoring System (EPSS) designates a score of 0.0003, placing it in the 8.67th percentile of exploitation probability. The vulnerability is absent from the CISA Known Exploited Vulnerabilities (KEV) catalog.
The definitive remediation requires upgrading the smallstep/certificates package. System administrators must deploy version 0.30.0 or later across all impacted infrastructure. The 0.30.0 release incorporates the upstream fix authored in commit ffd31ac0a87e03b0224cb8363094bfe602242888, which enforces explicit boundary checking during extension parsing.
Organizations incapable of immediate patching can apply an effective configuration workaround. Administrators can disable the device-attest-01 ACME challenge type within the Step CA configuration files. Removing this challenge type completely eliminates the vulnerable code path from the attack surface without requiring binary modification.
Security monitoring teams should implement specific log analysis rules to detect attempted exploitation. The rules should alert on unhandled Go runtime panics manifesting in application logs, specifically isolating stack traces referencing acme/challenge.go and the validateAKCertificateExtendedKeyUsage routine. Continuous process crash-loops often indicate an ongoing Denial of Service attempt.
Post-remediation validation entails executing a synthetic test against the updated ACME endpoint. Security engineering teams can utilize the internal unit test framework provided in the patch diff to generate an X.509 certificate containing the 0x30 0x00 DER sequence. Submitting this artifact to the patched server must return a standard HTTP error response rather than causing a process fault.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
smallstep/certificates smallstep | >= 0.24.0, < 0.30.0-rc3 | 0.30.0-rc3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-129 |
| Attack Vector | Network |
| CVSS Score | 3.7 |
| EPSS Score | 0.0003 |
| Impact | Denial of Service (DoS) |
| Exploit Status | None |
| KEV Status | Not Listed |
Improper Validation of Array Index