|
1 | 1 | # Security Policy |
2 | 2 |
|
3 | | -## Supported Versions |
| 3 | +## Supported versions |
4 | 4 |
|
5 | 5 | | Version | Status | |
6 | 6 | |---------|--------| |
7 | | -| 0.7.x | ✅ Supported — security fixes | |
8 | | -| < 0.7 | ❌ Unsupported — please upgrade | |
| 7 | +| 0.7.x | Supported, receives security fixes | |
| 8 | +| < 0.7 | Unsupported, please upgrade | |
9 | 9 |
|
10 | | -## Reporting a Vulnerability |
| 10 | +## Reporting a vulnerability |
11 | 11 |
|
12 | | -If you discover a security issue, please **do not** open a public GitHub |
13 | | -issue. Instead, email: |
| 12 | +Please do not open a public GitHub issue. Report privately by either: |
14 | 13 |
|
15 | | -**security@openstudy.dev** (forwarded to the maintainer) |
| 14 | +- Email: **security@openstudy.dev** |
| 15 | +- GitHub: [Report a vulnerability](https://github.com/openstudy-dev/OpenStudy/security/advisories/new) |
16 | 16 |
|
17 | | -You can also report via GitHub's private vulnerability disclosure: |
18 | | -**[Report a vulnerability](https://github.com/openstudy-dev/OpenStudy/security/advisories/new)** |
| 17 | +Include a description of the issue and its impact, steps to reproduce, |
| 18 | +the affected version, and how you would like to be credited (or that you |
| 19 | +prefer not to be). |
19 | 20 |
|
20 | | -### What to include |
| 21 | +### What to expect |
21 | 22 |
|
22 | | -- A description of the vulnerability and its potential impact. |
23 | | -- Steps to reproduce (PoC if possible — without harming other users). |
24 | | -- Affected version(s). |
25 | | -- Your preferred contact info if you want credit / coordination. |
| 23 | +- Acknowledgement within 72 hours. |
| 24 | +- Initial assessment within 7 days. |
| 25 | +- A fix or a disclosure timeline within 30 days for high-severity issues. |
| 26 | +- Public disclosure after the fix ships, or 90 days after the report, |
| 27 | + whichever comes first. |
26 | 28 |
|
27 | | -### What to expect |
| 29 | +### Safe harbour |
28 | 30 |
|
29 | | -- Acknowledgement within **72 hours**. |
30 | | -- An initial assessment within **7 days**. |
31 | | -- A fix or disclosure timeline within **30 days** for high-severity issues. |
32 | | -- Public disclosure happens **after** a fix ships, or **90 days** after |
33 | | - the initial report — whichever comes first. |
| 31 | +Good-faith research that follows this policy, avoids privacy violations, |
| 32 | +data destruction and service disruption, and gives us reasonable time to |
| 33 | +fix the issue will not be met with legal action. |
34 | 34 |
|
35 | 35 | ## Scope |
36 | 36 |
|
37 | | -OpenStudy is multi-tenant. The following are in scope for security |
38 | | -reports: |
| 37 | +OpenStudy is multi-tenant. In scope: |
39 | 38 |
|
40 | | -- **Cross-user data exposure** — one user reading/writing another user's |
41 | | - data via any API surface (REST, MCP, file storage). |
42 | | -- **Authentication / session bypass** — login, signup, password reset, |
43 | | - email verification, TOTP, OAuth consent. |
44 | | -- **Privilege escalation** — non-operator user gaining operator |
45 | | - capabilities. |
46 | | -- **Credential leakage** — Telegram tokens, encrypted secrets, session |
47 | | - cookies. |
48 | | -- **Stored XSS / SQL injection** — anywhere user input flows into a |
49 | | - query or rendered HTML. |
| 39 | +- Cross-user data exposure through any API surface (REST, MCP, file storage). |
| 40 | +- Authentication or session bypass: login, signup, password reset, email |
| 41 | + verification, TOTP, OAuth consent. |
| 42 | +- Privilege escalation from a normal user to operator. |
| 43 | +- Credential leakage: Telegram tokens, encrypted secrets, session cookies. |
| 44 | +- Stored XSS and SQL injection. |
50 | 45 |
|
51 | 46 | Out of scope: |
| 47 | + |
52 | 48 | - Bugs in third-party services (Hetzner, Cloudflare, Telegram). |
53 | | -- Denial-of-service via expected rate limits. |
54 | | -- Self-XSS / social engineering of the operator. |
55 | | -- Issues in self-hosted setups due to operator misconfiguration |
56 | | - (weak passwords, exposed env files, etc.). |
57 | | - |
58 | | -### OAuth client registration is intentionally open |
59 | | - |
60 | | -`POST /oauth/register` is an unauthenticated RFC 7591 Dynamic Client |
61 | | -Registration endpoint. This is **by design**: the MCP authorization spec |
62 | | -requires open DCR so MCP clients (Claude.ai, Claude Code, any future |
63 | | -client) can self-register without an operator in the loop. Reports that |
64 | | -the endpoint "allows unauthenticated registration" are therefore not |
65 | | -vulnerabilities on their own. |
66 | | - |
67 | | -What *is* in scope is anything that turns open DCR into account access |
68 | | -without an informed user click. The guard-rails, all of which are fair |
69 | | -game for reports: |
70 | | - |
71 | | -- **Rate limit** — per-IP cap on registration attempts, valid or not |
72 | | - (`REGISTER_MAX` / `REGISTER_WINDOW_MIN`). |
73 | | -- **redirect_uri validation** — `https` only (plain `http` accepted for |
74 | | - loopback hosts only), no fragments, no wildcards, absolute URIs with a |
75 | | - host. One bad URI rejects the whole registration. |
76 | | -- **Metadata caps** — at most 10 redirect URIs, `client_name` ≤ 100 |
77 | | - printable characters. |
78 | | -- **Informed consent** — the consent screen shows the exact redirect URI |
79 | | - the authorization code will be sent to and states that the client name |
80 | | - is self-asserted, not verified by OpenStudy. |
81 | | -- **Bounded token lifetime** — `OAUTH_TOKEN_TTL_DAYS` (default 30). |
82 | | -- **Stale-client pruning** — clients that never complete a flow within |
83 | | - 7 days are deleted. |
84 | | - |
85 | | -A consent-phishing bypass (getting a code to an attacker without the |
86 | | -user seeing the destination), a validator bypass, or a way around the |
87 | | -rate limit would all be valid reports. |
| 49 | +- Denial of service that the existing rate limits are designed to absorb. |
| 50 | +- Self-XSS, or social engineering of the operator. |
| 51 | +- Misconfigured self-hosted installs (weak passwords, exposed env files). |
| 52 | + |
| 53 | +### Not considered vulnerabilities |
| 54 | + |
| 55 | +- **Unauthenticated OAuth client registration.** `POST /oauth/register` |
| 56 | + is an open RFC 7591 endpoint on purpose: the MCP authorization spec |
| 57 | + requires it so clients such as Claude.ai can register themselves. |
| 58 | + Registration is rate-limited, redirect URIs are validated, and the |
| 59 | + consent screen shows the user exactly where the authorization code will |
| 60 | + be sent. A way around any of those protections is in scope. |
88 | 61 |
|
89 | 62 | ## Acknowledgements |
90 | 63 |
|
91 | | -We credit researchers who report responsibly, with their permission and |
92 | | -in the form they prefer (name, handle, link, or anonymous). |
| 64 | +We credit researchers who report responsibly, in the form they prefer. |
93 | 65 |
|
94 | | -- **2026-09** — Anonymous researcher: reported that the open DCR endpoint |
95 | | - could be used to stage a consent-phishing flow with an |
96 | | - attacker-controlled redirect URI. Led to the guard-rails documented |
97 | | - above (rate limiting, redirect URI validation, informed consent screen, |
98 | | - shorter token lifetime). |
| 66 | +- 2026-09: Anonymous researcher. Consent-phishing path via open client |
| 67 | + registration with an attacker-controlled redirect URI. |
0 commit comments