System prompt concatenates unbounded user content

ID

unbounded-user-content-in-system-prompt

Severity

high

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

OWASP LLM

LLM01:2025 — Prompt Injection

Family

LLM01 — Prompt Injection

Asset kind

ai_prompt

Red-team vectors

Prompt Injection, Jailbreaks

Tags

ai_security

Description

A role=system prompt that string-concatenates a user-controlled variable directly into its body — with no role separation, delimiter, or input guardrail — lets attacker-supplied text override the system instructions. This is the canonical prompt-injection exposure (OWASP LLM01).

This detector raises a finding when a system-role message interpolates a user-controlled variable (an f-string / format placeholder such as {user_input}, or a "…​" + user_input concatenation) within the same construction window.

This is the deterministic FilePattern half of the detection. The AST half (true f-string / template analysis) and the "no outgoing edge to an ai_guardrail`" cross-asset condition land with the AST framework and the in-memory asset graph in later slices; together they remove the residual false positives this content heuristic accepts. A template-escaped placeholder ({{user_input}}`) is deliberately not matched.

Examples

messages = [
  {"role": "system", "content": f"You are a helpful assistant. User says: {user_input}"}, (1)
]
openai.chat.completions.create(model="gpt-4o", messages=messages)
1 User-controlled {user_input} is concatenated straight into the system role, so a hostile input can rewrite the agent’s instructions.

Mitigation / Fix

messages = [
  {"role": "system", "content": "You are a helpful assistant."}, (1)
  {"role": "user", "content": user_input},                        (2)
]
guarded = llm_guard.scan_prompt(user_input)                       (3)
1 Keep the system role free of user input.
2 Pass user content as a separate user-role message (role separation).
3 Add an input guardrail before the model call to detect a hostile prompt.