Files
cleveragents-core/features/security_templates.feature
T
2026-02-25 10:06:27 +00:00

206 lines
9.1 KiB
Gherkin

Feature: Secure template rendering
As a security-conscious developer
I want templates to be sandboxed and validated
So that template injection attacks are prevented
Background:
Given a secure template test environment
# -- Safe rendering -------------------------------------------------------
Scenario: Render a simple placeholder
Given the secure template text "{greeting} {name}"
And a secure template context key "greeting" with value "Hello"
And a secure template context key "name" with value "World"
When I render the secure template
Then the secure template output should be "Hello World"
Scenario: Render with missing placeholder leaves it intact
Given the secure template text "Hello {name}, your role is {role}"
And a secure template context key "name" with value "Alice"
When I render the secure template
Then the secure template output should be "Hello Alice, your role is {role}"
Scenario: Render with empty context returns template as-is
Given the secure template text "No placeholders here"
When I render the secure template
Then the secure template output should be "No placeholders here"
Scenario: Render with numeric values converts to string
Given the secure template text "Count: {count}"
And a secure template context key "count" with value "42"
When I render the secure template
Then the secure template output should be "Count: 42"
# -- Security rejection ---------------------------------------------------
Scenario: Reject attribute access in template
Given the secure template text "{obj.__class__.__name__}"
When I render the secure template expecting a security error
Then the secure template error should mention "Unsafe"
Scenario: Reject index access in template
Given the secure template text "{items[0]}"
When I render the secure template expecting a security error
Then the secure template error should mention "Unsafe"
Scenario: Reject format spec in template
Given the secure template text "{value:>10}"
When I render the secure template expecting a security error
Then the secure template error should mention "Unsafe"
Scenario: Reject conversion flag in template
Given the secure template text "{value!r}"
When I render the secure template expecting a security error
Then the secure template error should mention "Unsafe"
Scenario: Reject function call in template
Given the secure template text "{fn()}"
When I render the secure template expecting a security error
Then the secure template error should mention "Unsafe"
Scenario: Reject Jinja2 expression delimiters
Given the secure template text "{{ config }}"
When I render the secure template expecting a security error
Then the secure template error should mention "Unsafe"
Scenario: Reject Jinja2 block delimiters
Given the secure template text "{% for x in items %}x{% endfor %}"
When I render the secure template expecting a security error
Then the secure template error should mention "Unsafe"
# -- Size limits -----------------------------------------------------------
Scenario: Reject template exceeding max length
Given a secure template that is 11000 characters long
When I render the secure template expecting a size error
Then the secure template error should mention "exceeds maximum"
Scenario: Reject output exceeding max length
Given the secure template text "{big}"
And a secure template config with max output length of 20
And a secure template context key "big" with value "This value is definitely longer than twenty characters"
When I render the secure template expecting a size error
Then the secure template error should mention "exceeds maximum"
# -- Allowlist enforcement ------------------------------------------------
Scenario: Reject template key not in allowlist
Given the secure template text "{name} {secret}"
And a secure template with allowed keys "name"
And a secure template context key "name" with value "Alice"
And a secure template context key "secret" with value "hidden"
When I render the secure template expecting a validation error
Then the secure template error should mention "disallowed"
Scenario: Accept template key that is in allowlist
Given the secure template text "{name}"
And a secure template with allowed keys "name"
And a secure template context key "name" with value "Alice"
When I render the secure template
Then the secure template output should be "Alice"
Scenario: Open allowlist allows any simple key
Given the secure template text "{anything}"
And the secure template has no key restrictions
And a secure template context key "anything" with value "works"
When I render the secure template
Then the secure template output should be "works"
# -- Pre-validation -------------------------------------------------------
Scenario: Validate clean template returns no errors
Given the secure template text "{name} {role}"
When I validate the secure template
Then the secure template validation should be empty
Scenario: Validate unsafe template returns errors
Given the secure template text "{obj.__class__}"
When I validate the secure template
Then the secure template validation should not be empty
And the secure template validation should mention "Unsafe"
Scenario: Validate template with unknown keys returns errors
Given the secure template text "{name} {secret}"
And a secure template with allowed keys "name"
When I validate the secure template
Then the secure template validation should not be empty
And the secure template validation should mention "Unknown"
Scenario: Validate oversized template returns errors
Given a secure template that is 11000 characters long
When I validate the secure template
Then the secure template validation should not be empty
And the secure template validation should mention "exceeds"
# -- Convenience function -------------------------------------------------
Scenario: render_template_secure convenience function works
Given the secure template text "{greeting}"
And a secure template context key "greeting" with value "Hi"
When I render via the secure convenience function
Then the secure template output should be "Hi"
Scenario: render_template_secure rejects unsafe input
Given the secure template text "{obj.attr}"
When I render via the secure convenience function expecting an error
Then the secure template error should mention "Unsafe"
# -- Config property access ------------------------------------------------
Scenario: Renderer exposes active configuration
Given a secure template with allowed keys "name"
When I create a renderer with those settings
Then the renderer config allowed keys should contain "name"
# -- Validate with matching allowlist (no unknown keys) -------------------
Scenario: Validate template where all keys match allowlist
Given the secure template text "{name}"
And a secure template with allowed keys "name"
When I validate the secure template
Then the secure template validation should be empty
# -- Rejected keys without logging ----------------------------------------
Scenario: Reject unknown key without logging when log_rejected is false
Given the secure template text "{name} {secret}"
And a secure template config with logging disabled
And a secure template context key "name" with value "Alice"
And a secure template context key "secret" with value "hidden"
When I render the secure template expecting a validation error
Then the secure template error should mention "disallowed"
# -- reject_unknown_keys=False path ----------------------------------------
Scenario: Allow unknown keys when reject_unknown_keys is disabled
Given the secure template text "{name} {extra}"
And a secure template config that permits unknown keys
And a secure template context key "name" with value "Alice"
And a secure template context key "extra" with value "data"
When I render the secure template
Then the secure template output should be "Alice data"
# -- Legacy renderer with config passthrough --------------------------------
Scenario: Legacy TemplateRenderer accepts config passthrough
Given the secure template text "{name}"
And a secure template with allowed keys "name"
And a secure template context key "name" with value "Carol"
When I render via the legacy TemplateRenderer with config
Then the secure template output should be "Carol"
# -- Legacy renderer backward compat --------------------------------------
Scenario: Legacy TemplateRenderer returns raw on unsafe template
Given the secure template text "{obj.__class__}"
And a secure template context key "obj" with value "test"
When I render via the legacy TemplateRenderer
Then the secure template output should be "{obj.__class__}"
Scenario: Legacy TemplateRenderer renders safe templates
Given the secure template text "{name}"
And a secure template context key "name" with value "Bob"
When I render via the legacy TemplateRenderer
Then the secure template output should be "Bob"