No authentication is required to invoke PUT /api/echo/like/:id. The handler is registered on the public router group. The service increments fav_count for the given echo without checking identity, without a per-user limit, and without CSRF tokens. A remote client can arbitrarily inflate like metrics with repeated requests.
The fetchPeerConnectInfo function in internal/service/connect/connect.go:214-239 uses httpUtil.SendRequest (no SSRF protection) instead of SendSafeRequest (which has ValidatePublicHTTPURL with private IP blocking). This allows authenticated users to make the server request arbitrary URLs including internal/cloud metadata endpoints.
The system log endpoints (GET /api/system/logs, GET /api/system/logs/stream, WS /ws/system/logs) lack authorization checks, allowing any authenticated non-admin user to read and stream all server logs. These logs contain error stack traces, internal file paths, module names, and arbitrary structured fields that facilitate reconnaissance for further attacks.
Ech0 scoped access tokens do not reliably enforce least privilege: multiple privileged admin routes omit scope checks, and the backup export handler strips token scope metadata entirely, allowing a low-scope admin access token to reach broader admin functionality than intended.
Ech0 allows any authenticated user to read historical system logs and subscribe to live log streams because the dashboard log endpoints validate only that a JWT is present and valid, but do not require an administrator role or privileged scope.
The PUT /user endpoint is protected by RequireScopes("profile:read"), which is a read-only scope. However, the endpoint performs write operations including password changes. An attacker who obtains an admin's restricted profile:read access token can change the admin's password, then login to receive an unrestricted session token that bypasses all scope enforcement.
The file upload endpoint validates Content-Type using only the client-supplied multipart header, with no server-side content inspection or file extension validation. Combined with an unauthenticated static file server that determines Content-Type from file extension, this allows an admin to upload HTML/SVG files containing JavaScript that execute in the application's origin when visited by any user. Additionally, image/svg+xml is in the default allowed types, enabling stored XSS via SVG without any …
The validateWebhookURL function in webhook_setting_service.go attempts to block webhooks targeting private/internal IP addresses, but only checks literal IP strings via net.ParseIP(). Hostnames that DNS-resolve to private IPs (e.g., 169.254.169.254.nip.io, 10.0.0.1.nip.io) bypass all checks, allowing an admin to create webhooks that make server-side requests to internal network services and cloud metadata endpoints.
All 9 comment panel admin endpoints (/api/panel/comments/*) are missing RequireScopes() middleware, while every other admin endpoint in the application enforces scope-based authorization on access tokens. An admin-issued access token scoped to minimal permissions (e.g., echo:read only) can perform full comment moderation operations including listing, approving, rejecting, deleting comments, and modifying comment system settings.
The GET /api/website/title endpoint accepts an arbitrary URL via the website_url query parameter and makes a server-side HTTP request to it without any validation of the target host or IP address. The endpoint requires no authentication. An attacker can use this to reach internal network services, cloud metadata endpoints (169.254.169.254), and localhost-bound services, with partial response data exfiltrated via the HTML <title> tag extraction.
Ech0 implements link preview (editor fetches a page title) through GET /api/website/title. That is legitimate product behavior, but the implementation is unsafe: the route is unauthenticated, accepts a fully attacker-controlled URL, performs a server-side GET, reads the entire response body into memory (io.ReadAll). There is no host allowlist, no SSRF filter, and InsecureSkipVerify: true on the outbound client. Attacker outcome : Anyone who can reach the instance can force the …
A public access-control flaw allows unauthenticated users to retrieve the full user list from GET /api/allusers. This exposes user profile metadata to anyone who can reach the application and enables remote user enumeration.