Shadow Code: an AI built the backdoor. Another AI found it.

A critical stored SQL injection, CVSS 8.8, discovered inside four complete internal codebases that an employee had published to a personal public GitHub repository. We were given one input: the company name.

A swarm of clay security agents mapping paths around a central system
Four codebases outside the wall, and one thread leading back in.

This story does not start with a vulnerability. It starts with a developer doing exactly what the AI ecosystem encourages him to do.

1Company name given
4Internal codebases exposed
8.8Critical SQLi CVSS

The opening

A senior product leader at a global B2B payments company built an MCP server — a Model Context Protocol integration — so an AI assistant could understand the company’s billing system: query invoice statuses, look up payment flows, the kind of tool that makes you more productive.

To give the AI enough context to be useful, he pushed source code into a docs/ directory in the project repository. Not snippets. Not sanitized samples. Four complete internal codebases — the core backend API, the internal admin panel, the customer dashboard, and the accounting integration — all sitting in a public repository on a personal GitHub account. The commits were co-authored with an AI coding assistant. Weeks of work.

Nobody noticed. The company’s security program did not catch it — not because the controls failed, but because none of them applied. This code never entered the corporate pipeline. No SAST. No code review. No branch protection. No secret scanning. The gates were all in place. The code walked around every one of them.

The discovery chain

The engagement reproduced the entire kill chain an external adversary would walk, from OSINT to confirmed exploitation, across four phases.

The path, walked4 phases
  1. Company name — the only input.
  2. Employee account — attributed through public correlation.
  3. Four codebases — found in a personal public repository.
  4. Operator gate — analysis paused for human scope review and approval.
  5. Timezone SQLi — identified in source.
  6. 10.1-second delta — proven live in sandbox.

Phase 1 — reconnaissance and attribution

The EASM agent began where a sophisticated attacker would: searching GitHub for employees who write code outside work. It surfaced the account through keyword and organisational correlation, finding three public repositories all related to the billing platform, then cross-referenced the profile against LinkedIn and confirmed the owner as a product leader at the target.

The repository contained, under a docs/ directory, complete copies of four internal codebases — the running source of the platform, not documentation.

Phase 2 — operator-gated deep source analysis

This is the part that distinguishes a responsible AI agent from a scanner. The agent did not immediately start exploiting. It flagged the sensitivity of what it had found — full deployable production source, not documentation — and requested operator approval before performing a deep scan. The operator reviewed the repository, confirmed scope, and approved.

Clay security agents paused around a system, representing a human approval gate
Fig. 1 — The gate. Everything waits until a person says continue.

With approval, the agent read the four codebases in a single pass and found what an attacker would have been looking for: user input interpolated straight into SQL, in a field every tenant can edit.

The hero finding

The time_zone field is interpolated directly into a SET time_zone statement with no parameterisation. An attacker with settings_edit permission injects through the company update endpoint.

Evidence · Stored payloadSandbox only
PATCH /companies/[redacted] · host: api.sandbox.[redacted] {"time_zone":"UTC'; DO SLEEP(10); -- "} Fires on every subsequent POST /reports — any user, integration, or scheduled job.

The payload is stored. A single malicious request poisons all future report generation across the whole tenant until the field is manually reset. DO SLEEP(10) rather than SELECT SLEEP(10) is the craftsmanship detail: SELECT would fail in the driver’s statement-execution context because it returns a result set.

Report response timeMilliseconds
Baseline — 697 ms After injection — 10,822 ms Next report — 10,818 ms Third report — 10,794 ms After cleanup — 696 ms

Persistence held across consecutive report requests and returned to baseline after cleanup. The measured delta was 10,125 ms — exactly SLEEP(10).

The supporting findings

Stored SQLi via timezone

Live-confirmed and persistent; fires for every user in the tenant.

Critical 8.8
Source-code exposure

Four codebases in a personal public repository turned a black-box engagement into a white-box audit.

High
Unauthenticated cross-tenant file download

Object retrieval with zero authentication, serving invoices, receipts, and tax documents across tenants.

High 9.0
SSRF via file-upload API

Fetches arbitrary URLs — enabling internal scanning, cloud metadata access, and a path to an admin secret.

High 9.1
Phantom organisation takeover

An unowned organisation under a former company name. We claimed it, exposing a supply-chain vector across eight repositories and seven packages.

High
Open redirect via base64 URL

Phishing from a trusted billing domain that bypasses email link scanners.

Medium 7.4

Root cause

Not a single bug — a governance gap. The vulnerabilities lived in code that was never supposed to be public, exposed by an employee using personal tooling and AI assistants outside any corporate control. No enterprise GitHub policy, secret scanning, or acceptable-use rule prevented the publication. The injection, the IDOR, and the SSRF were latent for as long as the code existed; the leak simply handed an attacker the map.

Clay security agents tracing an exposed route toward a system
Fig. 2 — The door was always there. The leak was the map to it.

Your security perimeter ends where your employees’ personal accounts begin — and attackers know it.

What was, and was not, done

Live-confirmed: the SQL injection against sandbox only, the source-code exposure, and the phantom-organisation takeover. The IDOR, SSRF, and open redirect were documented from source with full root-cause analysis for the client’s internal validation, not exploited against production. No data was read, modified, or exfiltrated. Critical and high findings were reported immediately for revocation and rotation, ahead of the consolidated report.

Company, employee, host, repository, and tenant identifiers remain anonymised. This account is published with client consent.

What this teaches

SAST, code review, and branch protection are worthless against code that never enters the pipeline.

AI-assisted development multiplies exposure. “Give the AI context” is becoming a normal instinct, and it routinely means pushing real source code somewhere it does not belong.

An AI agent that pauses for a human is the responsible model. The operator-approval gate before the deep scan is what separates an autonomous security agent from an autonomous attacker.

The same AI capability that built the exposure can find it. Our agent walked from a single company name to a confirmed critical bug with no insider access.

One company name is all an attacker needs to start.

Find out what ours turns up about you. Scoping starts with a call, then Cylent follows the evidence under an operator-controlled engagement.

Get a POC