<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="/static/style.xsl" type="text/xsl"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>Most recent entries from all</title>
    <link>https://vulnerability.circl.lu</link>
    <description>Contains only the most 10 recent entries.</description>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>python-feedgen</generator>
    <language>en</language>
    <lastBuildDate>Thu, 01 Oct 2026 21:12:21 +0000</lastBuildDate>
    <item>
      <title>GHSA-gx7w-56w6-g48x — Caddy: Remote Admin Authorization Bypass on PKI Endpoints via Prefix-Based Path Matching</title>
      <link>https://vulnerability.circl.lu/vuln/ghsa-gx7w-56w6-g48x</link>
      <description>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; Go: github.com/caddyserver/caddy/v2&lt;/p&gt;
&lt;p&gt;## AI Disclosure&lt;/p&gt;
&lt;p&gt;I used an LLM to help review the source code, reason about attack surface, and help draft and refine this report.
  I manually validated the finding by reproducing it locally, confirming the vulnerable code path, and verifying the HTTP behavior with `curl -v`.&lt;/p&gt;
&lt;p&gt;## Summary&lt;/p&gt;
&lt;p&gt;Caddy&amp;#39;s remote admin access control performs path authorization using prefix matching:&lt;/p&gt;
&lt;p&gt;- [`admin.go`](/caddy/admin.go#L719): `strings.HasPrefix(r.URL.Path, allowedPath)`&lt;/p&gt;
&lt;p&gt;This allows a client certificate authorized only for `/pki/ca/prod` to access sibling PKI resources whose paths merely share the same prefix, such as `/pki/ca/prod-backup`.&lt;/p&gt;
&lt;p&gt;This is an authorization bug in Caddy&amp;#39;s source code, not a misconfiguration issue. The configured policy is more restrictive than the behavior that Caddy actually enforces.&lt;/p&gt;
&lt;p&gt;## Affected Component&lt;/p&gt;
&lt;p&gt;Remote admin access control for PKI admin endpoints.&lt;/p&gt;
&lt;p&gt;Relevant code:&lt;/p&gt;
&lt;p&gt;- [`admin.go`](/caddy/admin.go#L687)
  - [`admin.go`](/caddy/admin.go#L719)
  - [`modules/caddypki/adminapi.go`](/caddy/modules/caddypki/adminapi.go#L68)
  - [`modules/caddypki/adminapi.go`](/caddy/modules/caddypki/adminapi.go#L164)&lt;/p&gt;
&lt;p&gt;## Root Cause&lt;/p&gt;
&lt;p&gt;In `RemoteAdmin.enforceAccessControls()`, allowed paths are checked like this:&lt;/p&gt;
&lt;p&gt;```go
  for _, allowedPath := range accessPerm.Paths {
  	if strings.HasPrefix(r.URL.Path, allowedPath) {
  		pathFound = true
  		break
  	}
  }
```&lt;/p&gt;
&lt;p&gt;This does not enforce a path-segment boundary.&lt;/p&gt;
&lt;p&gt;So if the allowed path is:&lt;/p&gt;
&lt;p&gt;/pki/c…&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; Go: github.com/caddyserver/caddy/v2&lt;/p&gt;
&lt;p&gt;## AI Disclosure&lt;/p&gt;
&lt;p&gt;I used an LLM to help review the source code, reason about attack surface, and help draft and refine this report.
  I manually validated the finding by reproducing it locally, confirming the vulnerable code path, and verifying the HTTP behavior with `curl -v`.&lt;/p&gt;
&lt;p&gt;## Summary&lt;/p&gt;
&lt;p&gt;Caddy&amp;#39;s remote admin access control performs path authorization using prefix matching:&lt;/p&gt;
&lt;p&gt;- [`admin.go`](/caddy/admin.go#L719): `strings.HasPrefix(r.URL.Path, allowedPath)`&lt;/p&gt;
&lt;p&gt;This allows a client certificate authorized only for `/pki/ca/prod` to access sibling PKI resources whose paths merely share the same prefix, such as `/pki/ca/prod-backup`.&lt;/p&gt;
&lt;p&gt;This is an authorization bug in Caddy&amp;#39;s source code, not a misconfiguration issue. The configured policy is more restrictive than the behavior that Caddy actually enforces.&lt;/p&gt;
&lt;p&gt;## Affected Component&lt;/p&gt;
&lt;p&gt;Remote admin access control for PKI admin endpoints.&lt;/p&gt;
&lt;p&gt;Relevant code:&lt;/p&gt;
&lt;p&gt;- [`admin.go`](/caddy/admin.go#L687)
  - [`admin.go`](/caddy/admin.go#L719)
  - [`modules/caddypki/adminapi.go`](/caddy/modules/caddypki/adminapi.go#L68)
  - [`modules/caddypki/adminapi.go`](/caddy/modules/caddypki/adminapi.go#L164)&lt;/p&gt;
&lt;p&gt;## Root Cause&lt;/p&gt;
&lt;p&gt;In `RemoteAdmin.enforceAccessControls()`, allowed paths are checked like this:&lt;/p&gt;
&lt;p&gt;```go
  for _, allowedPath := range accessPerm.Paths {
  	if strings.HasPrefix(r.URL.Path, allowedPath) {
  		pathFound = true
  		break
  	}
  }
```&lt;/p&gt;
&lt;p&gt;This does not enforce a path-segment boundary.&lt;/p&gt;
&lt;p&gt;So if the allowed path is:&lt;/p&gt;
&lt;p&gt;/pki/c…&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://vulnerability.circl.lu/vuln/ghsa-gx7w-56w6-g48x</guid>
    </item>
  </channel>
</rss>
