drupal-broken-access-control

Drupal security rules for detecting broken access control, where an application fails to check whether a user may perform an action. The rules follow the OWASP Top 10 category A01:2021.

In plain words
What is it for?
Use them to review Drupal routes, replace deprecated permission checks, prevent hard-coded administrator checks, and require access checks before entity operations.
Why use it?
They flag routes and entity operations that could let users access or change data without the required permission.

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-broken-access-control
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,458 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found 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.01458
Opus 5 $0.00000 $0.00729
Sonnet 5 $0.00000 $0.00292
Haiku 4.5 $0.00000 $0.00146

Measured yesterday against content hash bc74fca1d7ff, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

drupal-broken-access-control 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 yesterday.

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.

.cursor/rules/drupal-broken-access-control.mdc · 128 lines

How it starts

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

Drupal Broken Access Control Security Standards (OWASP A01:2021)

This rule enforces security best practices to prevent broken access control vulnerabilities in Drupal applications, as defined in OWASP Top 10:2021-A01.

actions:

  • type: enforce conditions:

    Pattern 1: Missing access checks in routes

    • pattern: "\s*\$routes\['[^']'\]\s=\s*.*(?!_access|access_callback|requirements)" message: "Route definition is missing access control. Add '_permission', '_role', '_access', or custom access check in requirements."

    Pattern 2: Using user_access() instead of more secure methods

    • pattern: "user_access\(" message: "user_access() is deprecated. Use $account->hasPermission() or proper dependency injection with AccessResult methods."

    Pattern 3: Hard-coded user ID checks

    • pattern: "(\$user->id\(\)|\$user->uid)\s*===?\s*1" message: "Avoid hardcoded checks against user ID 1. Use role-based permissions or proper access control services."

    Pattern 4: Missing access check on entity operations

    • pattern: "\$entity->(?!access)(save|delete|update)\(\)" message: "Entity operation without prior access check. Use $entity->access('operation') before performing operations."

    Pattern 5: Using Drupal::currentUser() directly in services

    • pattern: "\\Drupal::currentUser\(\)" message: "Avoid using \Drupal::currentUser() directly. Inject the current_user service for better testability and security."

    Pattern 6: Missing access checks in controllers

    • pattern: "class [A-Za-z0-9_]+Controller.+extends ControllerBase[^}]+public function [a-zA-Z0-9_]+\([^{]\)\s\{(?![^}]*access)" message: "Controller method lacks explicit access checking. Add checks via route requirements or within the controller method."

    Pattern 7: Direct field value manipulation without access check

    • pattern: "\$entity->set\([^)]+\)\s*;(?![^;]*access)" message: "Direct field value manipulation without access check. Verify entity field access before manipulation."

    Pattern 8: Unprotected REST endpoints

    • pattern: "@RestResource\([^)]\)(?![^{]_access|access_callback)" message: "REST resource lacks access controls. Add access checks via annotations or in methods."

    Pattern 9: Insecure access check by client IP

    • pattern: "\$_SERVER\['REMOTE_ADDR'\]\s*===?\s*" message: "IP-based access control is insufficient. Use proper Drupal permission system instead."

    Pattern 10: Allow bypassing cache for authenticated users without proper checks

    • pattern: "#cache\['contexts'\]\s*=\s*\[[^\]]'user'[^\]]\]" message: "Using 'user' cache context without proper access checks may expose content to unauthorized users."
  • type: suggest message: | Drupal Access Control Best Practices:

    1. Route Access Controls:

      • Always define access requirements in route definitions
      • Use permission-based access checks: '_permission', '_role', '_entity_access'
      • Implement custom access checkers implementing AccessInterface
    2. Entity Access Controls:

      • Always check entity access: $entity->access('view'|'update'|'delete')
      • Use EntityAccessControlHandler for consistent access control
      • Respect entity field access with $entity->get('field')->access('view'|'edit')
    3. Controller Security:

      • Inject and use proper services rather than \Drupal static calls
      • Add explicit access checks within controller methods
      • Use AccessResult methods (allowed, forbidden, neutral) with proper caching metadata

Read the full file on GitHub · 128 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. yesterday First seen · 128 lines · 1,458 tokens per session scan A bc74fca1d7ff

Subscribe to this mod's changes

drupal-broken-access-control 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,458 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.