Client CN with '/' in subject accesses subdirectory of clients/ config dir #31

Closed
opened 2026-05-17 23:13:43 +02:00 by heiko · 1 comment
Owner

Summary

cmd/cert-proxy-server/cnlist.go:15 opens the per-client config file using the raw X.509 Common Name:

cc, err := http.Dir(opt.ClientConfigDir).Open(cn)

http.Dir prevents ../ traversal, but a CN containing a forward slash (e.g. a/b) is treated as a path component: http.Dir.Open("a/b") opens clients/a/b rather than clients/a%2Fb.

A CA that issues a certificate with CN=subdir/name could cause the server to read a config file from an unexpected subdirectory of the clients directory.

Impact

Requires a compromised or permissive CA. If the clients directory contains subdirectories for other purposes, unexpected authorization files could be read.

Fix

Reject any CN that contains a path separator before using it as a filename:

if strings.ContainsAny(cn, "/\\") {
    return nil, fmt.Errorf("invalid CN %q: contains path separator", cn)
}
## Summary `cmd/cert-proxy-server/cnlist.go:15` opens the per-client config file using the raw X.509 Common Name: ```go cc, err := http.Dir(opt.ClientConfigDir).Open(cn) ``` `http.Dir` prevents `../` traversal, but a CN containing a forward slash (e.g. `a/b`) is treated as a path component: `http.Dir.Open("a/b")` opens `clients/a/b` rather than `clients/a%2Fb`. A CA that issues a certificate with CN=`subdir/name` could cause the server to read a config file from an unexpected subdirectory of the clients directory. ## Impact Requires a compromised or permissive CA. If the clients directory contains subdirectories for other purposes, unexpected authorization files could be read. ## Fix Reject any CN that contains a path separator before using it as a filename: ```go if strings.ContainsAny(cn, "/\\") { return nil, fmt.Errorf("invalid CN %q: contains path separator", cn) } ```
Author
Owner

Confirmed. http.Dir blocks .. traversal but treats / as a path separator, so a CN like a/b reads clients/a/b. Fix is a one-liner: reject CNs containing /, \, NUL, or that are empty / start with '.'. Will keep scope to cnList — the adjacent double-Close on cc is tracked separately in #32.

🤖 Generated with Claude Code (claude-opus-4-7)

Confirmed. http.Dir blocks .. traversal but treats / as a path separator, so a CN like a/b reads clients/a/b. Fix is a one-liner: reject CNs containing /, \\, NUL, or that are empty / start with '.'. Will keep scope to cnList — the adjacent double-Close on cc is tracked separately in #32. — 🤖 Generated with Claude Code (claude-opus-4-7)
heiko closed this issue 2026-05-20 23:48:34 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
heiko/cert-proxy#31
No description provided.