Flowise 1.6.5 - Authentication Bypass
# Exploit Title: Flowise 1.6.5 - Authentication Bypass
# Date: 17-April-2024
# Exploit Author: Maerifat Majeed
# Vendor Homepage: https://flowiseai.com/
# Software Link: https://github.com/FlowiseAI/Flowise/releases
# Version: 1.6.5
# Tested on: mac-os
# CVE : CVE-2024-31621
The flowise version <= 1.6.5 is vulnerable to authentication bypass
vulnerability.
The code snippet
this.app.use((req, res, next) => {
> if (req.url.includes('/api/v1/')) {
> whitelistURLs.some((url) => req.url.includes(url)) ?
> next() : basicAuthMiddleware(req, res, next)
> } else next()
> })
puts authentication middleware for all the endpoints with path /api/v1
except a few whitelisted endpoints. But the code does check for the case
sensitivity hence only checks for lowercase /api/v1 . Anyone modifying the
endpoints to uppercase like /API/V1 can bypass the authentication.
*POC:*
curl http://localhost:3000/Api/v1/credentials
For seamless authentication bypass. Use burpsuite feature Match and replace
rules in proxy settings. Add rule Request first line api/v1 ==> API/V1 Flowise 1.6.5 — Authentication Bypass (CVE-2024-31621)
This article explains an authentication bypass vulnerability discovered in Flowise versions ≤ 1.6.5 (CVE-2024-31621). It covers the root cause, proof-of-concept behavior, risk and impact, detection strategies, recommended fixes and hardening guidance for developers and operators.
Summary / Quick Facts
| Item | Detail |
|---|---|
| Vulnerability | Authentication bypass due to case-sensitive URL checking in middleware |
| Product | Flowise |
| Versions affected | ≤ 1.6.5 |
| CVE | CVE-2024-31621 |
| Root cause | Middleware uses case-sensitive substring checks on req.url and misses differently-cased paths |
| Remediation | Upgrade to a patched release or normalize path comparisons; use route-based authentication |
Root cause analysis
Flowise registers a global middleware that decides whether to run authentication middleware by testing whether the request URL contains the literal string "/api/v1/". The check is performed using JavaScript string matching on req.url and does not normalize case. As a result, semantically equivalent URLs with different capitalization (for example "/Api/v1/" or "/API/V1/") do not match the check and are treated as non-protected, allowing requests to reach API endpoints without authentication.
Relevant simplified logic (illustrative):
this.app.use((req, res, next) => {
if (req.url.includes('/api/v1/')) {
whitelistURLs.some((url) => req.url.includes(url)) ?
next() : basicAuthMiddleware(req, res, next)
} else next()
})
Explanation: the code above checks req.url.includes('/api/v1/') and branches accordingly. Because the check is case-sensitive, any request path with different case will not trigger authentication.
Why this matters
- APIs under /api/v1 are intended to require authentication. A bypass allows unauthenticated callers to access potentially sensitive endpoints.
- Attackers and automated scanners frequently try simple variations of paths (including case variations), so this class of mistake is trivially discovered.
- Even limited information disclosure or unintended actions available through these endpoints can have a high impact depending on the deployment.
Proof-of-concept (behavioral)
A request that uses a different case for the API prefix can avoid the conditional check and therefore avoid basicAuthMiddleware. The example below shows the change in path casing; it demonstrates the underlying issue but is shown here for defensive and testing purposes.
curl http://localhost:3000/Api/v1/credentials
Explanation: In a vulnerable deployment, hitting the endpoint with "Api" instead of "api" can result in the request bypassing the authentication gate because the middleware compares against a lowercase '/api/v1/' literal only.
Detecting exploitation and indicators
- Access logs showing requests to API paths with non-lowercase segments (e.g., "/Api/v1", "/API/V1") followed by successful 200 responses where authentication would normally be required.
- Audit logs showing requests that normally require auth being served without corresponding authentication events.
- Web application firewalls or IDS logs: look for requests containing case variations of the API prefix.
Example IDS regex to detect case-variant attempts:
(?i)\/api\/v1\/
Explanation: the (?i) flag makes the regular expression case-insensitive and will match any casing of "/api/v1/". Use this in log scanning or WAF rules to identify suspicious requests that attempt to target API endpoints with different casing.
Recommended fixes (code-level)
The safest approaches are to:
- Normalize request paths before performing comparisons (e.g., convert to lowercase).
- Prefer route-level middleware and Express routing instead of manual substring checks on req.url.
- Use strict matching (startsWith or exact match) rather than includes when possible to avoid accidental partial matches.
Here is a corrected middleware snippet that normalizes paths and compares in a case-insensitive, predictable way:
// Normalize the path and perform case-insensitive checks.
// Assumes `whitelistURLs` contains strings like '/api/v1/public'
this.app.use((req, res, next) => {
// Use req.path (preferred) and normalize to lowercase
const path = (req.path || req.url || '').toLowerCase()
if (path.includes('/api/v1/')) {
// Normalize whitelist entries once or compare lowercased
const allowed = whitelistURLs.some((url) => path.includes(url.toLowerCase()))
return allowed ? next() : basicAuthMiddleware(req, res, next)
}
return next()
})
Explanation: This corrected code converts the request path to lowercase and compares it to lowercase whitelist entries. That eliminates the case sensitivity issue. Using req.path is preferred because it excludes the query string; ensure your Express setup populates req.path as expected.
Better: use Express route mounting and built-in middleware placement so authentication applies consistently:
// Mount API router and protect it consistently
const apiRouter = express.Router()
// Attach basic auth to all api routes, unless the route explicitly permits public access
apiRouter.use((req, res, next) => basicAuthMiddleware(req, res, next))
// Define public endpoints before the auth middleware or mark them explicitly
apiRouter.get('/public-info', publicHandler)
// Mount secured router at '/api/v1' — Express routing is configurable for case sensitivity
this.app.use('/api/v1', apiRouter)
Explanation: Mounting routes under '/api/v1' and applying middleware at the router level reduces the risk of ad-hoc string checks introducing bypasses. Note that Express has a configuration option for case-sensitive routing; confirm the setting to ensure routing behavior aligns with your expectations.
Deployment and configuration mitigation
- Upgrade: apply the vendor's patch or upgrade to a fixed Flowise release. Check Flowise release notes and security advisories for the exact patched version.
- Temporary hardening: normalize paths in middleware (as above) or enforce authentication earlier in the request pipeline.
- Use a reverse proxy or WAF rule to normalize and/or enforce authentication headers on API prefixes.
- Harden logging and alerting for unexpected 200 responses to API endpoints without associated auth events.
Testing and verification
- After applying a fix, run automated tests that exercise path variants (different casing, trailing slashes, encoded segments) to ensure the authentication decision is consistent and correct.
- Use unit tests for middleware functions to ensure any normalization logic behaves as intended.
- Perform code review on any future string-based checks of URLs; prefer canonicalization and route-based control.
Responsible disclosure and timeline
When discovering such issues in third-party projects, follow responsible disclosure: report to the project maintainers (GitHub issue or security contact), allow time for a fix and release, and coordinate public disclosure with the vendor. Refer to CVE-2024-31621 for public details about this specific issue.
Best practices to avoid similar issues
- Prefer declarative route mounting and middleware in the web framework instead of ad-hoc string checks.
- Always canonicalize user-controlled input (paths, headers) before making security decisions.
- Unit test edge cases: different casings, encodings, trailing slashes, and path traversal patterns.
- Use defense-in-depth: enforce authentication at multiple layers (application middleware and reverse proxy/WAF).
Conclusion
This Flowise authentication bypass was caused by a simple but impactful case-sensitivity mistake in request URL checks. The fix is straightforward — normalize paths or use route-based middleware — but the lesson is broader: security decisions based on string comparisons must always account for canonicalization and framework routing behavior. Patch or upgrade affected deployments promptly and add tests and monitoring to prevent regressions.