drupal-security

madsnorgaard/agent-resources · updated Apr 8, 2026

$npx skills add https://github.com/madsnorgaard/agent-resources --skill drupal-security
0 commentsdiscussion
summary

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

skill.md

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:

Pattern Risk Fix
String concatenation in SQL SQL injection Use query builder
#markup with variables XSS Use #plain_text
accessCheck(FALSE) Access bypass Use accessCheck(TRUE)
Missing _permission in routes Unauthorized access Add permission
{{ var|raw }} in Twig XSS Remove |raw
Hardcoded passwords/keys Credential exposure Use env vars
eval() or exec() Code injection Avoid entirely
unserialize() on user data Object injection Use 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

Discussion

Product Hunt–style comments (not star reviews)
  • No comments yet — start the thread.
general reviews

Ratings

4.434 reviews
  • Liam Kim· Dec 16, 2024

    I recommend drupal-security for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.

  • Chaitanya Patil· Dec 12, 2024

    I recommend drupal-security for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.

  • Alexander Verma· Dec 8, 2024

    drupal-security reduced setup friction for our internal harness; good balance of opinion and flexibility.

  • Rahul Santra· Nov 27, 2024

    Keeps context tight: drupal-security is the kind of skill you can hand to a new teammate without a long onboarding doc.

  • Layla Diallo· Nov 27, 2024

    drupal-security has been reliable in day-to-day use. Documentation quality is above average for community skills.

  • Diya Huang· Nov 7, 2024

    Useful defaults in drupal-security — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.

  • Piyush G· Nov 3, 2024

    Useful defaults in drupal-security — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.

  • Ren Reddy· Nov 3, 2024

    Keeps context tight: drupal-security is the kind of skill you can hand to a new teammate without a long onboarding doc.

  • Li Dixit· Oct 26, 2024

    drupal-security has been reliable in day-to-day use. Documentation quality is above average for community skills.

  • Shikha Mishra· Oct 22, 2024

    drupal-security has been reliable in day-to-day use. Documentation quality is above average for community skills.

showing 1-10 of 34

1 / 4