CTFd / CTFd

CTFs as you need them
https://ctfd.io
Apache License 2.0
5.59k stars 2.07k forks source link

Undocumented and unauthenticated API notifications endpoint ? #2310

Open pandatix opened 1 year ago

pandatix commented 1 year ago

Environment:

What happened?

When reviewing the API for a Golang client, I discovered the /api/v1/notifications endpoints. Nevertheless, it does not contain the HEAD that is documented in the swagger UI (screenshot follows).

Using the undocumented HEAD one, you can issue requests that don't require authentication. An example without parameters follows.

$ curl -I http://127.0.0.1:4000/api/v1/notifications
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Result-Count: 1
Set-Cookie: session=9ddc61ea-2fdd-4f08-9a9a-2ea8546aa41f.mRLdOxPbeXrDbi3zNSWL5p95ZxE; HttpOnly; Path=/; SameSite=Lax
Content-Length: 0
Server: Werkzeug/1.0.1 Python/3.11.2
Date: Wed, 24 May 2023 22:52:50 GMT

Thanks to the parameters, you could blindly-fetch notifications content as blind-SQLi are made.

For instance, let's says you iterate using the title parameter. The response header Result-Count should be 0 until you match one/many notifications titles.

I have to admit that I don't know if we have to consider it a vulnerability has it leaks data without authentication going against the expected and documented behavior, or just a way to have the notifications working. If we consider an attack, the attacker requires no account (there may be a problem here) and a blind brute-force attack on the endpoint to get the title/content/user_id/team_id/... Let's say we write notifications title with an alphabet of 62 chars (26 lowercase 26 uppercase 10 special characters) with a minimal length of 10 chars : worst case is 62^10 combinations until blind brute-force works, possibly taking forever. Apply it on the most-valuable parameter i.e. content and you see it is unlikely to happen. This may create the CVSS v3.1 vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N with a score of 5.3 (MEDIUM).

What did you expect to happen?

Get redirected to the login form, maybe ? :shrug:

How to reproduce your issue

Steps 1 to 3 are optional if have a running CTFd near.

  1. Clone the repository
  2. cd CTFd && make serve
  3. Setup CTFd with whatever configuration
  4. Make the previous curl call
pandatix commented 1 year ago

By dissecting the code, seems there is no obvious authentication : https://github.com/CTFd/CTFd/blob/master/CTFd/api/v1/notifications.py#L104, same for get method.

pandatix commented 1 year ago

Up @ColdHeat, don't know if you had time to check 🤗

ColdHeat commented 1 year ago

Calling this SQL injection is a bit of a stretch unless you can query information about other tables. Notifications are currently intended to be borderline public. In the future they may become private (i.e. for specific users) but for now they are almost global broadcasts.

We can add authentication but there was some idea around allowing users to check how many notifications they had missing without having to authenticate. Perhaps it makes more sense to have authentication but it's not really a pressing issue or a vulnerability.

As for the documentation I'm not sure why it's not showing up. Perhaps I need to update some JSON somewhere.