mcpField
D
drupal-security

drupal-security

github.com/madsnorgaard安全49842 次安装6 周前更新
代码仓库

关于 drupal-security

drupal-security 是面向 Drupal 开发与代码审查的安全技能。它指出 SQL 注入、XSS、访问控制缺失和文件处理不安全等常见风险,并提供安全写法与提交前检查清单。

主要功能

  1. 01识别 SQL 注入风险
  2. 02防止渲染输出中的 XSS
  3. 03检查权限与 CSRF 控制
  4. 04审查文件上传验证
  5. 05发现凭据暴露和不安全代码

适用场景

  1. 01审查 Drupal 表单和控制器
  2. 02检查用户输入与数据库处理
  3. 03审计路由和访问权限
  4. 04提交前检查文件上传代码

安装

复制下面的命令,在终端中运行。

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

安装后在 Claude Code 中输入/drupal-security确认已加载。

详细介绍

Drupal 安全专家

在编写代码时主动识别安全漏洞,而不是等到事后才发现。

何时触发

  • 编写或编辑表单、控制器或插件
  • 处理用户输入或查询参数
  • 构建数据库查询
  • 渲染用户提供的内容
  • 实施访问控制

关键安全模式

防止 SQL 注入

绝不要将用户输入拼接到查询中:

// 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

始终转义输出。信任渲染系统:

// 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

对于仅管理员可见的内容:

use Drupal\Component\Utility\Xss;

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

始终验证权限:

// 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 保护

表单会自动包含 CSRF 令牌。对于自定义 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');
}
文件上传安全
$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
}
敏感数据
// 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';

需要留意的危险信号

看到以下模式时,立即警告:

模式风险修复方法
在 SQL 中拼接字符串SQL 注入使用查询构建器
使用变量的 #markupXSS使用 #plain_text
accessCheck(FALSE)绕过访问控制使用 accessCheck(TRUE)
路由中缺少 _permission未经授权的访问添加权限
Twig 中的 {{ var|raw }}XSS移除 |raw
硬编码的密码/密钥凭据泄露使用环境变量
eval() 或 exec()代码注入完全避免使用
对用户数据调用 unserialize()对象注入使用 JSON

安全审查提示词

审查代码时,始终询问:

  1. “这些数据来自哪里?”(用户输入 = 不可信)
  2. “这些数据会去往哪里?”(输出 = 需要转义)
  3. “谁应该有权访问?”(需要权限)
  4. “如果其中包含恶意输入会怎样?”(验证/净化)

快速安全检查清单

提交任何代码之前:

  • 验证/净化所有用户输入
  • 正确转义所有输出
  • 路由设有权限要求
  • 实体查询使用 accessCheck(TRUE)
  • 没有硬编码的凭据
  • 文件上传同时验证类型和扩展名
  • 表单使用 Form API(自动防护 CSRF)
  • 不记录敏感数据

资源

评论

支持 Markdown