chore(deps): update security updates [security] - #146
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough
ChangesDependency Updates
Estimated code review effort: 1 (Trivial) | ~2 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
NumaryBot
left a comment
There was a problem hiding this comment.
🛑 Changes requested — automated review
The dependency bump is incomplete because the corresponding go.sum entry was not committed, which will make the existing tidy/dirty CI workflow fail.
| github.com/opencontainers/go-digest v1.0.0 // indirect | ||
| github.com/opencontainers/image-spec v1.1.1 // indirect | ||
| github.com/opencontainers/runc v1.2.8 // indirect | ||
| github.com/opencontainers/runc v1.3.6 // indirect |
There was a problem hiding this comment.
🔴 [blocker] Commit the updated runc checksum
With this version bump, go.sum still only contains the github.com/opencontainers/runc v1.2.8 entries and has no checksum for v1.3.6. The CI Dirty job runs just pre-commit, which includes go mod tidy, and that will add the missing v1.3.6 checksum before the subsequent git status check, causing the repository to be reported dirty; environments using readonly module mode can also fail on the missing sum.
flemzord
left a comment
There was a problem hiding this comment.
The target version is the correct upstream security fix and is compatible with this repository. However, the dependency update is incomplete: go.sum still contains only the v1.2.8 checksums, and the artifact, Dirty, and Test checks are failing. This is already captured by the existing inline comment and is not duplicated here. Please repair the invalid go-libs/v5 pseudo-version or rebase, then retrigger Renovate so it can regenerate and commit the v1.3.6 sums.
859b332 to
7ef5747
Compare
✅ Approve — automated reviewThe dependency updates are consistently reflected in go.mod and go.sum, including the previously missing runc checksums. No actionable regressions were identified. No findings. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@go.mod`:
- Line 166: Update the github.com/formancehq/go-libs/v5 dependency pin in go.mod
to a valid resolvable version, replacing the broken pseudo-version while
preserving the module’s existing dependency configuration.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
7ef5747 to
7b82b0e
Compare
7b82b0e to
3eac728
Compare
3eac728 to
ad746c4
Compare
ℹ Artifact update noticeFile name: go.modIn order to perform the update(s) described in the table above, Renovate ran the
Details:
|
There was a problem hiding this comment.
♻️ Duplicate comments (1)
go.mod (1)
164-164:⚠️ Potential issue | 🟠 MajorCommit the checksum for
github.com/opencontainers/runc v1.3.6.At Line 164,
go.modselectsv1.3.6, but the supplied dependency state still lacks itsgo.sumentry.just pre-commitcan modify the checkout duringgo mod tidy, and readonly module mode can fail earlier. Regenerate and commitgo.sum. Then verify thatgo mod tidyis a no-op andgo mod verifypasses.#!/usr/bin/env bash set -euo pipefail git grep -n '^github.com/opencontainers/runc v1.3.6 ' -- go.sum || true go mod tidy git diff --exit-code -- go.mod go.sum go mod verify🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@go.mod` at line 164, Regenerate and commit the go.sum checksum entry for github.com/opencontainers/runc v1.3.6 selected in go.mod. Run go mod tidy, confirm it produces no changes to go.mod or go.sum, and run go mod verify successfully.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@go.mod`:
- Line 164: Regenerate and commit the go.sum checksum entry for
github.com/opencontainers/runc v1.3.6 selected in go.mod. Run go mod tidy,
confirm it produces no changes to go.mod or go.sum, and run go mod verify
successfully.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: d5986ba4-a4d7-4dc1-b558-35f7fb6c9052
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (1)
go.mod
ad746c4 to
c5834fa
Compare
This PR contains the following updates:
v0.134.0->v0.144.0v5.2.5->v5.3.0v1.18.4->v1.18.7v1.2.8->v1.3.6v1.43.0->v1.44.0v0.35.0->v0.40.0v0.55.0->v0.56.0v0.37.0->v0.39.0v1.80.0->v1.82.1GitHub Vulnerability Alerts
GHSA-r277-6w6q-xmqw
Summary
ValidationHandler.Load()ingetkin/kin-openapisilently replaces a nilAuthenticationFuncwithNoopAuthenticationFunc, which always returnsnilwithout performing any credential check. Because this substitution happens unconditionally when the caller omits the field, every OpenAPIsecurityrequirement declared in the spec is silently satisfied for unauthenticated requests. An unauthenticated remote attacker can reach handlers for routes whose OpenAPI operation requires an API key, OAuth token, or any other security scheme if the application relies onValidationHandleras its enforcement middleware.Details
ValidationHandleris an HTTP middleware exported byopenapi3filterthat validates incoming requests and responses against a loaded OpenAPI specification. ItsLoad()method initialises default fields before the handler begins serving:NoopAuthenticationFuncis defined as:It always returns
nil, meaning every security scheme check it handles is automatically approved.When a request arrives,
ServeHTTP→before→validateRequestassembles aRequestValidationInputwith the currentAuthenticationFunc(now the no-op) injected intoOptions:Inside
ValidateRequest, each security requirement callsoptions.AuthenticationFunc:Because
fis the no-op (notnil), theErrAuthenticationServiceMissingguard is never triggered andf(...)returnsnil, clearing the security requirement. Control then proceeds to the protected handler (validation_handler.go:61-62).The critical contradiction is that callers who use
ValidateRequestdirectly with a nilAuthenticationFuncget fail-closed behavior (ErrAuthenticationServiceMissing), while callers who use the higher-levelValidationHandlerwith a nilAuthenticationFuncget fail-open behavior. Since omittingAuthenticationFuncis the natural default, the majority of real-world integrations are vulnerable.Affected source file and line:
openapi3filter/validation_handler.go:47–49(commit30e2923, tagv0.143.0).PoC
Environment
Step 1 — Build the Docker image
From the repository root (parent of
vuln-001/):The
Dockerfilecopies the localkin-openapisource into/kin-openapi/inside the image and builds a Go binary (/poc-binary) frommain.go. Thego.modinside the image uses areplacedirective pointing to/kin-openapi, so no network access to the Go module proxy is required.Step 2 — Run the container
Step 3 (alternative) — Use the Python helper
What the PoC does
main.gocreates a temporary OpenAPI 3.0 spec that declaresGET /secretas protected by anapiKeysecurity scheme:It then constructs a
ValidationHandlerwithout settingAuthenticationFunc, callsLoad(), and sends a request with noX-Api-Keyheader:Expected (vulnerable) output
The contrast block confirms fail-closed behavior when
ValidateRequestis called directly. The exploit block confirms fail-open behavior throughValidationHandler. Status 200 andSECRET_DATAare returned without any credential.Remediation patch
After this change, a nil
AuthenticationFuncpropagates intoValidateRequest, which returnsErrAuthenticationServiceMissingand rejects the request. Callers who genuinely want to skip authentication can still opt in explicitly:h.AuthenticationFunc = openapi3filter.NoopAuthenticationFunc.Impact
This is an authentication bypass vulnerability (CWE-287). Any application that:
openapi3filter.ValidationHandleras its HTTP middleware, andsecurityrequirements in its OpenAPI specification, andAuthenticationFunc,is fully exposed. An unauthenticated remote attacker can send requests to any protected endpoint without supplying credentials; the middleware accepts the request and forwards it to the underlying handler as if authentication had succeeded.
Affected parties include all Go services that adopt
ValidationHandleras a drop-in validation layer and rely on OpenAPIsecuritydeclarations for access control without adding a separate authentication layer upstream (e.g., an API gateway or reverse proxy). Because the insecure behavior is the default, developers following the "getting started" path are affected without any additional mistake.The confidentiality and integrity of data behind secured endpoints are both at high risk. Availability is not directly affected by this vulnerability.
Reproduction artifacts
Dockerfilepoc.pyCVE-2026-73502
github.com/getkin/kin-openapi<= 0.143.0(introduced inv0.2.0, PR #90, 2019-05-07; reproduced onHEAD30e2923)Summary
openapi3filter.ValidateRequestcontains a NULL-pointer-dereference denial of service: any unauthenticated client can crash the request-validation path with a single HTTP request. When an operation declares acontentparameter (as opposed to aschemaparameter) whose media type object has noschema, request validation dereferences that missing schema and panics. The document is legal under the OpenAPI Specification — kin-openapi's owndoc.Validate()accepts it — and the defect affects both OpenAPI 3.0.x and 3.1.x. Depending on how the library is wired into the server (see Impact), this ranges from a per-request abort with unbounded panic-log growth to a full remote process crash.Details
The decoder used for
contentparameters when no customParamDecoderis configured (the library default),defaultContentParameterDecoder, dereferences the media-type schema without a nil check.openapi3filter/req_resp_decoder.go, around line 197:The function guards
param.Content == nil,len(content) != 1, andmt == nil, but nevermt.Schema == nil.Why a schema-less content parameter is legal (so the sink is reachable —
doc.Validate()returns no error), in both 3.0.x and 3.1.x:openapi3/parameter.go—Parameter.Validateonly enforces exactly one ofschemaXORcontent; a parameter withcontent(and noschema) satisfies it.openapi3/media_type.go—MediaType.Validatevalidates the schema only when it is non-nil, so an absent schema is not a validation error.Call path to the panic:
Authentication note:
ValidateRequestvalidates security before parameters, but the panic is reachable without credentials whenever the target operation declares no security requirement, or when noAuthenticationFuncis configured (it is opt-in). A single unauthenticated operation anywhere in the served spec is sufficient. If an operation does declare security and a rejectingAuthenticationFuncis wired, that request is rejected before decoding.PoC
Reproduced end-to-end against
HEAD(30e2923) with a realnet/httpserver and a stockhttp.Client.1. Minimal OpenAPI 3.0.3 document (legal —
doc.Validate()passes). Thecfgquery parameter usescontentwith anapplication/jsonmedia type that has noschema:2. A complete, self-contained program. Drop this into a directory inside a checkout of
github.com/getkin/kin-openapiand run it withgo run .. It loads the document above, assertsdoc.Validate()accepts it (proving reachability), serves it behind request validation exactly as the recommended middleware does, and sends one unauthenticatedGET /c?cfg=1:3. Observed result — the request goroutine panics inside validation, and the client's
http.Getreturns an EOF:Swapping the media type for one that carries a schema (
application/json: {schema: {type: object}}) makes the same request return a clean400instead of panicking, confirming the missing schema is the cause.Impact
This is an unauthenticated remote denial of service (CWE-476) against any service that validates incoming requests with
openapi3filterand serves a spec containing at least onecontentparameter whose media type lacks aschema.The precise consequence depends on which goroutine runs the panic and whether a
recover()covers it:net/http?net/http(incl.openapi3filter.ValidationHandler)http: panic servinglog growth.ValidateRequeston an app-spawned goroutine (fan-out,errgroup, async pre-check)recover().net/httphost (fasthttp adaptor, gRPC-gateway shim, CLI, offline/batch spec validator)This is why the suggested CVSS uses
A:L(Base 5.3): under the recommended synchronousnet/httpwiring the panic is recovered per-connection. Reviewers may reasonably raise it toA:H(Base 7.5) for the spawned-goroutine and non-net/httpintegrations, where a single request kills the process.Remediation (suggested)
Add a
mt.Schema == nilguard mirroring the existingmt == nilguard, so a schema-less content parameter yields a clean validation error instead of a panic:The
unmarshalclosure immediately below already tolerates a nil schema (it checksparamSchema != nil), so returning early on nilmt.Schemais consistent with surrounding intent.Workarounds for consumers, pending a patch:
contentparameter in served specs declares aschema, or reject such specs at load time.ParamDecoderthat guardsmt.Schema == nil.recover()— especially if validation runs off the request goroutine or on a non-net/httphost.kin-openapi: ValidationHandler.Load() Fail-Open Authentication Bypass via NoopAuthenticationFunc Default
CVE-2026-73501 / GHSA-r277-6w6q-xmqw
More information
Details
Summary
ValidationHandler.Load()ingetkin/kin-openapisilently replaces a nilAuthenticationFuncwithNoopAuthenticationFunc, which always returnsnilwithout performing any credential check. Because this substitution happens unconditionally when the caller omits the field, every OpenAPIsecurityrequirement declared in the spec is silently satisfied for unauthenticated requests. An unauthenticated remote attacker can reach handlers for routes whose OpenAPI operation requires an API key, OAuth token, or any other security scheme if the application relies onValidationHandleras its enforcement middleware.Details
ValidationHandleris an HTTP middleware exported byopenapi3filterthat validates incoming requests and responses against a loaded OpenAPI specification. ItsLoad()method initialises default fields before the handler begins serving:NoopAuthenticationFuncis defined as:It always returns
nil, meaning every security scheme check it handles is automatically approved.When a request arrives,
ServeHTTP→before→validateRequestassembles aRequestValidationInputwith the currentAuthenticationFunc(now the no-op) injected intoOptions:Inside
ValidateRequest, each security requirement callsoptions.AuthenticationFunc:Because
fis the no-op (notnil), theErrAuthenticationServiceMissingguard is never triggered andf(...)returnsnil, clearing the security requirement. Control then proceeds to the protected handler (validation_handler.go:61-62).The critical contradiction is that callers who use
ValidateRequestdirectly with a nilAuthenticationFuncget fail-closed behavior (ErrAuthenticationServiceMissing), while callers who use the higher-levelValidationHandlerwith a nilAuthenticationFuncget fail-open behavior. Since omittingAuthenticationFuncis the natural default, the majority of real-world integrations are vulnerable.Affected source file and line:
openapi3filter/validation_handler.go:47–49(commit30e2923, tagv0.143.0).PoC
Environment
Step 1 — Build the Docker image
From the repository root (parent of
vuln-001/):The
Dockerfilecopies the localkin-openapisource into/kin-openapi/inside the image and builds a Go binary (/poc-binary) frommain.go. Thego.modinside the image uses areplacedirective pointing to/kin-openapi, so no network access to the Go module proxy is required.Step 2 — Run the container
Step 3 (alternative) — Use the Python helper
What the PoC does
main.gocreates a temporary OpenAPI 3.0 spec that declaresGET /secretas protected by anapiKeysecurity scheme:It then constructs a
ValidationHandlerwithout settingAuthenticationFunc, callsLoad(), and sends a request with noX-Api-Keyheader:Expected (vulnerable) output
The contrast block confirms fail-closed behavior when
ValidateRequestis called directly. The exploit block confirms fail-open behavior throughValidationHandler. Status 200 andSECRET_DATAare returned without any credential.Remediation patch
After this change, a nil
AuthenticationFuncpropagates intoValidateRequest, which returnsErrAuthenticationServiceMissingand rejects the request. Callers who genuinely want to skip authentication can still opt in explicitly:h.AuthenticationFunc = openapi3filter.NoopAuthenticationFunc.Impact
This is an authentication bypass vulnerability (CWE-287). Any application that:
openapi3filter.ValidationHandleras its HTTP middleware, andsecurityrequirements in its OpenAPI specification, andAuthenticationFunc,is fully exposed. An unauthenticated remote attacker can send requests to any protected endpoint without supplying credentials; the middleware accepts the request and forwards it to the underlying handler as if authentication had succeeded.
Affected parties include all Go services that adopt
ValidationHandleras a drop-in validation layer and rely on OpenAPIsecuritydeclarations for access control without adding a separate authentication layer upstream (e.g., an API gateway or reverse proxy). Because the insecure behavior is the default, developers following the "getting started" path are affected without any additional mistake.The confidentiality and integrity of data behind secured endpoints are both at high risk. Availability is not directly affected by this vulnerability.
Reproduction artifacts
Dockerfilepoc.pySeverity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
kin-openapi openapi3filter: unauthenticated nil-pointer panic when validating a request against a
contentparameter whose media type has no schemaCVE-2026-73502 / GHSA-jpcw-4wr7-c3vq
More information
Details
github.com/getkin/kin-openapi<= 0.143.0(introduced inv0.2.0, PR #90, 2019-05-07; reproduced onHEAD30e2923)Summary
openapi3filter.ValidateRequestcontains a NULL-pointer-dereference denial of service: any unauthenticated client can crash the request-validation path with a single HTTP request. When an operation declares acontentparameter (as opposed to aschemaparameter) whose media type object has noschema, request validation dereferences that missing schema and panics. The document is legal under the OpenAPI Specification — kin-openapi's owndoc.Validate()accepts it — and the defect affects both OpenAPI 3.0.x and 3.1.x. Depending on how the library is wired into the server (see Impact), this ranges from a per-request abort with unbounded panic-log growth to a full remote process crash.Details
The decoder used for
contentparameters when no customParamDecoderis configured (the library default),defaultContentParameterDecoder, dereferences the media-type schema without a nil check.openapi3filter/req_resp_decoder.go, around line 197:The function guards
param.Content == nil,len(content) != 1, andmt == nil, but nevermt.Schema == nil.Why a schema-less content parameter is legal (so the sink is reachable —
doc.Validate()returns no error), in both 3.0.x and 3.1.x:openapi3/parameter.go—Parameter.Validateonly enforces exactly one ofschemaXORcontent; a parameter withcontent(and noschema) satisfies it.openapi3/media_type.go—MediaType.Validatevalidates the schema only when it is non-nil, so an absent schema is not a validation error.Call path to the panic:
Authentication note:
ValidateRequestvalidates security before parameters, but the panic is reachable without credentials whenever the target operation declares no security requirement, or when noAuthenticationFuncis configured (it is opt-in). A single unauthenticated operation anywhere in the served spec is sufficient. If an operation does declare security and a rejectingAuthenticationFuncis wired, that request is rejected before decoding.PoC
Reproduced end-to-end against
HEAD(30e2923) with a realnet/httpserver and a stockhttp.Client.1. Minimal OpenAPI 3.0.3 document (legal —
doc.Validate()passes). Thecfgquery parameter usescontentwith anapplication/jsonmedia type that has noschema:2. A complete, self-contained program. Drop this into a directory inside a checkout of
github.com/getkin/kin-openapiand run it withgo run .. It loads the document above, assertsdoc.Validate()accepts it (proving reachability), serves it behind request validation exactly as the recommended middleware does, and sends one unauthenticatedGET /c?cfg=1:3. Observed result — the request goroutine panics inside validation, and the client's
http.Getreturns an EOF:Swapping the media type for one that carries a schema (
application/json: {schema: {type: object}}) makes the same request return a clean400instead of panicking, confirming the missing schema is the cause.Impact
This is an unauthenticated remote denial of service (CWE-476) against any service that validates incoming requests with
openapi3filterand serves a spec containing at least onecontentparameter whose media type lacks aschema.The precise consequence depends on which goroutine runs the panic and whether a
recover()covers it:net/http?net/http(incl.openapi3filter.ValidationHandler)http: panic servinglog growth.ValidateRequeston an app-spawned goroutine (fan-out,errgroup, async pre-check)recover().net/httphost (fasthttp adaptor, gRPC-gateway shim, CLI, offline/batch spec validator)This is why the suggested CVSS uses
A:L(Base 5.3): under the recommended synchronousnet/httpwiring the panic is recovered per-connection. Reviewers may reasonably raise it toA:H(Base 7.5) for the spawned-goroutine and non-net/httpintegrations, where a single request kills the process.Remediation (suggested)
Add a
mt.Schema == nilguard mirroring the existingmt == nilguard, so a schema-less content parameter yields a clean validation error instead of a panic:The
unmarshalclosure immediately below already tolerates a nil schema (it checksparamSchema != nil), so returning early on nilmt.Schemais consistent with surrounding intent.Workarounds for consumers, pending a patch:
contentparameter in served specs declares aschema, or reject such specs at load time.ParamDecoderthat guardsmt.Schema == nil.recover()— especially if validation runs off the request goroutine or on a non-net/httphost.Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:LReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
Chi has an IP spoofing vulnerability in middleware.RealIP in github.com/go-chi/chi
CVE-2026-72815 / GHSA-3fxj-6jh8-hvhx / GO-2026-5774
More information
Details
Chi has an IP spoofing vulnerability in middleware.RealIP in github.com/go-chi/chi
Severity
Unknown
References
This data is provided by OSV and the Go Vulnerability Database (CC-BY 4.0).
Chi Middleware vulnerable to IP spoofing via X-Forwarded-For header in github.com/go-chi/chi
CVE-2026-72817 / GHSA-9g5q-2w5x-hmxf / GO-2026-5775
More information
Details
Chi Middleware vulnerable to IP spoofing via X-Forwarded-For header in github.com/go-chi/chi
Severity
Unknown
References
This data is provided by OSV and the Go Vulnerability Database (CC-BY 4.0).
Chi's RealIP Middleware allows IP spoofing via unvalidated X-Forwarded-For header in github.com/go-chi/chi
CVE-2026-72816 / GHSA-rjr7-jggh-pgcp / GO-2026-5777
More information
Details
Chi's RealIP Middleware allows IP spoofing via unvalidated X-Forwarded-For header in github.com/go-chi/chi
Severity
Unknown
References
This data is provided by OSV and the Go Vulnerability Database (CC-BY 4.0).
OOB read in github.com/klauspost/compress/s2
GHSA-259r-337f-4rfw / GO-2026-5841
More information
Details
Providing a specially crafted dictionary to s2.NewDict and using it to encode data can make the encoder read out of bounds.
Severity
Unknown
References
This data is provided by OSV and the Go Vulnerability Database (CC-BY 4.0).
CVE-2026-41579
Impact
When setting up the container rootfs,
setupPtmxandsetupDevSymlinkscallos.Removeandos.Symlinkwith afilepath.Joinstring which allow an image with/devas a symlink to trick runc into deleting files calledptmxon the host or creating a hardcoded set of symlinks with specific names and targets in an arbitrary pre-existing host directory.Please note that this issue is not exploitable under Docker because it creates a top-level
rolayer that masks any malicious/devsymlink present in the container image (this is also done without mounting the lower layers so there is no opportunity for the malicious/devsymlink to trick it into resolving to some other path). Unfortunately, Podman and containerd† do not do this and so users using those higher-level runtimes with runc can be exploited via a malicious image.This issue mirrors a somewhat similar issue in crun, which was also published recently.
† Actually, at the time the issue was analysed, containerd had dead code that implemented this feature but the implementation contained several security issues that would arguably have made it more exploitable than in runc. Luckily, the code appears to have never been used (at least since 2017) and the code has since been removed.
Mitigating Factors
There are a few mitigating factors about this issue which reduce the impact for most users quite significantly, and is the reason why we decided to release the fix publicly without an embargo.
While the deletion of
ptmxseems like a significant issue, in practice it is quite limited. Notably,devptsdoes not permit you to unlink/dev/pts/ptmxregardless of privileges and so it is not a usable target for this attack. Additionally, while/dev/ptmxcan be unlinked‡, trying to use an image with a symlink from/devto/devwill cause runc will return an error before it reaches the buggy code (it correctly detects a symlink loop while setting up the mount target and the code correctly scopes the lookup inside the container). Thus, the only files calledptmxthat are guaranteed to exist on the system cannot actually be removed by this bug and so only some user file that happens to have that specific name could be deleted, which seems fairly unlikely to happen on real systems.As for the issue of symlinks, again the impact is likely quite limited. While the creation of arbitrary symlinks could be used to create drop-in files for system services (and thus lead to a container breakout), the hardcoded set of symlink names and targets that this bug allows you to create on the host make it quite unlikely that you would be able to do much more than pollute the host system with dummy symlinks. Here is the complete list of symlinks that can be created with this attack:
core→/proc/kcorefd→/proc/self/fd/ptmx→pts/ptmxstdin→/proc/self/fd/0stdout→/proc/self/fd/1stderr→/proc/self/fd/2Note that none of these symlinks are likely to point to user-controlled data -- the
/proc/self/fd/$nsymlinks are all properties of the process accessing them (so privileged processes will only see the state they were spawned with) and thepts/ptmxsymlink is almost certainly in the same privilege scope as the directory the symlink itself is in. It seems the only somewhat plausible impact would be that a service could return an error when trying to parse one of these symlinks and thus treat it as an invalid configuration file. How arbitrary processes deal with this situation is a bit hard to analyse, but most daemons require configuration files to have certain suffixes (such as.conf) so it's not really clear how large the impact is in practice and it seems there are a few barriers to clear to use this to cause a DoS or other problems.‡ This would actually be quite problematic if it could occur because
glibcseemingly only attempts to use/dev/ptmxwhen creating new terminals and thus most terminal managers (includingtmux) and shell tools (includingsudo-- but notsu) would fail to start and thus bring the system to a halt.setupPtmxdoes add a symlink to/dev/pts/ptmxafterwards but on some systems the mode of the host/dev/pts/ptmxis set to0o000which would still cause the same DoS issue.Patches
This issue has been patched in runc 1.3.6, runc 1.4.3, and runc 1.5.0-rc.3.
Workarounds
Using user namespaces restricts this attack fairly significantly such that the attacker can only create/delete inodes in directories that the remapped root user/group has write access to. Unless the root user is remapped to an actual user on the host (such as with rootless containers that don't use
/etc/sub[ug]id), this in practice means that an attacker would only be able to create or delete inodes in world-writable directories.LSMs can restrict the scope of where in the host filesystem runc can be tricked into operating on, though how much this helps is questionable. The default
container_runtime_tSELinux label rules (or custom AppArmor rules for the hostrunccontext) may restrict the scope where these filesystem operations can operate on, but we have not done an in-depth analysis on the impact of those kinds of LSM protections.Resources
Credits
runc thanks "Davias" for initially finding and reporting this issue. The same underlying issue (with varying levels of completeness) was later reported by Arthur Chan (@arthurscchan from Ada Logics), Junyi Liu (@mosskappa), and Derek Manzella (@Dmanzella).
Malicious image with /dev symlink can trigger limited host filesystem integrity violations in github.com/opencontainers/runc
CVE-2026-41579 / GHSA-xjvp-4fhw-gc47 / GO-2026-5761
More information
Details
Malicious image with /dev symlink can trigger limited host filesystem integrity violations in github.com/opencontainers/runc
Severity
Unknown
References
This data is provided by OSV and the [Go Vulnerability Database](https://redirect.github.com/