Case study
Case study: an n8n webhook opened administrator accounts
On a French online training platform, an unauthenticated n8n webhook bypassed disabled sign-up and led to administrator access in under two minutes. Here is the chain, what held up, the fixes and the lesson for AI agents.
By Florian Bonamy · Updated 2026-10-29
Key facts
| Indicator | Value |
|---|---|
| Type of target | French online training platform (very small business), invitation only, with a single-page app, Supabase and an n8n server |
| Entry point | Account-creation n8n webhook with no authentication, whose address sat in a public JavaScript file |
| Impact | Creation of an account at the chosen access level, then escalation to administrator: access to profiles, coaching sessions, purchases and login logs |
| Findings | 4: 1 critical, 3 medium |
| Time to exploit | Under two minutes for a motivated attacker (estimate, chain not run end to end) |
| What held up | Read access locked down, inserts blocked, signature verified on the payment webhook, n8n REST API protected |
| Fix priority | Immediate: authenticate every n8n webhook and add UPDATE and DELETE RLS policies |
Context: what happened on this training platform?
A French online training platform (a very small business), open by invitation only, had an external audit in early 2026. The finding fits in one sentence: a plain n8n webhook, callable by anyone, let a visitor create accounts with the access level of their choice even though public sign-up was disabled.
The platform combined three common building blocks: a single-page web app, a Supabase backend (Postgres database, authentication, generated APIs) and an n8n server that automated admin tasks such as account creation. The team had disabled public sign-up, checked read access to the data and secured payments. On paper the platform was closed. In practice, a side door built for the administrator's convenience bypassed all of those protections.
This case study is anonymized. We do not name the client, its product or its hosting, and we publish nothing that would let anyone reproduce the attack.
Scope and authorization: under what conditions did the audit take place?
The audit was an authorized, paid, read-only engagement run from the outside, with the viewpoint of a visitor or attacker without an account. No account was created and no data was modified.
These are the rules we apply to this kind of engagement:
- Only publicly served resources were analyzed: pages, JavaScript files, API responses.
- The account-creation endpoint was not called. The proof of concept relied on reading the code sent to the browser.
- A single webhook received an empty request, to confirm that it answered without authentication. That action is recorded in the report.
- No personal data was downloaded or kept. Tests stop at confirming that data is readable.
- Temporary files were deleted at the end of the engagement.
This discipline matters as much as the finding. A report must prove the risk without carrying it out.
What we found: four findings, one of them critical
The critical finding is an account-creation webhook with no authentication at all, whose address was written in the site's code. Three medium-severity findings made it worse.
- Critical: unauthenticated account creation. The admin interface sends the future user's details (address, name, password, access level) to an n8n webhook. No authentication header, no token. The webhook address sat in a JavaScript file that any visitor could download.
- Medium: missing security rules for updates and deletions. At database level, row-level security (RLS) policies blocked inserts, but no policy covered updates or deletions.
- Medium: three publicly callable n8n webhooks. All their addresses were present in the site's code. A test with an empty request confirmed that a workflow started without any check.
- Medium: n8n server directly exposed to the internet. The server was up to date at the time of the audit, but an automation instance reachable from anywhere remains a permanent attack surface.
The first finding is the one that hurts. The other three explain why it became so serious.
The attack chain: how do you go from anonymous visitor to administrator?
The chain has three conceptual steps and, based on our analysis, takes under two minutes for a motivated attacker. We did not run it end to end, out of respect for the read-only rule, but each link was checked separately.
- Discovery. The admin interface code, served publicly, contains the webhook address and the exact shape of the data it expects. Reading that code is enough.
- Creation of a privileged account. The webhook accepts the request without checking who sent it. The attacker chooses the access level, including the highest one in the product. With public sign-up disabled, this webhook becomes the only way in, and it is wide open.
- Privilege escalation. Once logged in, the user can change their own rights. The roles table had no UPDATE RLS policy: the database accepted the request without a security error. The account becomes an administrator, with access to profiles, coaching sessions, purchases and login logs.
None of these links is sophisticated. Their combination is what produces a complete takeover. Any team would reasonably have rated finding 2 as medium in isolation, which is exactly why an audit must chain findings instead of listing them.
What held up: which controls worked well?
Several protections were correctly in place, and the report says so, because an honest audit also describes what resists.
- Read access to data was locked down. The vast majority of tables returned an empty result to an anonymous visitor. The usual workarounds (GraphQL queries, joins through the API) got nowhere.
- Inserts were blocked on all tables.
- The payment provider's webhook verified the signature of incoming calls. That is the right model, and the contrast is striking: on the same n8n server, one webhook was protected and another was not.
- The n8n REST API was protected: every unauthenticated request was refused.
- Email sign-in links and password reset revealed nothing exploitable, and no payment secret appeared in the site's code.
These points show a team that cares. The flaw comes from a blind spot: internal automations were not treated as an attack surface.
Fixes: what do we recommend to a small business?
The fixes are cheap and take a few hours to a few days. We ranked them by urgency.
Immediate
- Authenticate every n8n webhook with a secret that only the application's server knows. n8n offers native authentication methods on the Webhook node.
- Add UPDATE and DELETE RLS policies on all tables, starting with the roles table.
This week
- Move admin operations server-side (a server function or Edge Function that verifies the administrator's identity) so the browser never calls the webhook directly.
- Remove webhook addresses and any secret from the code sent to the browser.
- Restrict network access to the n8n server (VPN, allowlist) so it is no longer publicly exposed.
This month
- Apply least privilege: a logged-in user must not be able to change their own role or rights.
- Review the RLS policies for authenticated accounts, not only for anonymous visitors.
What this changes for an AI agent: why this case study concerns us
An n8n workflow or webhook is exactly the kind of tool an AI agent calls. If access control is missing on that entry point, the same flaw becomes an action an agent can trigger, including under the influence of malicious text.
Here, a human read the code to find the webhook. Replace that human with an agent wired to its tools through function calling or an MCP server. The agent receives an email, a document or a web page containing hidden instructions (indirect prompt injection). Among its tools is "create a user", connected to an open webhook. No human validates the action, and no authentication separates the legitimate request from the injected one. This is the scenario OWASP calls excessive agency (LLM06 in the Top 10 for LLM Applications 2025).
Three lessons carry over directly:
- The security barrier must live outside the agent. Rules written in a prompt are soft. The decision to allow an action must live in the system that executes it, with authentication, a narrow scope and logging.
- Every tool of an agent is an attack surface. The MCP server, webhook or workflow must verify the caller and the right to act, just as a publicly exposed API would.
- Chains matter more than isolated findings. A permissive tool, an overly open database and an injected instruction are enough to produce an incident.
To go further, read our page on AI agent security, the one on MCP security and our approach to AI agent red teaming. The Agent Red Team Express offer applies this chain logic to your agent in five days.
Result: what did the client get?
The client received a full report, an executive summary with priorities for today, this week and this month, and the list of controls that worked. The critical findings were presented with their exploitation chain so that the fix targets the cause (missing access control) and the visible symptom (an exposed address).
The takeaway for any team automating with n8n, Make or Zapier: inventory every webhook, check who can call it, and treat automation as a public API. If an AI agent relies on those automations, this work becomes your agent's first line of defense.
Further reading
What happened next: the re-test
We came back to this platform a few weeks later for a second authorized penetration test, from the same vantage point: an anonymous external attacker with no account, registration still disabled. The question was direct: does the fix for the critical flaw hold, and what was left open elsewhere?
What was fixed. Unauthenticated account creation, the entry point of the whole chain, is gone. The webhook addresses no longer appear in the JavaScript served to visitors, and account creation now goes through a server-side function that checks the caller's identity and role before acting. The missing row-level security policies for updates and deletions are in place too: an anonymous attempt to change or delete a row no longer affects anything. Reading training content, previously partly open, now returns empty results. The schema exposed by the API was largely hidden, with a remainder on the generic query side.
What remained. The re-test closed with zero critical findings, one high, eight medium and five low. The high finding fits in one sentence: the browser extension offered to the public embedded the addresses of three automation webhooks with no authentication. Anyone could use paid features for free, at the expense of the owner who pays the usage costs, and trigger sign-in emails. The fix had been applied to the website, but not to this second surface.
The medium findings are platform hygiene: insufficient throttling of login and verification attempts, paid content reachable through a public link, anonymous writes possible into an error log, a bypassable origin check on video delivery, missing security headers, and public client registration on the automation server. Nine further leads tied to business logic could not be confirmed without an account.
The lesson. Fixing a flaw closes one door. The re-test showed that the same design mistake, automations callable by anyone, persisted elsewhere in another form. The same reflex applies to AI agents: every tool, webhook and extension is an entry point that must be authenticated. We recommend a full inventory of entry points after any fix, followed by a new test. See also the Agent Red Team Express.
Other case studies
Frequently asked questions
Is an n8n webhook secure by default?
No. An n8n webhook with no authentication method configured answers any request that knows its address. n8n offers authentication options on the Webhook node (header, basic auth, JWT). You have to enable them and never rely on a secret URL alone, especially when it appears in the code sent to the browser.
Why did disabling sign-up not protect the platform?
Disabling public sign-up closes the official front door. The account-creation webhook took another path that created users directly. A protection is only worth what the weakest path to the same action is worth, so every path has to be controlled.
What is an UPDATE RLS policy and why does it matter?
A Supabase RLS (Row Level Security) policy defines which rows a user can read, insert, update or delete. A table with a read policy but no update policy can let a logged-in user change their own rights. That is what allowed the jump from a standard account to an administrator account here.
Did the audit involve actually attacking the platform?
The audit was authorized, external and read-only. No account was created, no data was modified or downloaded, and the account-creation endpoint was not called. The proof rests on reading public code and on non-destructive tests.
How does this relate to AI agents?
An AI agent calls tools: webhooks, n8n workflows, MCP servers. If one of them does not authenticate the caller, malicious text read by the agent can trigger the same action as a human attacker. Access control must therefore exist on the tool side, with human approval for sensitive actions.
How can I get my automations and AI agent tested?
An AI agent red team examines the agent, its tools, its MCP connections and its automations, then delivers a report with evidence and priorities. The first contact is a free 30-minute discovery call. The Agent Red Team Express offer covers one agent in five days.
Related reading
- n8n webhooks: exposed URLs, workflows anyone can triggerAn n8n webhook URL in your JavaScript is enough to trigger a workflow without an account, even to create admins. Exploitation, testing, authentication.
- RLS mistakes: the 2026 guide for Supabase and PostgreSQLIncomplete policies, missing WITH CHECK, stale JWTs, exposed service_role keys, views and functions that bypass RLS: the mistakes and how to test them.
- Function Calling: The AI Agent Attack SurfaceFunction calling and AI agents: five families of tool attacks, safer tool design and a testing protocol to limit unauthorized actions.
- API and Webhook Security Guide 2026BOLA, object properties, business flows and unsigned webhooks: the API mistakes that expose data, how to test them, and what AI agents change.
- E-commerce: privilege escalation and order flawsRoles set at sign-up, other customers' orders, editable prices and stock, public WooCommerce exports: e-commerce flaws and how to test them.
- MCP Connected to a Database: What to Lock DownAn MCP server wired to your database inherits its account's rights. Risks, account hardening, server audit points and a step-by-step testing protocol.