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"