drupal-injection

A Drupal code rule set that checks for injection risks, including unsafe database queries, unescaped output, and unfiltered user input. Drupal is a content-management system for building websites.

In plain words
What is it for?
It helps review Drupal PHP code for SQL injection, cross-site scripting, unsafe render markup, and unsafe JavaScript settings.
Why use it?
It flags patterns that can let attackers alter database queries or inject harmful content into a site. The messages point to safer Drupal APIs and escaping methods.

Cursor rule for Cursor

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add rules/abderrahimghazali/cursor-rules/drupal-injection
Clone the repo
git clone --depth 1 https://github.com/abderrahimghazali/cursor-rules

Made for: Cursor.

Per session 0 Nothing until a file matches its globs; then the whole rule loads.
When invoked 1,612 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin 89% copy Near-identical to another mod in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00000 $0.01612
Opus 5 $0.00000 $0.00806
Sonnet 5 $0.00000 $0.00322
Haiku 4.5 $0.00000 $0.00161

Measured 2d ago against content hash 4dbf68efc505, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

drupal-injection scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

Origin

This is a copy

89% identical to drupal-injection — 206 lines differ, which has more behind it and is treated as the original. This page carries a canonical link to it rather than competing with it.

.cursor/rules/drupal-injection.mdc · 135 lines

How it starts

The opening of the file, as written. The whole thing — 135 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Drupal Injection Security Standards (OWASP A03:2021)

This rule enforces security best practices to prevent injection vulnerabilities in Drupal applications, as defined in OWASP Top 10:2021-A03.

actions:

  • type: enforce conditions:

    Pattern 1: Raw SQL queries without placeholders

    • pattern: "db_query\(['"][^'"]\$[^'"]['"]" message: "Direct variables in SQL queries are vulnerable to SQL injection. Use parameterized queries with placeholders."

    Pattern 2: Modern DB API without placeholders

    • pattern: "->query\(['"][^'"]\$[^'"]['"]" message: "Use parameterized queries with placeholders to prevent SQL injection: ->query($sql, [$param1, $param2])."

    Pattern 3: Unescaped output

    • pattern: "<?=|<?php\s+echo\s+(?!(t|\\t|\$this->t))[^;]*;" message: "Direct output may lead to XSS. Use t(), escaped variables with Html::escape(), or Twig templates."

    Pattern 4: Unfiltered user input in render arrays

    • pattern: "["']#markup["']\s*=>\s*(?!t\(|\\t\(|Xss::filterAdmin|Html::escape)\$" message: "Never use unfiltered variables in #markup. Use t(), Xss::filterAdmin(), or Html::escape()."

    Pattern 5: Unescaped variables in JavaScript settings

    • pattern: "->addJsSettings\(\[(?![^\]]*(Xss::filter|Json::encode))\$" message: "Filter variables before adding to JavaScript settings using Xss::filter() or properly encode with Json::encode()."

    Pattern 6: Direct command execution

    • pattern: "exec\(|shell_exec\(|system\(|passthru\(|proc_open\(|popen\(|`" message: "Command execution functions can lead to command injection. Use Symfony\Component\Process\Process if necessary."

    Pattern 7: Unvalidated redirect

    • pattern: "->redirect\(\s*\$(?!(this->|allowed_destinations|config))" message: "Unvalidated redirects can lead to open redirect vulnerabilities. Whitelist allowed destinations."

    Pattern 8: Raw user input in conditions

    • pattern: "->condition\([^,],\s\$(?!(this->|config|entity|storage))[^,]*," message: "Use proper input validation before using variables in database conditions to prevent SQL injection."

    Pattern 9: Missing CSRF protection in forms

    • pattern: "(?<!buildForm|getFormId)\sfunction\s+[a-zA-Z0-9_]+Form\s\([^{]*\{[^}]return\s+\$form;(?![^}]FormBuilderInterface|[^}]::TOKEN|[^}]#token)" message: "Form submissions must include CSRF protection with $form['#token']."

    Pattern 10: Unvalidated file operations

    • pattern: "file_get_contents\(\s*\$(?!(this->|allowed_paths|config))" message: "Validate file paths before operations to prevent path traversal attacks."
  • type: suggest message: | Drupal Injection Prevention Best Practices:

    1. SQL Injection Prevention:

      • Always use parameterized queries with placeholders
      • Use the Database API's condition methods: ->condition(), ->where()
      • Properly escape table and field names with {}
      • Consider using EntityQuery for entity operations
    2. XSS Prevention:

      • Use Drupal's t() function for user-visible strings
      • Apply appropriate filtering: Html::escape(), Xss::filter(), Xss::filterAdmin()
      • Use #plain_text instead of #markup when displaying user input
      • Utilize Twig's automatic escaping in templates
      • For admin UIs, be careful with Xss::filterAdmin() as it allows some tags
    3. CSRF Protection:

      • Always include form tokens with $form['#token']
      • Validate form tokens with FormState->validateToken()
      • For AJAX requests, utilize Drupal's ajax framework
      • Use drupal_valid_token() for custom validation

Read the full file on GitHub · 135 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 135 lines · 1,612 tokens per session scan A 4dbf68efc505

Subscribe to this mod's changes

drupal-injection is a cursor rule published in the GitHub repository abderrahimghazali/cursor-rules (2 stars, last pushed 1y ago), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 1,612 tokens. A static security scan graded it A with 0 findings. It is 89% identical to drupal-injection, differing in 206 lines, and is treated as a copy.