You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- 🔒 **Rate Limiting** - Per-IP rate limiting for API protection
173
173
- 🔌 **Extensible** - Add custom adapters to integrate any external OER API
174
174
175
+
> **Security Note — Nostr AMB Relay adapter:** If you plan to use the `nostr-amb-relay` adapter, it is recommended to use it in **direct-client mode** (browser-side) only. If you need to use it through the proxy server, configure **imgproxy** and set `ASSET_PROXY_ALLOWED_DOMAINS` to restrict which domains the proxy may contact. AMB relay events can contain arbitrary URLs; when the proxy fetches these server-side, a malicious event could point to internal network resources (SSRF). See the [Server Setup Guide](./docs/server-setup.md#nostr-amb-relay-security) for details.
|`TRUST_PROXY`|`0`| Number of trusted reverse proxy hops (0 = disabled, max 10). Set to `1` when behind a single reverse proxy (e.g. nginx) so rate limiting uses the real client IP |
68
+
69
+
### Rate Limiting
70
+
71
+
| Variable | Default | Description |
72
+
|----------|---------|-------------|
73
+
|`THROTTLE_TTL`|`60000`| Rate limit window in milliseconds |
74
+
|`THROTTLE_LIMIT`|`30`| Maximum requests per window |
75
+
|`THROTTLE_BLOCK_DURATION`|`60000`| Block duration in milliseconds after exceeding the limit |
65
76
66
77
### Source Adapter Configuration
67
78
@@ -76,7 +87,7 @@ Source adapters forward search requests to external OER sources. Adapters are en
76
87
77
88
| Adapter ID | Description | Additional Config |
78
89
|------------|-------------|-------------------|
79
-
|`nostr-amb-relay`| AMB Nostr relay for educational metadata |`NOSTR_AMB_RELAY_URL` required |
90
+
|`nostr-amb-relay`| AMB Nostr relay for educational metadata |`NOSTR_AMB_RELAY_URL` required. See [security note](#nostr-amb-relay-security)|
> **Recommendation:** If you plan to use the `nostr-amb-relay` adapter, it is recommended to use it in **direct-client mode only** (running in the browser). If you need to use it through the proxy server, **configure imgproxy** and set `ASSET_PROXY_ALLOWED_DOMAINS` to restrict which domains the proxy may contact.
110
+
>
111
+
> **Why:** AMB relay events can contain arbitrary URLs (e.g. thumbnails, resource links). When the proxy fetches these URLs server-side, a malicious event could include URLs pointing to internal network resources (e.g. `http://169.254.169.254/...`, `http://localhost:...`), causing the proxy to make requests to services that should not be publicly reachable (SSRF). In direct-client mode, these requests come from the user's browser, which does not have access to the server's internal network. When using imgproxy, asset fetching is handled by imgproxy's own safeguards rather than the proxy application directly.
112
+
96
113
When adapters are enabled:
97
114
- The `source` query parameter selects which adapter to query (required)
98
115
- With `source=nostr-amb-relay`: queries the AMB Nostr relay
@@ -127,6 +144,12 @@ The proxy supports optional [imgproxy](https://imgproxy.net/) integration. When
127
144
-**Insecure**: Set only `IMGPROXY_BASE_URL`. URLs are generated without signatures.
128
145
-**Secure**: Set all three variables. URLs are signed with HMAC-SHA256.
129
146
147
+
**SSRF hardening**: imgproxy fetches arbitrary source URLs server-side. While imgproxy has built-in loopback protections, [past CVEs have shown bypasses](https://github.com/imgproxy/imgproxy/security/advisories/GHSA-j2hp-6m75-v4j4). To mitigate SSRF risks:
148
+
1.**Set `ASSET_PROXY_ALLOWED_DOMAINS`** — the proxy applies this allowlist *before* any URL reaches imgproxy, blocking URLs to non-allowlisted domains at the application layer.
149
+
2.**Network isolation** — run imgproxy in a network segment that cannot reach internal services (e.g. cloud metadata endpoints, databases, admin interfaces). In Docker Compose, use a dedicated network with no access to internal services.
150
+
3.**Keep imgproxy updated** — patches close known bypasses.
|`ASSET_PROXY_TIMEOUT_MS`|`15000`| Per-asset proxy fetch timeout in ms (range 1000–30000) |
198
+
|`ASSET_PROXY_ALLOWED_DOMAINS`| - | Comma-separated domain allowlist for asset proxy (empty = allow all). Subdomains are matched automatically |
199
+
200
+
When the proxy fetches assets on behalf of clients, these settings control timeouts and restrict which external domains are allowed. Setting `ASSET_PROXY_ALLOWED_DOMAINS` is **strongly recommended** in production to prevent the proxy from being used to probe internal network resources (SSRF).
201
+
170
202
**Priority**: When both imgproxy and asset signing are configured, imgproxy takes priority for generating image URLs from source URLs. Asset signing is still used to sign adapter-provided image URLs.
0 commit comments