How Cal.com Rebuilt AppSec After Going Closed Source
How Cal.com consolidated noisy security tooling into one continuous, context-aware pull request security program with Gecko.
Gecko Security
An IDOR in the public variables API allows authenticated users to read project variables outside their authorized project scope.
The vulnerable handler (variables.handler.ts) directly queries VariablesRepository with a user-controlled projectId, instead of enforcing membership checks through VariablesService.
In enterprise/team setups with multiple projects, a regular member with variable:list scope can read variables from projects they do not belong to, including sensitive values.
This issue only affects licensed enterprise or team deployments with multiple projects and the variables feature enabled.
The vulnerable code path is the public API list endpoint in packages/cli/src/public-api/v1/handlers/variables/variables.handler.ts:
<code class="hljs language-typescript"><span class="hljs-keyword">const</span> [variables, count] = <span class="hljs-keyword">await</span> <span class="hljs-title class_">Container</span>.<span class="hljs-title function_">get</span>(<span class="hljs-title class_">VariablesRepository</span>).<span class="hljs-title function_">findAndCount</span>({
<span class="hljs-attr">skip</span>: offset,
<span class="hljs-attr">take</span>: limit,
<span class="hljs-attr">where</span>: {
<span class="hljs-attr">project</span>: projectId === <span class="hljs-string">'null'</span> ? <span class="hljs-title class_">IsNull</span>() : { <span class="hljs-attr">id</span>: projectId },
<span class="hljs-attr">value</span>: state === <span class="hljs-string">'empty'</span> ? <span class="hljs-string">''</span> : <span class="hljs-literal">undefined</span>,
},
<span class="hljs-attr">relations</span>: [<span class="hljs-string">'project'</span>],
});
</code>This path does not validate whether req.user has access to the requested project.
The internal enterprise controller uses the authorization-aware service path instead (variables.controller.ee.ts → variables.service.ee.ts), which filters by project membership (projectVariable:list scope).
The feature is license-gated via isLicensed(‘feat:variables’), so exploitability is limited to licensed editions.
The response model includes variable value (variable.yml), making this a confidentiality issue.
Project A (attacker is a member)Project B (attacker is not a member)Project Bvariable:list scope.<code class="hljs language-bash">curl -X GET <span class="hljs-string">'http://target:5678/api/v1/variables?projectId=PROJECT_B_ID'</span> \
-H <span class="hljs-string">'X-N8N-API-KEY: ATTACKER_MEMBER_API_KEY'</span>
</code>Project B are returned even though the attacker is not a member.This is a cross-project authorization bypass in the public API that leaks secrets across project boundaries.
Any authenticated low-privilege member with variable:list scope can read unauthorized project variables, including API keys, tokens, internal endpoints, and environment secrets stored in variables.
Exploitability conditions:
variable:list scopeIf variables were misused to store sensitive information such as credentials or tokens, they should be rotated immediately.
n8n (verified in: 2.7.4 and 2.9.2) CWE-639: Authorization Bypass Through User-Controlled Key (IDOR)

Artemiy Malyshau
Co-founder & CTO
Artemiy served in an elite unit of the Austrian Cyber Forces, defending national infrastructure He was then the first employee at a government-backed cybersecurity research group, where he led security projects for Interpol and national governments. At Gecko he builds the platform trusted to sit inside Fortune 500 codebases, and holds it to the standard those governments taught him.
The latest news, technologies, and resources from our team.
How Cal.com consolidated noisy security tooling into one continuous, context-aware pull request security program with Gecko.
Gecko Security
Authorization bypass in n8n’s dynamic-credentials OAuth endpoints allows any authenticated user to operate on another user’s OAuth credential by supplying its ID, enabling unauthorized OAuth rebinding and revocation.
Artemiy Malyshau
Learn API scanning for automated security testing. Find vulnerabilities from broken authentication to business logic flaws in your endpoints.
Artemiy Malyshau
A complete guide to automated pentest tools and best practices. Learn what works, what doesn’t, and how to implement continuous security testing.
Artemiy Malyshau
Compare the best AI-powered application security testing tools. Find which tools detect business logic flaws and broken access control.
Artemiy Malyshau
Compare the 14 best AI security tools. Features, pricing, and detailed comparisons to find vulnerabilities in code and secure AI systems.
Artemiy Malyshau
Occasional updates, new content, and insights. No spam; unsubscribe anytime.