agentleFS
ddtcorexddtcorex/maestro-skills/skills/magento2-security-scan/SKILL.md

magento2-security-scan

Skill5 starsChanged 3 months agoMITView on GitHub

This skill should be used when the user asks to "run a security audit", "find vulnerabilities", "check for XSS", "check CSRF protection", "validate form security", "run a dependency audit", "check for outdated packages", "run a PCI compliance check", or "do a security review before deploy". Scans Magento 2 code for security vulnerabilities and compliance issues. DEPENDENT on magento2-dev-core for security patterns.

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Check in nginx/Apache config or .htaccess:

    line 187
  2. Very specific:

    Run this for a rapid security assessment.

    line 210

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Magento 2 Security Scanner

This skill performs security scanning for vulnerabilities, misconfigurations, and compliance issues.

Govard-Native Audit Coverage

govard audit run executes PHPCS and PHPStan through Govard's pinned lint toolchain image, it covers coding-standard and static-analysis findings only. As of Govard v1.64.0 no security audit check exists: govard audit run --checks security fails with "audit check ... is not implemented". The lint run does include a pub/media PHP guard since v1.64.0, every PHP file under pub/media is flagged (M2-LINT-MEDIA), so a lint pass also covers that specific file-drop attack surface, but it is still not a vulnerability scan. Run this skill's manual checklist yourself and treat govard audit run --checks lint as the shared lint gate. Never present a lint-only pass as a security verdict.

Related Skills

REQUIRED BACKGROUND: Load magento2-dev-core first, this skill scans for violations of the security patterns it defines (escaping, discouraged functions, ObjectManager misuse), and its patterns are what you fix findings with.

Part of the QA trio with magento2-linter (style/static analysis) and magento2-performance-audit (runtime/infrastructure). Re-check API/resolver-specific findings against magento2-backend-dev.

Vulnerability Categories

1. Injection Vulnerabilities

TypePatternSeverityCode
SQL InjectionDirect SQL with user inputCriticalM2-SEC-001
XSS (Reflected)Unescaped user input in outputHighM2-SEC-003
XSS (Stored)Unescaped database contentCriticalM2-SEC-002
Command InjectionSystem command execution with user inputCriticalM2-SEC-004

Full scale and code catalogue: magento2-dev-core/references/severity-and-codes.md.

2. Authentication & Authorization

CheckCommand
Admin path changedCheck env.php for custom admin path
2FA enabledCheck admin/twofactor module
Password hashingVerify EncryptorInterface usage
Session securityCheck cookie configuration

3. Data Exposure

# Check for exposed sensitive files
curl -I https://store.test/app/etc/env.php
curl -I https://store.test/var/log/system.log
curl -I https://store.test/.git/config

# Expected: All should return 403 or 404

4. CSP Configuration

# Check CSP settings
govard sh -c "bin/magento config:get cms/wysiwyg/use_static_urls"
govard sh -c "bin/magento config:get design/content-security_policy/enable_content_security_policy"

Scanner Commands

PHP Security Checker

# Install security tools
composer require --dev magento/security-package --no-interaction

# Run Magento security scan
govard sh -c "vendor/bin/magento-security-scanner scan ./app/code/Vendor/Module"

Dependency Audit

# Check for known vulnerabilities
govard sh -c "composer audit --no-interaction"

# Check for outdated packages with security fixes
govard sh -c "composer outdated --direct --format=json | jq '.[] | select(.[\"security-update\"]) | .name'"

File Permission Check

# Check Magento file permissions
find var/ pub/static pub/media -type f -not -perm 0644 -ls
find var/ pub/static pub/media -type d -not -perm 0755 -ls
find app/etc -type f -not -perm 0640 -ls

Scoping

The "Quick Security Scan" greps default to a full module path (app/code/Vendor/Module). Given an explicit file list instead, loop over it the same way:

for f in app/code/Vendor/Module/Controller/Index/Index.php app/code/Vendor/Module/Model/Foo.php; do
  grep -Hn "\$_GET\|\$_POST\|\$_REQUEST\|ObjectManager::getInstance\|eval(" "$f"
done

magento2-code-review derives this file list from a git diff or an MR fetch and calls this skill with it directly, the git/glab mechanics themselves live there, not here.

Environment-level checks: scope boundary

Authentication & Authorization, Data Exposure, and CSP Configuration (sections 2-4 above) are not file-list-scoped at all, they check the running environment (env.php, a live URL, bin/magento config:get), not specific files. They cannot run against a PR/MR diff or remote fetch (no checked-out environment to query there) and, even at project/module scope, run once per audit rather than once per file. magento2-code-review states explicitly in its Coverage note whether these ran (project/module/ theme scope, live environment available) or were skipped (PR/MR scope, or no environment access this session), this is never left for whoever's running the review to decide silently.

XSS Prevention Checklist

  • All output escaped with $escaper
  • escapeHtml for HTML content
  • escapeHtmlAttr for attributes
  • escapeJs for JavaScript strings
  • escapeUrl for URLs
  • Form keys in all POST forms
  • No direct $_GET, $_POST, $_REQUEST usage

CSRF Protection

Verified Patterns

// Form with form key
<form action="<?= $escaper->escapeUrl($action) ?>" method="post">
    <?= $block->getBlockHtml('formkey') ?>
</form>

// AJAX with form key
$.ajax({
    url: url,
    type: 'POST',
    data: {
        form_key: $.cookie('form_key'),
        ...data
    }
});

Verify Admin Protection

# Check if admin form key validation is active
govard sh -c "bin/magento config:show admin/security/use_form_key"
# Expected: 1

Rate Limiting

# Configure rate limiting
govard sh -c "bin/magento config:set web/secure/open_restriction_enabled 1"

Security Headers

Check in nginx/Apache config or .htaccess:

X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()

PCI-DSS 4.0 Checklist (E-commerce)

From April 2025, payment pages require:

  • unsafe-eval CSP disabled
  • unsafe-inline CSP disabled
  • No inline scripts in payment forms
  • TLS 1.2+ enforced

Quick Security Scan

Quick check: grep -R "$_GET|$_POST|ObjectManager::getInstance" --include="*.phtml" over the changed templates. Address high-risk hits first.

Run this for a rapid security assessment. Run one grep per pattern and exclude ORM-layer hits (Collection/Repository/ResourceModel class files) when judging results:

# 1. Check for SQL in code
grep -r "execute\|fetch\|fetchAll\|select\|insert\|update\|delete" \
    app/code/Vendor/Module --include="*.php" | \
    grep -v "Collection\|Repository\|ResourceModel"

# 2. Check for superglobals
grep -r "\$_GET\|\$_POST\|\$_REQUEST" \
    app/code/Vendor/Module --include="*.php"

# 3. Check for ObjectManager
grep -r "ObjectManager::getInstance" \
    app/code/Vendor/Module --include="*.php"

# 4. Check for code evaluation functions
grep -r "eval" app/code/Vendor/Module --include="*.php"

Findings report

Every confirmed security finding goes into one report. Write every finding to findings.json in the shared schema (magento2-dev-core/references/findings-schema.md): tool: "magento2-security-scan", the four severities only, a code from severity-and-codes.md (or code: null with the tool's rule id in rule), and summary counts that match the findings. Then render it:

node <skills>/magento2-dev-core/scripts/report/render.mjs render --layout findings --audience dev --data findings.json --out <report-dir>

The engine writes report.md, report.html and report.body.html with the shared theme and report contract, so a brand overlay works on this report the same way as on a performance audit. It refuses mismatched counts and unknown codes with exit 1; fix the data, never the rendered file.

Compliance Report

# Security Audit Report

## Injection Vulnerabilities
- [ ] No SQL injection vectors
- [ ] No XSS vulnerabilities
- [ ] No command injection

## Authentication
- [ ] Admin path changed from /admin
- [ ] 2FA enabled
- [ ] Strong password policy

## Data Protection
- [ ] Sensitive files not exposed
- [ ] File permissions correct
- [ ] CSP configured

## PCI-DSS (if applicable)
- [ ] CSP no unsafe-eval on checkout
- [ ] No inline scripts in payment forms

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.