AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Twig Audit

skill-trebormc-drupal-ai-agents-twig-audit · by trebormc

>-

No reviews yet
0 installs
11 views
0.0% view→install

Install

$ agentstack add skill-trebormc-drupal-ai-agents-twig-audit

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-trebormc-drupal-ai-agents-twig-audit)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Twig Audit? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Twig Audit

Principle: Twig is for presentation ONLY. Preprocess handles logic.

Audit Workflow

  1. Run the detection greps below on the theme/module templates.
  2. Read EVERY flagged template in full (grep hits need context to confirm).
  3. Classify each confirmed hit against the anti-pattern list (severity: drilling/raw = CRITICAL, logic/isolation = HIGH, attributes = MEDIUM).
  4. Produce the report using the Audit Report Format at the end.

Detection Commands

Replace TPL with the templates directory, e.g. $DDEV_DOCROOT/themes/custom/*/templates/:

# Anti-pattern 1: render array drilling — matches content.field_x[0]['#markup'] and ['#items']
grep -rn "\[.['\"]#" TPL ; grep -rn "\['#" TPL

# Anti-pattern 2: business logic — comparisons/calculations on .value inside if/set
grep -rnE "\{% *(if|set) .*\.value" TPL

# Anti-pattern 3: raw filter usage — every hit must be justified
grep -rn "|raw" TPL

# Anti-pattern 4: non-isolated includes — check each hit for "with_context = false" or "only"
grep -rn "include(" TPL ; grep -rn "{% embed" TPL

# Anti-pattern 6: direct entity access bypassing the render system
grep -rn "\.entity\." TPL

# Anti-pattern 7: attributes built as strings
grep -rnE "class=\"[^\"]*\{\{" TPL

A grep hit is a CANDIDATE, not a confirmed issue — always read the template before reporting.

Anti-Patterns to Detect

1. Render Array Drilling (CRITICAL — Breaks Cache)

{# BAD — loses cache metadata, security risk #}
{{ content.field_image[0]['#markup'] }}
{{ content.field_body['#items'][0]['value'] }}

{# GOOD #}
{{ content.field_image }}
{{ content.body }}

2. Business Logic in Templates

{# BAD #}
{% if user.field_role.value == 'premium' and user.field_expiration.value|date('U') > 'now'|date('U') %}
  {% set discount = product.price.value * 0.2 %}

{# GOOD — variable from preprocess #}
{% if has_premium_discount %}
  {{ formatted_discounted_price }}

3. Unsafe |raw Usage

{# BAD — XSS vulnerability #}
{{ node.field_user_content.value|raw }}

{# GOOD — use processed field #}
{{ content.field_user_content }}

4. Missing Component Isolation

{# BAD — variable contamination #}
{{ include('mytheme:card', {heading: title}) }}

{# GOOD #}
{{ include('mytheme:card', {heading: title}, with_context = false) }}
{% embed 'mytheme:card' with {heading: title} only %}

Use include (+ with_context = false) when only passing simple values; use embed (+ only) when the component has blocks/slots to fill. Both isolate the component from the parent template's variables.

5. Content Not Rendered (Loses Cache Metadata)

{# BAD — cache metadata lost #}
{{ label }}
{{ content.body }}

{# GOOD — render remaining with without #}
{{ label }}
{{ content.body }}
{{ content|without('body') }}

6. Direct Entity Access (Bypasses Render System)

{# BAD — bypasses formatters and cache #}
{{ file_url(node.field_image.entity.uri.value) }}

{# GOOD — render the field properly #}
{{ content.field_image }}

{# Or if you need just the URL, use preprocess #}
{{ image_url }}

7. Attributes as Strings

{# BAD #}

{# GOOD #}
{% set classes = ['node', 'node--' ~ node.bundle|clean_class] %}

Component Props vs Slots

| Props (simple values) | Slots (complex content) | |----------------------|------------------------| | Titles, labels | Formatted text fields | | Numbers, booleans | Images, media | | URLs | Entity references | | CSS variants | Nested components |

Correct Adapter Pattern

{# node--article--teaser.html.twig #}
{% embed 'mytheme:card' with {
  heading: label,
  url: url,
  variant: node.isPromoted ? 'featured' : 'default',
} only %}
  {% block media %}{{ content.field_image }}{% endblock %}
  {% block body %}{{ content.body }}{% endblock %}
{% endembed %}

{# CRITICAL: Render remaining for cache bubbling #}
{{ content|without('field_image', 'body') }}

Move to Preprocess

Flag these as preprocess candidates:

  • Entity queries
  • Service calls
  • Complex calculations
  • Permission checks
  • Date formatting beyond simple |date

Audit Report Format

Issues Detected

| Severity | Line | Issue | Risk | |----------|------|-------|------| | CRITICAL | 12 | Render array drilling | Broken cache |

Refactored Code

Complete template with fixes and comments.

Preprocess Changes

function mytheme_preprocess_node(&$variables) {
  // Required PHP code for logic moved from template
}

Final Checklist

  • [ ] No render array drilling
  • [ ] content rendered or |without used
  • [ ] No business logic
  • [ ] |raw only with trusted data
  • [ ] Components isolated
  • [ ] Attributes via object

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.