Описание
Flowise: Unauthenticated OAuth2 Refresh Enables Non-Blind SSRF and Secret Exfiltration
Summary
The OAuth2 token refresh endpoint (POST /api/v1/oauth2-credential/refresh/:credentialId) is unauthenticated by design (it is in the public whitelist) and performs a server-side HTTP request to a credential-controlled URL (accessTokenUrl) without SSRF protections. In runtime validation, this endpoint was reachable without auth, triggered outbound POST requests to an attacker-controlled server, and reflected the full remote response body to the caller (tokenInfo), confirming non-blind SSRF and credential secret exfiltration.
Details
The vulnerability is in dist/routes/oauth2/index.js (container runtime build), under path prefix /api/v1/oauth2-credential.
Confirmed in runtime code:
-
Unauthenticated route via whitelist
dist/utils/constants.jsincludes:/api/v1/oauth2-credential/callback/api/v1/oauth2-credential/refresh
dist/index.jsauth middleware uses:const isWhitelisted = whitelistURLs.some((url) => req.path.startsWith(url))
- Therefore
/api/v1/oauth2-credential/refresh/:credentialIdis treated as whitelisted.
-
User-controlled SSRF target
- In refresh handler (
dist/routes/oauth2/index.js):- loads credential by
credentialId - decrypts credential data
- reads
accessTokenUrl - executes:
axios.post(tokenUrl, new URLSearchParams(refreshRequestData).toString(), ...)
- loads credential by
- No
secureAxiosRequest()/ denylist wrapper is used in this path.
- In refresh handler (
-
Non-blind response reflection
- Response returns:
tokenInfo: { ...tokenData, ... }
tokenDatais the attacker/internal server response body.
- Response returns:
-
Secrets sent to SSRF target
- Request body includes:
client_idclient_secretgrant_type=refresh_tokenrefresh_token
- Request body includes:
PoC
Environment used
flowiseai/flowise:latestcontainer (localhost:3000)- Attacker server (
localhost:18081) returning JSON
Step 1: Start attacker server
Step 2: Create OAuth2 credential with attacker accessTokenUrl (authenticated action)
In validation, this was done via authenticated API path (credential creation requires auth/permissions), then refresh was tested publicly.
Resulting credential ID used in runtime validation:
24c0b18b-ff6e-4d81-a9a7-26ea8ddccdef
Step 3: Trigger refresh without auth
Observed response:
Attacker server logs captured:
This confirms:
- unauthenticated trigger,
- server-side POST to attacker-controlled URL,
- exfiltration of OAuth2 secrets in POST body,
- full response reflection to client (
tokenInfo).
Impact
- Vulnerability class: Non-blind SSRF + sensitive secret exfiltration.
- Who can set up attack: Any authenticated user who can create/update OAuth2 credentials.
- Who can trigger attack: Anyone who knows a valid OAuth2 credential UUID (refresh endpoint is public/whitelisted).
- Technical impact:
- outbound SSRF to attacker/internal targets,
- direct leak of
client_secretandrefresh_tokento SSRF target, - direct response read from target via API response (
tokenInfo).
- Deployment impact:
- cloud/internal network reachability can expose metadata/internal services depending on egress controls.
Пакеты
flowise
<= 3.1.2
3.1.3
Связанные уязвимости
Flowise is a drag & drop user interface to build a customized large language model flow. Prior to 3.1.3, the OAuth2 token refresh endpoint POST /api/v1/oauth2-credential/refresh/:credentialId is unauthenticated by design and performs a server-side HTTP request to the credential-controlled accessTokenUrl without SSRF protections. Runtime validation confirmed that the endpoint was reachable without authentication, triggered outbound POST requests to an attacker-controlled server, reflected the full remote response body to the caller through tokenInfo, and sent client_id, client_secret, grant_type=refresh_token, and refresh_token in the request body. This issue is fixed in version 3.1.3.
Уязвимость файла dist/routes/oauth2/index.js программной платформы для создания пользовательских интерфейсов поверх языковых моделей (LLM) Flowise, позволяющая нарушителю осуществить SSRF-атаку и раскрыть защищаемую информацию