Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
madsnorgaard avatar

Drupal Security

  • 535 installs
  • 45 repo stars
  • Updated April 22, 2026
  • madsnorgaard/agent-resources

drupal-security is a Claude Code skill that flags SQL injection, XSS, and access bypass risks while developers or agents write Drupal forms, controllers, and database queries in PHP.

About

drupal-security is a proactive Drupal security expert skill for agent-assisted PHP development. It auto-activates when writing or editing forms, controllers, plugins, database queries, user input handling, and access control, surfacing vulnerable patterns like concatenated SQL and unsafe rendering before code ships. The skill encodes Drupal-specific prevention guidance for SQL injection, XSS, and access bypass across common module touchpoints. Developers reach for drupal-security when building custom Drupal modules, entity forms, or REST endpoints where input validation and permission checks are easy to miss under time pressure.

  • Auto-activates on forms, controllers, plugins, and user input handling in Drupal
  • Parameterized queries and placeholders instead of concatenated SQL
  • XSS guidance: #plain_text, render elements, and Twig auto-escape vs raw #markup
  • Access control and safe handling of query parameters and user-provided content
  • Critical security patterns documented with vulnerable vs safe PHP examples

Drupal Security by the numbers

  • 535 all-time installs (skills.sh)
  • +12 installs in the week ending Aug 2, 2026 (Skillselion tracking)
  • Ranked #503 of 2,203 Security skills by installs in the Skillselion catalog
  • Security screen: LOW risk (skills.sh audit)
  • Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/madsnorgaard/agent-resources --skill drupal-security

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs535
repo stars45
Security audit3 / 3 scanners passed
Last updatedApril 22, 2026
Repositorymadsnorgaard/agent-resources

How do you prevent SQL injection in Drupal modules?

Keep Drupal modules and custom PHP safe from SQL injection, XSS, and access bypass while you or your agent writes forms, controllers, and queries.

Who is it for?

Drupal module developers writing custom forms, controllers, plugins, and database queries who want inline security review during implementation.

Skip if: Teams needing infrastructure hardening, WAF tuning, or penetration-test reports rather than secure PHP module authoring.

When should I use this skill?

Writing or editing Drupal forms, controllers, plugins, queries, user input handling, or access control in PHP.

What you get

Hardened Drupal PHP with safe query APIs, sanitized output, and correct access checks on forms and controllers.

  • secure query patterns
  • sanitized render output
  • access-checked controllers

Files

SKILL.mdMarkdownGitHub ↗

Drupal Security Expert

You proactively identify security vulnerabilities while code is being written, not after.

When This Activates

  • Writing or editing forms, controllers, or plugins
  • Handling user input or query parameters
  • Building database queries
  • Rendering user-provided content
  • Implementing access control

Critical Security Patterns

SQL Injection Prevention

NEVER concatenate user input into queries:

// VULNERABLE - SQL injection
$query = "SELECT * FROM users WHERE name = '" . $name . "'";
$result = $connection->query($query);

// SAFE - parameterized query
$result = $connection->select('users', 'u')
  ->fields('u')
  ->condition('name', $name)
  ->execute();

// SAFE - placeholder
$result = $connection->query(
  'SELECT * FROM {users} WHERE name = :name',
  [':name' => $name]
);

XSS Prevention

Always escape output. Trust the render system:

// VULNERABLE - raw HTML output
return ['#markup' => $user_input];
return ['#markup' => '<div>' . $title . '</div>'];

// SAFE - plain text (auto-escaped)
return ['#plain_text' => $user_input];

// SAFE - use proper render elements
return [
  '#type' => 'html_tag',
  '#tag' => 'div',
  '#value' => $title,  // Escaped automatically
];

// SAFE - Twig auto-escapes
{{ variable }}  // Escaped
{{ variable|raw }}  // DANGEROUS - only for trusted HTML

For admin-only content:

use Drupal\Component\Utility\Xss;

// Filter but allow safe HTML tags
$safe = Xss::filterAdmin($user_html);

Access Control

Always verify permissions:

// In routing.yml
my_module.admin:
  path: '/admin/my-module'
  requirements:
    _permission: 'administer my_module'  # Required!

// In code
if (!$this->currentUser->hasPermission('administer my_module')) {
  throw new AccessDeniedHttpException();
}

// Entity queries - check access!
$query = $this->entityTypeManager
  ->getStorage('node')
  ->getQuery()
  ->accessCheck(TRUE)  // CRITICAL - never FALSE unless intentional
  ->condition('type', 'article');

CSRF Protection

Forms automatically include CSRF tokens. For custom AJAX:

// Include token in AJAX requests
$build['#attached']['drupalSettings']['myModule']['token'] =
  \Drupal::csrfToken()->get('my_module_action');

// Validate in controller
if (!$this->csrfToken->validate($token, 'my_module_action')) {
  throw new AccessDeniedHttpException('Invalid token');
}

File Upload Security

$validators = [
  'file_validate_extensions' => ['pdf doc docx'],  // Whitelist extensions
  'file_validate_size' => [25600000],  // 25MB limit
  'FileSecurity' => [],  // Drupal 10.2+ - blocks dangerous files
];

// NEVER trust file extension alone - check MIME type
$file_mime = $file->getMimeType();
$allowed_mimes = ['application/pdf', 'application/msword'];
if (!in_array($file_mime, $allowed_mimes)) {
  // Reject file
}

Sensitive Data

// NEVER log sensitive data
$this->logger->info('User @user logged in', ['@user' => $username]);
// NOT: $this->logger->info('Login: ' . $username . ':' . $password);

// NEVER expose in error messages
throw new \Exception('Database error');  // Generic
// NOT: throw new \Exception('Query failed: ' . $query);

// Use environment variables for secrets
$api_key = getenv('MY_API_KEY');
// NOT: $api_key = 'hardcoded-secret-key';

Red Flags to Watch For

When you see these patterns, immediately warn:

PatternRiskFix
String concatenation in SQLSQL injectionUse query builder
#markup with variablesXSSUse #plain_text
accessCheck(FALSE)Access bypassUse accessCheck(TRUE)
Missing _permission in routesUnauthorized accessAdd permission
`{{ var\raw }}` in TwigXSS
Hardcoded passwords/keysCredential exposureUse env vars
eval() or exec()Code injectionAvoid entirely
unserialize() on user dataObject injectionUse JSON

Security Review Prompts

When reviewing code, always ask:

1. "Where does this data come from?" (User input = untrusted) 2. "Where does this data go?" (Output = escape it) 3. "Who should access this?" (Permissions required) 4. "What if this contains malicious input?" (Validate/sanitize)

Quick Security Checklist

Before any code is committed:

  • [ ] All user input validated/sanitized
  • [ ] All output properly escaped
  • [ ] Routes have permission requirements
  • [ ] Entity queries use accessCheck(TRUE)
  • [ ] No hardcoded credentials
  • [ ] File uploads validate type AND extension
  • [ ] Forms use Form API (automatic CSRF)
  • [ ] Sensitive data not logged

Resources

Related skills

How it compares

Pick drupal-security for inline Drupal PHP module review; use general OWASP or PHP security skills when the stack is not Drupal-specific.

FAQ

When does drupal-security activate?

drupal-security activates when writing or editing Drupal forms, controllers, plugins, database queries, user input handling, rendering user content, or implementing access control in PHP module code.

What vulnerabilities does drupal-security catch?

drupal-security focuses on SQL injection from unsafe query construction, XSS from unsanitized output, and access bypass from missing or weak permission and entity access checks in Drupal modules.

Is Drupal Security safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

Securityappsecaudit

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.