javascript-solid-server 0.0.52 → 0.0.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +3 -1
- package/package.json +1 -1
- package/src/auth/solid-oidc.js +27 -8
- package/src/idp/index.js +4 -0
- package/src/server.js +3 -3
|
@@ -200,7 +200,9 @@
|
|
|
200
200
|
"Bash(tar:*)",
|
|
201
201
|
"Bash(TEST_API=1 API_URL=https://api.solid.social node:*)",
|
|
202
202
|
"Bash(webledgers show:*)",
|
|
203
|
-
"Bash(webledgers set-balance:*)"
|
|
203
|
+
"Bash(webledgers set-balance:*)",
|
|
204
|
+
"Bash(ssh melvincarvalho.com \"pm2 list | grep jss\")",
|
|
205
|
+
"Bash(ssh melvincarvalho.com \"cd /home/ubuntu/jss && git pull && pm2 restart jss\")"
|
|
204
206
|
]
|
|
205
207
|
}
|
|
206
208
|
}
|
package/package.json
CHANGED
package/src/auth/solid-oidc.js
CHANGED
|
@@ -20,6 +20,19 @@ const jwksCache = new Map();
|
|
|
20
20
|
// Cache TTL (15 minutes)
|
|
21
21
|
const CACHE_TTL = 15 * 60 * 1000;
|
|
22
22
|
|
|
23
|
+
// Trusted issuers (skip SSRF check) - populated by server config
|
|
24
|
+
const trustedIssuers = new Set();
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Add a trusted issuer (e.g., the server's own issuer)
|
|
28
|
+
* Trusted issuers bypass SSRF validation since they're configured by admin
|
|
29
|
+
*/
|
|
30
|
+
export function addTrustedIssuer(issuer) {
|
|
31
|
+
const normalized = issuer.replace(/\/$/, '');
|
|
32
|
+
trustedIssuers.add(normalized);
|
|
33
|
+
trustedIssuers.add(normalized + '/');
|
|
34
|
+
}
|
|
35
|
+
|
|
23
36
|
// DPoP proof max age (5 minutes)
|
|
24
37
|
const DPOP_MAX_AGE = 5 * 60;
|
|
25
38
|
|
|
@@ -206,15 +219,21 @@ async function getOidcConfig(issuer) {
|
|
|
206
219
|
return cached.config;
|
|
207
220
|
}
|
|
208
221
|
|
|
209
|
-
//
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
222
|
+
// Check if this is a trusted issuer (e.g., our own server)
|
|
223
|
+
const normalizedIssuer = issuer.replace(/\/$/, '');
|
|
224
|
+
const isTrusted = trustedIssuers.has(normalizedIssuer) || trustedIssuers.has(normalizedIssuer + '/');
|
|
225
|
+
|
|
226
|
+
// SSRF Protection: Validate issuer URL before fetching (skip for trusted issuers)
|
|
227
|
+
if (!isTrusted) {
|
|
228
|
+
const validation = await validateExternalUrl(issuer, {
|
|
229
|
+
requireHttps: true,
|
|
230
|
+
blockPrivateIPs: true,
|
|
231
|
+
resolveDNS: true
|
|
232
|
+
});
|
|
215
233
|
|
|
216
|
-
|
|
217
|
-
|
|
234
|
+
if (!validation.valid) {
|
|
235
|
+
throw new Error(`Invalid OIDC issuer: ${validation.error}`);
|
|
236
|
+
}
|
|
218
237
|
}
|
|
219
238
|
|
|
220
239
|
const configUrl = `${issuer.replace(/\/$/, '')}/.well-known/openid-configuration`;
|
package/src/idp/index.js
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
handleCredentials,
|
|
19
19
|
handleCredentialsInfo,
|
|
20
20
|
} from './credentials.js';
|
|
21
|
+
import { addTrustedIssuer } from '../auth/solid-oidc.js';
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* IdP Fastify Plugin
|
|
@@ -32,6 +33,9 @@ export async function idpPlugin(fastify, options) {
|
|
|
32
33
|
throw new Error('IdP requires issuer URL');
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
// Register our own issuer as trusted (bypasses SSRF check for self-validation)
|
|
37
|
+
addTrustedIssuer(issuer);
|
|
38
|
+
|
|
35
39
|
// Initialize signing keys
|
|
36
40
|
await initializeKeys();
|
|
37
41
|
|
package/src/server.js
CHANGED
|
@@ -240,12 +240,12 @@ export function createServer(options = {}) {
|
|
|
240
240
|
});
|
|
241
241
|
|
|
242
242
|
// Pod creation endpoint with rate limiting
|
|
243
|
-
// Limit:
|
|
243
|
+
// Limit: 1 pod per IP per day to prevent resource exhaustion and namespace squatting
|
|
244
244
|
fastify.post('/.pods', {
|
|
245
245
|
config: {
|
|
246
246
|
rateLimit: {
|
|
247
|
-
max:
|
|
248
|
-
timeWindow: '1
|
|
247
|
+
max: 1,
|
|
248
|
+
timeWindow: '1 day',
|
|
249
249
|
keyGenerator: (request) => request.ip
|
|
250
250
|
}
|
|
251
251
|
}
|