# Codegen schema injection

Untrusted schema or CI values interpolated unescaped into generated source, executing on import or call

_Area: Software supply chain and CI/CD. Seen in 7 disclosed reports; latest 2026-10-09. Updated 2026-10-24._

## How it works
A code generator treats schema and environment values as inert data, but emits them into source positions where they become live code. The generator's escaping is either absent or conditional, so a value containing a quote, backtick, `${`, backslash or newline closes the surrounding literal and the rest is parsed as code. The generated client then runs the payload when a consumer imports it or calls a method.

## Where it shows up
- Template engines with raw interpolation tags (`<%~ %>`, `!{}`) inside backtick or quoted literals [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-w284-33mx-6g9v.md)[E5](https://bugbountylibrary.com/r/ghsa%3AGHSA-38c3-wv3c-v3xj.md)[E6](https://bugbountylibrary.com/r/ghsa%3AGHSA-hqj5-cw9f-rx67.md)
- String-wrapping helpers that add quotes but never escape the content (`"${content}"`) [E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-5f94-x226-ccpm.md)
- Path/route rewriting that substitutes params but leaves backticks, `${` and backslashes intact [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-w284-33mx-6g9v.md)
- Schema extensions (`x-python-import`, `customTypePath`, `x-python-type`) rendered verbatim into imports or annotations [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-5578-w22f-pfx9.md)[E7](https://bugbountylibrary.com/r/ghsa%3AGHSA-m34r-v34r-rf9q.md)
- CI-derived values (branch refs from `VERCEL_GIT_COMMIT_REF`/`GITHUB_BRANCH`) flowing into generated config [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-pwhx-cvv3-qj5c.md)
- Sinks in class bodies, object literals or enum bodies, not just statement context [E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-5f94-x226-ccpm.md)[E5](https://bugbountylibrary.com/r/ghsa%3AGHSA-38c3-wv3c-v3xj.md)[E6](https://bugbountylibrary.com/r/ghsa%3AGHSA-hqj5-cw9f-rx67.md)

## How to review
Trace every schema- or environment-controlled value to its template sink. The invariant: any value emitted into generated source must be encoded for the exact syntactic position it lands in (string literal, identifier, import path, object key), or rejected if it does not match that grammar. Check that the escaping helper is actually applied on each path, not just defined. Confirm the sink's context: a quote in a class field initializer, enum body or computed object key still yields execution [E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-5f94-x226-ccpm.md)[E5](https://bugbountylibrary.com/r/ghsa%3AGHSA-38c3-wv3c-v3xj.md)[E6](https://bugbountylibrary.com/r/ghsa%3AGHSA-hqj5-cw9f-rx67.md). For import/annotation sinks, validate values as legal identifiers or dotted paths, rejecting newlines and brackets [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-5578-w22f-pfx9.md)[E7](https://bugbountylibrary.com/r/ghsa%3AGHSA-m34r-v34r-rf9q.md).

## Variants seen
- Route path strings into template literals in method bodies [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-w284-33mx-6g9v.md)
- Newlines in import extensions breaking out of `from X import Y` [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-5578-w22f-pfx9.md)
- Branch name with a quote closing a config string [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-pwhx-cvv3-qj5c.md)
- Enum string values closing a quoted literal [E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-5f94-x226-ccpm.md)
- `servers[0].url` into axios object literal via computed key [E5](https://bugbountylibrary.com/r/ghsa%3AGHSA-38c3-wv3c-v3xj.md)
- Same URL into a fetch class-body field, executing on bare import [E6](https://bugbountylibrary.com/r/ghsa%3AGHSA-hqj5-cw9f-rx67.md)
- `x-python-type` bypassing a position-dependent sanitiser by placing `[` early [E7](https://bugbountylibrary.com/r/ghsa%3AGHSA-m34r-v34r-rf9q.md)

## Why fixes fail
E2 shows a hardening release that fixed sibling sinks (`x-python-type`, `default_factory`, validators) but left other extensions reaching the same import renderer. E7 shows a sanitiser whose condition depends on delimiter position, skipped by moving the other delimiter earlier. Fixing one call site or one field leaves the shared sink reachable.

## Impact and severity
Attacker code executes in the consumer's build or at import/call time, giving supply-chain reach into every project using the generator. Severity is high: a malicious published spec or PR branch is enough, and execution can occur on bare import [E6](https://bugbountylibrary.com/r/ghsa%3AGHSA-hqj5-cw9f-rx67.md) or first method call [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-w284-33mx-6g9v.md). Worse where the generator is a widely used npm/Python package and where CI branch values are attacker-influenced [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-pwhx-cvv3-qj5c.md).

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-w284-33mx-6g9v.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-5578-w22f-pfx9.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-pwhx-cvv3-qj5c.md
- E4: https://bugbountylibrary.com/r/ghsa%3AGHSA-5f94-x226-ccpm.md
- E5: https://bugbountylibrary.com/r/ghsa%3AGHSA-38c3-wv3c-v3xj.md
- E6: https://bugbountylibrary.com/r/ghsa%3AGHSA-hqj5-cw9f-rx67.md
- E7: https://bugbountylibrary.com/r/ghsa%3AGHSA-m34r-v34r-rf9q.md
