BUG-HUNT: [security] Template placeholders with whitespace bypass security validation #7090

Open
opened 2026-04-10 07:37:33 +00:00 by HAL9000 · 1 comment
Owner

Background and Context

The SecureTemplateRenderer in src/cleveragents/templates/secure_renderer.py uses regex-based security validation to detect and reject unsafe template patterns. A critical flaw exists in the interaction between _SAFE_PLACEHOLDER_RE and _UNSAFE_RE: template placeholders containing whitespace characters (space, tab, newline) fall into a validation gap — they are neither matched as safe nor explicitly rejected as unsafe.

This creates a potential obfuscation attack vector where a malicious actor could disguise unsafe template constructs using whitespace to bypass security checks, while the raw template is silently exposed to the caller.

Current Behavior (Bug)

Templates containing whitespace within placeholders — such as { name }, {name\t}, or {na\nme} — are not caught by _UNSAFE_RE and are not matched by _SAFE_PLACEHOLDER_RE. They pass through security validation without being blocked, but fail to render, leaving the raw template string exposed.

Expected Behavior

Templates containing whitespace characters (space \x20, tab \t, newline \n, carriage return \r) within {...} placeholder delimiters must be explicitly rejected with TemplateSecurityError to prevent whitespace-based obfuscation attacks.

Evidence

Testing revealed the following inconsistency:

renderer = SecureTemplateRenderer()

# These should raise TemplateSecurityError — but they do NOT:
renderer.render("{ name }", {"name": "Alice"})    # space in placeholder
renderer.render("{name\t}", {"name": "Alice"})    # tab in placeholder
renderer.render("{na\nme}", {"name": "Alice"})    # newline in placeholder

# These are correctly blocked:
renderer.render("{obj.attr}", {})                 # attribute access — blocked ✓
renderer.render("{fn()}", {})                     # function call — blocked ✓

Location:

  • File: src/cleveragents/templates/secure_renderer.py
  • Patterns: _SAFE_PLACEHOLDER_RE and _UNSAFE_RE
  • Approximate lines: ~60–85

Suggested Fix

Add explicit whitespace detection to _UNSAFE_RE:

r'\{[^}]*\s[^}]*\}',  # whitespace in placeholder: { name }, {name\t}, {na\nme}

This ensures any {...} construct containing whitespace is explicitly rejected before it can reach the rendering pipeline.

Acceptance Criteria

  • SecureTemplateRenderer.render("{ name }", ...) raises TemplateSecurityError
  • SecureTemplateRenderer.render("{name\t}", ...) raises TemplateSecurityError
  • SecureTemplateRenderer.render("{na\nme}", ...) raises TemplateSecurityError
  • SecureTemplateRenderer.render("{name}", {"name": "Alice"}) still renders correctly
  • All existing security validation tests continue to pass
  • All nox stages pass
  • Coverage ≥ 97%

Metadata

  • Branch: bugfix/m3-secure-renderer-whitespace-bypass
  • Commit Message: fix(templates): reject whitespace in placeholders to prevent security bypass
  • Milestone: v3.2.0
  • Parent Epic: #400

Subtasks

  • Write TDD issue-capture test (tagged @tdd_issue, @tdd_issue_<N>, @tdd_expected_fail) proving the bug exists
  • Add explicit whitespace detection pattern to _UNSAFE_RE in secure_renderer.py
  • Remove @tdd_expected_fail tag once fix is implemented
  • Update unit-level Behave scenarios for SecureTemplateRenderer whitespace rejection
  • Add integration-level Robot Framework test for whitespace bypass scenario
  • Verify all nox stages pass (lint, typecheck, security, unit_tests, coverage)
  • Update docs/ if any security model documentation references placeholder validation

Definition of Done

  • TemplateSecurityError is raised for all whitespace-in-placeholder patterns ({ name }, {name\t}, {na\nme}, {na\rme})
  • Valid placeholders ({name}, {user_id}) continue to render correctly
  • TDD test with @tdd_issue and @tdd_issue_<N> tags is present and permanent
  • @tdd_expected_fail tag removed from TDD test after fix
  • Behave BDD scenarios cover the new rejection cases
  • Robot Framework integration test covers the security bypass scenario
  • All nox stages pass
  • Coverage >= 97%

Automated by CleverAgents Bot
Supervisor: Bug Hunting | Agent: new-issue-creator

## Background and Context The `SecureTemplateRenderer` in `src/cleveragents/templates/secure_renderer.py` uses regex-based security validation to detect and reject unsafe template patterns. A critical flaw exists in the interaction between `_SAFE_PLACEHOLDER_RE` and `_UNSAFE_RE`: template placeholders containing whitespace characters (space, tab, newline) fall into a validation gap — they are neither matched as safe nor explicitly rejected as unsafe. This creates a potential obfuscation attack vector where a malicious actor could disguise unsafe template constructs using whitespace to bypass security checks, while the raw template is silently exposed to the caller. ## Current Behavior (Bug) Templates containing whitespace within placeholders — such as `{ name }`, `{name\t}`, or `{na\nme}` — are not caught by `_UNSAFE_RE` and are not matched by `_SAFE_PLACEHOLDER_RE`. They pass through security validation without being blocked, but fail to render, leaving the raw template string exposed. ## Expected Behavior Templates containing whitespace characters (space `\x20`, tab `\t`, newline `\n`, carriage return `\r`) within `{...}` placeholder delimiters must be explicitly rejected with `TemplateSecurityError` to prevent whitespace-based obfuscation attacks. ## Evidence Testing revealed the following inconsistency: ```python renderer = SecureTemplateRenderer() # These should raise TemplateSecurityError — but they do NOT: renderer.render("{ name }", {"name": "Alice"}) # space in placeholder renderer.render("{name\t}", {"name": "Alice"}) # tab in placeholder renderer.render("{na\nme}", {"name": "Alice"}) # newline in placeholder # These are correctly blocked: renderer.render("{obj.attr}", {}) # attribute access — blocked ✓ renderer.render("{fn()}", {}) # function call — blocked ✓ ``` **Location:** - File: `src/cleveragents/templates/secure_renderer.py` - Patterns: `_SAFE_PLACEHOLDER_RE` and `_UNSAFE_RE` - Approximate lines: ~60–85 ## Suggested Fix Add explicit whitespace detection to `_UNSAFE_RE`: ```python r'\{[^}]*\s[^}]*\}', # whitespace in placeholder: { name }, {name\t}, {na\nme} ``` This ensures any `{...}` construct containing whitespace is explicitly rejected before it can reach the rendering pipeline. ## Acceptance Criteria - `SecureTemplateRenderer.render("{ name }", ...)` raises `TemplateSecurityError` - `SecureTemplateRenderer.render("{name\t}", ...)` raises `TemplateSecurityError` - `SecureTemplateRenderer.render("{na\nme}", ...)` raises `TemplateSecurityError` - `SecureTemplateRenderer.render("{name}", {"name": "Alice"})` still renders correctly - All existing security validation tests continue to pass - All nox stages pass - Coverage ≥ 97% ## Metadata - **Branch**: `bugfix/m3-secure-renderer-whitespace-bypass` - **Commit Message**: `fix(templates): reject whitespace in placeholders to prevent security bypass` - **Milestone**: v3.2.0 - **Parent Epic**: #400 ## Subtasks - [ ] Write TDD issue-capture test (tagged `@tdd_issue`, `@tdd_issue_<N>`, `@tdd_expected_fail`) proving the bug exists - [ ] Add explicit whitespace detection pattern to `_UNSAFE_RE` in `secure_renderer.py` - [ ] Remove `@tdd_expected_fail` tag once fix is implemented - [ ] Update unit-level Behave scenarios for `SecureTemplateRenderer` whitespace rejection - [ ] Add integration-level Robot Framework test for whitespace bypass scenario - [ ] Verify all nox stages pass (lint, typecheck, security, unit_tests, coverage) - [ ] Update `docs/` if any security model documentation references placeholder validation ## Definition of Done - [ ] `TemplateSecurityError` is raised for all whitespace-in-placeholder patterns (`{ name }`, `{name\t}`, `{na\nme}`, `{na\rme}`) - [ ] Valid placeholders (`{name}`, `{user_id}`) continue to render correctly - [ ] TDD test with `@tdd_issue` and `@tdd_issue_<N>` tags is present and permanent - [ ] `@tdd_expected_fail` tag removed from TDD test after fix - [ ] Behave BDD scenarios cover the new rejection cases - [ ] Robot Framework integration test covers the security bypass scenario - [ ] All nox stages pass - [ ] Coverage >= 97% --- **Automated by CleverAgents Bot** Supervisor: Bug Hunting | Agent: new-issue-creator
HAL9000 added this to the v3.2.0 milestone 2026-04-10 07:37:48 +00:00
Author
Owner

Verified — Critical security bug: template placeholders with whitespace bypass security validation. MoSCoW: Must-have. Priority: Critical.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

✅ **Verified** — Critical security bug: template placeholders with whitespace bypass security validation. MoSCoW: Must-have. Priority: Critical. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#400 Epic: Post-MVP Security
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#7090
No description provided.