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

The code your AI assistant generates usually works, which is exactly why the security problems slip through. Securing AI-generated code requires different analysis than what traditional SAST tools provide because the vulnerabilities aren’t structural, they’re semantic. An endpoint that returns user data without checking ownership, an update function that skips authorization, a deletion route that doesn’t verify permissions all look syntactically correct. Your security tools need to understand execution paths across files and services, tracing whether authorization checks actually happen before sensitive operations run, beyond matching code patterns to known vulnerability signatures.
TLDR:
AI code assistants have changed how we build software, but they’ve introduced a real security gap. Veracode’s 2025 research found that 45% of AI-generated code samples fail security tests and introduce OWASP Top 10 vulnerabilities into production.
The problem isn’t functionality. Carnegie Mellon research showed that 60% of AI-generated features work correctly, but only 10% meet basic security standards. There’s a gap between code that runs and code that’s safe.
AI models learn from existing codebases that often contain the same flaws we’re trying to avoid. When you ask an assistant to build authentication or data access layers, it generates syntactically correct code that handles the happy path but misses authorization checks, input validation, and access controls.
Stanford researchers found another pattern: engineers using AI write less secure code but trust it more, which means vulnerabilities slip through review.
AI code generation breaks down at the business logic layer because these tools optimize for syntactic correctness, not security rules. When you prompt an assistant to build user data endpoints or resource updates, it produces functional code that handles the database interaction and response formatting. What gets left out are the authorization checks, ownership validations, and context-aware filtering that keep the feature secure.
The root cause is training data. LLMs learn from public repositories where broken access control and missing authorization patterns appear frequently. If half the training examples omit ownership verification, the model treats it as optional. The output compiles and runs, but it doesn’t enforce who can access what.
This gap expands with application context. AI can’t infer tenant isolation rules, role hierarchies, or resource-specific permissions without explicit instruction. You end up with features that work perfectly on the happy path but fail the moment a user manipulates a parameter or crosses an access boundary.
The confidence gap in AI-assisted coding creates more risk than the bugs themselves. Stanford researchers found that developers using AI assistants wrote less secure code than those coding manually while believing the opposite.
This is vibe coding: trusting that generated code feels right without verifying what it actually does. When an AI assistant produces clean, well-formatted code that handles your use case, the syntax validates, the logic flows naturally, and the feature works in testing.
The problem surfaces in production. The AI generated an endpoint that returns user data without checking ownership. It built an update function that skips permission validation. It created a deletion route that doesn’t verify the requester has rights to the resource.
Traditional SAST tools analyze code through abstract syntax trees (ASTs), which capture structural elements within individual files. Why static analysis struggles with business logic vulnerabilities becomes clear when you look at this approach. Pattern matching rules run against this tree to flag potential issues like SQL injection or XSS.
This approach works when the vulnerability exists in code structure. Business logic flaws are AppSec’s unsolved problem because they don’t conform to patterns. An authorization check isn’t missing because of syntax. The code is structurally correct but semantically wrong.
AST-based tools can’t answer the questions that matter: Does any path to this database query include an authorization check? Is user ownership validated before this resource gets modified? These are questions about meaning and relationships across files, services, and execution paths.
| Analysis Approach | Traditional SAST Tools | Gecko Security |
|---|---|---|
| Analysis Method | Abstract Syntax Tree (AST) parsing within individual files using pattern matching rules | Code Property Graph (CPG) with semantic understanding across repositories and services |
| Vulnerability Detection | Identifies structural vulnerabilities like SQL injection and XSS through code pattern matching | Traces execution paths to find missing authorization checks and business logic flaws |
| Cross-Service Analysis | Limited to single-file or single-repository scope; cannot trace calls across microservices | Maps API contracts, OpenAPI specs, and gRPC definitions to follow authorization context across service boundaries |
| AI-Generated Code Coverage | Misses semantically incorrect code that is syntactically valid; cannot detect missing security logic | Validates that authorization checks exist in execution paths before sensitive operations run |
| False Positive Rate | High false positive rates from pattern-based alerts that lack business context | 50% fewer false positives through semantic reasoning and proof-of-concept exploit generation |
| Broken Access Control Detection | Cannot verify if authorization happens across call chains or identify ownership validation gaps | Models application-specific threats and tests whether endpoints enforce documented security models |
Broken Access Control holds the number one spot in OWASP’s 2025 Top 10, with 100% of tested applications showing some form of this vulnerability. The category sat at fifth place in 2017, climbed to first by 2021, and hasn’t moved since.
Injection attacks dropped from first to fifth over the same period while broken access control went the opposite direction. Injection vulnerabilities got solved through framework defaults, parameterized queries, and ORM protections. Authorization flaws have no equivalent fix.
The gap widens in the AI coding era. Every time an assistant generates an endpoint without explicit security instructions, it produces working code that bypasses authorization, similar to Cal.com’s broken access control vulnerability. Models don’t infer ownership checks because these patterns don’t exist consistently in training data. Teams ship features faster while introducing the vulnerability class that already affects every tested application.
Security governance for AI coding tools starts with defining boundaries. Some code categories should never be AI-generated. Authentication systems, authorization frameworks, and cryptographic implementations require human expertise because mistakes create systemic vulnerabilities that affect every user and every transaction.
Draw clear lines around what assistants can and cannot generate. API endpoint scaffolding might be acceptable with proper review. Permission checks and access control logic should be written by engineers who understand your threat model. The distinction matters because AI tools inherit patterns from training data that often lack security context.
Set specification requirements before generation. If a developer uses an AI assistant to build a feature that touches user data or crosses trust boundaries, require them to document intended authorization rules, data access constraints, and validation requirements first. The specification becomes the security baseline that generated code must satisfy.
Review processes need adjustment. Code that an AI produced requires different scrutiny than human-written code. Reviewers should verify that authorization checks exist, that they’re placed correctly in the execution path, and that they enforce the documented security model. Your policies need to adapt as AI capabilities change and new vulnerability patterns appear.
Semantic analysis moves beyond parsing structure to understanding code meaning. Code Property Graphs (CPGs) preserve relationships between functions, types, and data flows across files and repositories. While ASTs capture syntax trees within single files, CPGs map how components connect and execution flows through call chains.
This contextual model answers questions pattern matching cannot. Does this endpoint check authorization before querying data? Where does user input flow across service boundaries? Is ownership validated in the execution path?
Language server integration provides the foundation, creating an accurate map of code behavior that security analysis can reason about.
Threat modeling AI-generated code starts with identifying where generated functions touch sensitive operations. Map trust boundaries first: authentication gateways, data access layers, inter-service communication points, and user input handlers. AI assistants frequently write code at these boundaries while omitting required security controls.
Trace data flows to find authorization gaps and RCE vulnerabilities that scanners miss. Which execution paths validate user context before database queries? Does ownership verification happen at every step? AI-generated code often handles data movement correctly while skipping the logic that should gate each operation.
Model attack scenarios based on real business logic. What happens if a user manipulates an ID parameter? Can role restrictions be bypassed through alternate endpoints?
Verification needs to happen at the same speed code gets generated. When developers accept AI-generated code, security testing should run before merge, catching vulnerabilities when they’re easiest to fix.
Pull request integration creates the first checkpoint. Run security scans against every change that touches authentication, authorization, or data access layers. Flag any execution path that reaches sensitive operations without proper checks.
Proof-of-concept generation separates real vulnerabilities from theoretical concerns. Automated exploit building validates that a finding is exploitable, beyond mere suspicion. If the scanner can’t prove the vulnerability exists, developers won’t trust the alert. Context-aware analysis that understands business logic produces findings that matter instead of pattern-match noise, like how Gecko found 30 0-day vulnerabilities other tools missed.
Microservice architectures multiply authorization complexity because trust boundaries fragment across service edges. AI-generated code compounds this by creating endpoints in one service that call data layers in another, often without passing authentication context between them.
The user gets validated at the API gateway, but the downstream service handling database access assumes the request is authorized and skips its own checks. Each service looks secure in isolation. The vulnerability exists in the gap.
Cross-repository analysis traces these execution paths by parsing API contracts, OpenAPI specs, and gRPC definitions to map how services communicate. Security analysis must follow call chains through HTTP clients to REST endpoints, from message publishers to subscribers, across every boundary where user context could be dropped or authorization skipped.
Gecko’s compiler-accurate indexer builds a semantic graph that maps execution paths across files and services, answering questions AST-based tools can’t: Does this endpoint validate ownership? Is authorization enforced at every call chain step?
We model threats specific to your application’s business logic, test scenarios to find exploitable vulnerabilities, and build proof-of-concept exploits to validate findings. This approach catches multi-step vulnerability chains and missing authorization checks that appear frequently in AI-generated code.
The result is 50% fewer false positives because we reason about what code should do based on semantic understanding, not pattern matching.
Every AI-generated endpoint represents a potential authorization bypass unless you verify the security controls exist. Analysis tools that understand business logic can answer the questions that matter: does this code check ownership, does it validate permissions, does it enforce your security model. Securing AI generated code becomes practical when verification happens automatically and proves vulnerabilities instead of guessing at them.

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
An IDOR vulnerability in n8n’s public variables API allows authenticated users to read project variables outside their authorized scope, exposing secrets across project boundaries.
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
Occasional updates, new content, and insights. No spam; unsubscribe anytime.