id,category,subcategory,title,description,severity,examples,references,tags,rationale,fix_guidance
OWASP001,owasp_top10,A01_broken_access_control,Implement Proper Access Control,Access control enforces policy such that users cannot act outside of their intended permissions,critical,"{""good"": ""if (\\Drupal::currentUser()->hasPermission('administer content')) { // Allow action } else { throw new AccessDeniedHttpException(); }"", ""bad"": ""// No permission check before sensitive operation""}","[""https://owasp.org/Top10/A01_2021-Broken_Access_Control/"", ""https://www.drupal.org/docs/security/access-control""]",security|access-control|authorization,"94% of applications were tested for some form of broken access control. Can lead to unauthorized information disclosure, modification, or destruction of all data","Use Drupal's permission system, implement access control checks on routes, use entity access API for content access control"
OWASP002,owasp_top10,A01_broken_access_control,Use Route Access Requirements,Define access requirements in routing.yml files to protect routes,critical,"{""good"": ""mymodule.admin:\n path: '/admin/mymodule'\n defaults:\n _form: '\\Drupal\\mymodule\\Form\\AdminForm'\n requirements:\n _permission: 'administer mymodule'"", ""bad"": ""requirements:\n _access: 'TRUE' # Allows everyone""}","[""https://www.drupal.org/docs/drupal-apis/routing-system""]",security|routing|access-control,"Missing access controls on routes can expose administrative functions to unauthorized users","Always specify appropriate access requirements: _permission, _role, _custom_access, or _entity_access"
OWASP003,owasp_top10,A01_broken_access_control,Implement Entity Access Control,Use entity access handlers to control CRUD operations on entities,critical,"{""good"": ""class NodeAccessControlHandler extends EntityAccessControlHandler {\n protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {\n if ($operation === 'view') {\n return AccessResult::allowedIfHasPermission($account, 'view content');\n }\n return parent::checkAccess($entity, $operation, $account);\n }\n}"", ""bad"": ""// Direct entity operations without access checks""}","[""https://www.drupal.org/docs/drupal-apis/entity-api/access-control""]",security|entity|access-control,"Entity access controls prevent unauthorized CRUD operations on content","Implement custom access control handlers for entities, use hook_entity_access() for additional checks"
OWASP004,owasp_top10,A02_cryptographic_failures,Store Sensitive Data Encrypted,Never store sensitive data in plain text,critical,"{""good"": ""use Drupal\\Core\\Site\\Settings;\n$encrypted_key = \\Drupal::service('encryption')->encrypt($api_key);\n\\Drupal::state()->set('mymodule.encrypted_key', $encrypted_key);"", ""bad"": ""\\Drupal::config('mymodule.settings')->set('api_key', $plain_text_key)->save();""}","[""https://owasp.org/Top10/A02_2021-Cryptographic_Failures/"", ""https://www.drupal.org/project/encrypt""]",security|encryption|data-protection,"Storing sensitive data unencrypted can lead to data breaches if database is compromised","Use the Encrypt module for storing sensitive data, use environment variables for API keys, never commit secrets to version control"
OWASP005,owasp_top10,A02_cryptographic_failures,Use HTTPS Everywhere,Enforce HTTPS for all communications,critical,"{""good"": ""# In settings.php\n$settings['force_https'] = TRUE;\n\n# In .htaccess\nRewriteCond %{HTTPS} off\nRewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]"", ""bad"": ""// Allowing HTTP connections for authenticated users""}","[""https://www.drupal.org/docs/administering-a-drupal-site/security/securing-your-site""]",security|https|transport-security,"Data transmitted over HTTP can be intercepted by attackers","Force HTTPS redirects, implement HSTS headers, ensure all resources load over HTTPS"
OWASP006,owasp_top10,A02_cryptographic_failures,Hash Passwords Properly,Use Drupal's password hashing service for storing passwords,critical,"{""good"": ""$password_hasher = \\Drupal::service('password');\n$hashed = $password_hasher->hash($password);\n// Verify\nif ($password_hasher->check($password, $hashed)) {\n // Password is correct\n}"", ""bad"": ""$hashed = md5($password); // Never use MD5 for passwords""}","[""https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Password!PasswordInterface.php""]",security|passwords|hashing,"Weak password hashing allows attackers to recover passwords from stolen hashes","Always use Drupal's password service which implements secure hashing algorithms with salt"
OWASP007,owasp_top10,A03_injection,Prevent SQL Injection,Always use Drupal's database API with placeholders,critical,"{""good"": ""$result = \\Drupal::database()->select('users_field_data', 'u')\n ->fields('u', ['uid', 'name'])\n ->condition('name', $username)\n ->execute();"", ""bad"": ""$result = \\Drupal::database()->query(\""SELECT * FROM users WHERE name = '$username'\"");""}","[""https://owasp.org/Top10/A03_2021-Injection/"", ""https://www.drupal.org/docs/security/sql-injection""]",security|sql|injection,"SQL injection is #3 in OWASP Top 10, can lead to complete database compromise","Use Database API query builders, use placeholders for dynamic queries, never concatenate user input into SQL"
OWASP008,owasp_top10,A03_injection,Prevent XSS in Twig,Properly escape output in Twig templates,critical,"{""good"": ""{{ title }} {# Auto-escaped by default #}\n{{ content|raw }} {# Only when HTML is trusted #}"", ""bad"": ""{{ user_input|raw }} {# Never trust user input #}""}","[""https://www.drupal.org/docs/security/cross-site-scripting"", ""https://twig.symfony.com/doc/3.x/filters/escape.html""]",security|xss|twig,"XSS attacks can steal user sessions and compromise accounts","Let Twig auto-escape by default, only use |raw filter for trusted HTML, use specific escape filters when needed"
OWASP009,owasp_top10,A03_injection,Sanitize User Input,Use Drupal's sanitization methods for user input,critical,"{""good"": ""use Drupal\\Component\\Utility\\Html;\nuse Drupal\\Component\\Utility\\Xss;\n\n$safe_string = Html::escape($user_input);\n$filtered = Xss::filterAdmin($content);"", ""bad"": ""$output = '<div>' . $_POST['user_input'] . '</div>';""}","[""https://www.drupal.org/docs/drupal-apis/sanitization-functions""]",security|sanitization|input-validation,"Unsanitized input can lead to XSS and other injection attacks","Use Html::escape() for plain text, Xss::filter() for limited HTML, validate input types"
OWASP010,owasp_top10,A04_insecure_design,Implement Secure Design Patterns,Design with security in mind from the start,high,"{""good"": ""// Implement rate limiting\n\\Drupal::service('flood')->register('mymodule.action', 3600);\nif (!\\Drupal::service('flood')->isAllowed('mymodule.action', 5, 3600)) {\n throw new TooManyRequestsHttpException();\n}"", ""bad"": ""// No rate limiting on sensitive operations""}","[""https://owasp.org/Top10/A04_2021-Insecure_Design/""]",security|design|architecture,"Insecure design cannot be fixed by perfect implementation","Use threat modeling, implement defense in depth, follow principle of least privilege"
OWASP011,owasp_top10,A05_security_misconfiguration,Disable Unnecessary Modules,Remove or disable modules not in use,high,"{""good"": ""# Disable development modules in production\ndrush pm:uninstall devel kint webprofiler\n\n# In settings.php\n$settings['extension_discovery_scan_tests'] = FALSE;"", ""bad"": ""// Leaving development modules enabled in production""}","[""https://owasp.org/Top10/A05_2021-Security_Misconfiguration/""]",security|configuration|hardening,"Unnecessary modules increase attack surface and may expose sensitive information","Audit enabled modules regularly, disable UI modules like Views UI in production"
OWASP012,owasp_top10,A05_security_misconfiguration,Configure Error Handling,Properly configure error display for production,high,"{""good"": ""# In settings.php for production\n$config['system.logging']['error_level'] = 'hide';\nini_set('display_errors', FALSE);\nini_set('display_startup_errors', FALSE);"", ""bad"": ""$config['system.logging']['error_level'] = 'verbose'; // In production""}","[""https://www.drupal.org/docs/administering-a-drupal-site/security/hide-php-warnings-and-errors""]",security|errors|information-disclosure,"Verbose errors can reveal system information to attackers","Hide errors from display in production, log errors to files, use custom error pages"
OWASP013,owasp_top10,A06_vulnerable_components,Keep Drupal Updated,Regularly update Drupal core and modules,critical,"{""good"": ""# Regular update workflow\ncomposer outdated --direct\ncomposer update drupal/core --with-dependencies\ndrush updatedb\ndrush cache:rebuild"", ""bad"": ""// Running outdated Drupal versions with known vulnerabilities""}","[""https://owasp.org/Top10/A06_2021-Vulnerable_and_Outdated_Components/"", ""https://www.drupal.org/security""]",security|updates|maintenance,"Known vulnerabilities in outdated components are easily exploitable","Subscribe to security advisories, use Composer for updates, test updates in non-production first"
OWASP014,owasp_top10,A06_vulnerable_components,Audit Dependencies,Regularly audit third-party libraries,high,"{""good"": ""# Check for security advisories\ncomposer audit\n\n# Use only trusted sources\ncomposer config repositories.drupal composer https://packages.drupal.org/8"", ""bad"": ""// Using modules from untrusted sources""}","[""https://www.drupal.org/docs/develop/using-composer/using-composer-to-manage-drupal-site-dependencies""]",security|dependencies|third-party,"Vulnerable dependencies can compromise entire application","Use composer audit, monitor security advisories, prefer stable releases"
OWASP015,owasp_top10,A07_auth_failures,Implement Strong Authentication,Use Drupal's authentication system properly,critical,"{""good"": ""// Use Drupal's user authentication\n$uid = \\Drupal::service('user.auth')->authenticate($username, $password);\nif ($uid) {\n user_login_finalize(User::load($uid));\n}"", ""bad"": ""// Custom weak authentication implementation""}","[""https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/""]",security|authentication|identity,"Authentication failures can lead to account takeover","Use Drupal's built-in authentication, implement 2FA, enforce strong passwords"
OWASP016,owasp_top10,A07_auth_failures,Secure Session Management,Properly manage user sessions,critical,"{""good"": ""// Regenerate session ID on login\n\\Drupal::service('session')->migrate();\n\n// Set secure session cookies in settings.php\nini_set('session.cookie_secure', TRUE);\nini_set('session.cookie_httponly', TRUE);"", ""bad"": ""// Not regenerating session IDs""}","[""https://www.drupal.org/docs/security/session-management""]",security|sessions|authentication,"Poor session management can lead to session hijacking","Regenerate session IDs, use secure session cookies, implement session timeout"
OWASP017,owasp_top10,A08_data_integrity,Verify Data Integrity,Implement checks for data integrity,high,"{""good"": ""// Verify file integrity\n$expected_hash = 'abc123...';\n$actual_hash = hash_file('sha256', $file_path);\nif (!hash_equals($expected_hash, $actual_hash)) {\n throw new \\Exception('File integrity check failed');\n}"", ""bad"": ""// No integrity verification""}","[""https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/""]",security|integrity|validation,"Data integrity failures can lead to malicious code execution","Implement checksums, use secure update mechanisms, verify third-party code"
OWASP018,owasp_top10,A09_logging_monitoring,Implement Security Logging,Log security-relevant events,high,"{""good"": ""\\Drupal::logger('security')->warning('Failed login attempt for user @username from IP @ip', [\n '@username' => $username,\n '@ip' => \\Drupal::request()->getClientIp(),\n]);"", ""bad"": ""// No logging of security events""}","[""https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/""]",security|logging|monitoring,"Without logging, breaches go undetected","Log authentication events, access control failures, input validation failures"
OWASP019,owasp_top10,A10_ssrf,Prevent SSRF Attacks,Validate and sanitize URLs in user input,high,"{""good"": ""use Drupal\\Component\\Utility\\UrlHelper;\n\n$url = UrlHelper::filterBadProtocol($user_url);\n$allowed_hosts = ['api.example.com', 'cdn.example.com'];\n$host = parse_url($url, PHP_URL_HOST);\nif (!in_array($host, $allowed_hosts)) {\n throw new \\Exception('Invalid URL');\n}"", ""bad"": ""$content = file_get_contents($user_provided_url);""}","[""https://owasp.org/Top10/A10_2021-Server-Side_Request_Forgery/""]",security|ssrf|validation,"SSRF can lead to internal network scanning and data exfiltration","Whitelist allowed protocols and domains, validate URLs, use allow lists for external requests"
OWASP020,owasp_top10,A05_security_misconfiguration,Secure File Permissions,Set proper file permissions for Drupal,high,"{""good"": ""# Secure file permissions\nfind . -type f -exec chmod 644 {} \\;\nfind . -type d -exec chmod 755 {} \\;\n\n# Protect sensitive files\nchmod 444 sites/default/settings.php\nchmod 755 sites/default"", ""bad"": ""chmod -R 777 sites/default/files""}","[""https://www.drupal.org/docs/security-in-drupal/securing-file-permissions-and-ownership""]",security|permissions|filesystem,"Incorrect file permissions can expose sensitive files","Follow Drupal's recommended file permissions, protect settings.php, secure private files directory"