|
| 1 | +# Handover Document: sanctify-php Integration Insights |
| 2 | + |
| 3 | +## Context |
| 4 | + |
| 5 | +This document summarizes findings from integrating `php-aegis` and `sanctify-php` into a WordPress semantic theme (wp-sinople-theme). It provides actionable recommendations for the `sanctify-php` team based on real-world usage patterns. |
| 6 | + |
| 7 | +## Role Clarification |
| 8 | + |
| 9 | +| Tool | Role | When Used | |
| 10 | +|------|------|-----------| |
| 11 | +| **php-aegis** | Runtime security library | During request handling (validation, sanitization, headers) | |
| 12 | +| **sanctify-php** | Static analysis tool | During development/CI (find vulnerabilities before deploy) | |
| 13 | + |
| 14 | +These are **complementary**, not competing tools: |
| 15 | +- `sanctify-php` finds the bugs |
| 16 | +- `php-aegis` provides the fixes |
| 17 | + |
| 18 | +## Issues Discovered During Integration |
| 19 | + |
| 20 | +### 1. Haskell Toolchain Dependency |
| 21 | + |
| 22 | +**Problem**: `sanctify-php` requires GHC/Cabal to build, which is a significant barrier for PHP developers. |
| 23 | + |
| 24 | +**Impact**: Most PHP teams don't have Haskell expertise or toolchain installed. |
| 25 | + |
| 26 | +**Recommendations**: |
| 27 | +- Provide pre-built binaries for Linux (x86_64, aarch64), macOS (Intel, Apple Silicon), Windows |
| 28 | +- Create official Docker image: `ghcr.io/hyperpolymath/sanctify-php:latest` |
| 29 | +- Consider GitHub Actions integration that runs analysis without local install |
| 30 | +- Add installation via common package managers (Homebrew, apt, nix) |
| 31 | + |
| 32 | +**Example Docker usage**: |
| 33 | +```bash |
| 34 | +docker run --rm -v $(pwd):/workspace ghcr.io/hyperpolymath/sanctify-php analyze /workspace |
| 35 | +``` |
| 36 | + |
| 37 | +### 2. PHP 8.x Syntax Support |
| 38 | + |
| 39 | +**Problem**: Parser may not handle all PHP 8.x syntax (enums, union types, named arguments, attributes, match expressions, constructor property promotion). |
| 40 | + |
| 41 | +**Test cases needed**: |
| 42 | +```php |
| 43 | +// Enums (PHP 8.1+) |
| 44 | +enum Status: string { |
| 45 | + case Draft = 'draft'; |
| 46 | + case Published = 'published'; |
| 47 | +} |
| 48 | + |
| 49 | +// Union types (PHP 8.0+) |
| 50 | +function process(string|int $input): string|false { ... } |
| 51 | + |
| 52 | +// Attributes (PHP 8.0+) |
| 53 | +#[Route('/api/users')] |
| 54 | +class UserController { ... } |
| 55 | + |
| 56 | +// Constructor property promotion (PHP 8.0+) |
| 57 | +class User { |
| 58 | + public function __construct( |
| 59 | + public readonly string $name, |
| 60 | + private int $age = 0, |
| 61 | + ) {} |
| 62 | +} |
| 63 | + |
| 64 | +// Named arguments (PHP 8.0+) |
| 65 | +htmlspecialchars(string: $input, flags: ENT_QUOTES); |
| 66 | + |
| 67 | +// Match expressions (PHP 8.0+) |
| 68 | +$result = match($status) { |
| 69 | + Status::Draft => 'Editing', |
| 70 | + Status::Published => 'Live', |
| 71 | +}; |
| 72 | +``` |
| 73 | + |
| 74 | +**Recommendation**: Add PHP 8.x grammar rules and comprehensive test suite. |
| 75 | + |
| 76 | +### 3. RDF/Turtle Output Context Awareness |
| 77 | + |
| 78 | +**Problem**: Static analyzer doesn't detect RDF/Turtle injection vulnerabilities in semantic web themes. |
| 79 | + |
| 80 | +**Background**: Semantic WordPress themes output RDF Turtle format for linked data. Standard XSS detection won't catch Turtle-specific injection vectors. |
| 81 | + |
| 82 | +**Vulnerable pattern** (not currently detected): |
| 83 | +```php |
| 84 | +// DANGEROUS: addslashes() is insufficient for Turtle |
| 85 | +$turtle = '<' . $uri . '> rdfs:label "' . addslashes($label) . '" .'; |
| 86 | +``` |
| 87 | + |
| 88 | +**Attack vectors**: |
| 89 | +```turtle |
| 90 | +# Turtle escape sequences |
| 91 | +\n \r \t \\ \" \uXXXX \UXXXXXXXX |
| 92 | +
|
| 93 | +# IRI injection |
| 94 | +<http://evil.com> owl:sameAs <http://trusted.com> |
| 95 | +``` |
| 96 | + |
| 97 | +**Recommendation**: Add detection rules for: |
| 98 | +- `addslashes()` used in RDF/Turtle context |
| 99 | +- Unescaped variables in Turtle string literals (`"..."`) |
| 100 | +- Unescaped IRIs (`<...>`) |
| 101 | +- Missing use of proper escaping functions |
| 102 | + |
| 103 | +**Suggested rule signatures**: |
| 104 | +``` |
| 105 | +turtle_string_injection: Detects unescaped user input in Turtle string literals |
| 106 | +turtle_iri_injection: Detects unescaped user input in Turtle IRIs |
| 107 | +rdf_semantic_injection: Detects potential semantic attacks via RDF |
| 108 | +``` |
| 109 | + |
| 110 | +### 4. WordPress Integration Documentation |
| 111 | + |
| 112 | +**Problem**: No clear guidance for WordPress-specific vulnerability patterns. |
| 113 | + |
| 114 | +**WordPress-specific patterns to detect**: |
| 115 | + |
| 116 | +```php |
| 117 | +// DANGEROUS: Direct $_GET/$_POST usage |
| 118 | +echo $_GET['query']; // XSS |
| 119 | + |
| 120 | +// DANGEROUS: Missing nonce verification |
| 121 | +if (isset($_POST['action'])) { ... } // CSRF |
| 122 | + |
| 123 | +// DANGEROUS: Direct SQL interpolation |
| 124 | +$wpdb->query("SELECT * FROM users WHERE id = " . $_GET['id']); // SQLi |
| 125 | + |
| 126 | +// DANGEROUS: Unescaped output |
| 127 | +echo $user_input; // Should use esc_html(), esc_attr(), etc. |
| 128 | + |
| 129 | +// DANGEROUS: Privileged action without capability check |
| 130 | +add_action('wp_ajax_delete_user', 'delete_user_handler'); |
| 131 | +function delete_user_handler() { |
| 132 | + // Missing: current_user_can('delete_users') |
| 133 | + wp_delete_user($_POST['user_id']); |
| 134 | +} |
| 135 | +``` |
| 136 | + |
| 137 | +**WordPress-specific safe patterns**: |
| 138 | +```php |
| 139 | +// Safe escaping functions |
| 140 | +esc_html($text) |
| 141 | +esc_attr($attr) |
| 142 | +esc_url($url) |
| 143 | +wp_kses($html, $allowed) |
| 144 | +wp_kses_post($html) |
| 145 | + |
| 146 | +// Safe nonce verification |
| 147 | +wp_verify_nonce($_POST['_wpnonce'], 'action_name') |
| 148 | +check_admin_referer('action_name') |
| 149 | + |
| 150 | +// Safe capability checks |
| 151 | +current_user_can('edit_posts') |
| 152 | +``` |
| 153 | + |
| 154 | +**Recommendation**: Create WordPress-specific ruleset that: |
| 155 | +- Detects missing `esc_*` function usage |
| 156 | +- Detects missing nonce verification in form handlers |
| 157 | +- Detects missing capability checks in AJAX handlers |
| 158 | +- Recognizes WordPress sanitization functions as safe sinks |
| 159 | + |
| 160 | +### 5. IndieWeb/Micropub Pattern Detection |
| 161 | + |
| 162 | +**Problem**: No awareness of IndieWeb protocols (Micropub, IndieAuth, Webmention). |
| 163 | + |
| 164 | +**Patterns to detect**: |
| 165 | + |
| 166 | +```php |
| 167 | +// DANGEROUS: Missing IndieAuth token verification |
| 168 | +function handle_micropub($request) { |
| 169 | + $content = $request['content']; // Unverified! |
| 170 | + create_post($content); |
| 171 | +} |
| 172 | + |
| 173 | +// DANGEROUS: Webmention SSRF |
| 174 | +function verify_webmention($source) { |
| 175 | + $response = wp_remote_get($source); // Can hit internal IPs |
| 176 | +} |
| 177 | + |
| 178 | +// DANGEROUS: Micropub content injection |
| 179 | +$mf2 = Mf2\parse($html, $source); |
| 180 | +$content = $mf2['items'][0]['properties']['content'][0]; |
| 181 | +echo $content; // Unsanitized from external source |
| 182 | +``` |
| 183 | + |
| 184 | +**Recommendation**: Add rules for common IndieWeb vulnerability patterns. |
| 185 | + |
| 186 | +## Integration Architecture |
| 187 | + |
| 188 | +``` |
| 189 | +┌─────────────────────────────────────────────────────────────┐ |
| 190 | +│ Development Workflow │ |
| 191 | +├─────────────────────────────────────────────────────────────┤ |
| 192 | +│ │ |
| 193 | +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ |
| 194 | +│ │ Developer │───▶│ sanctify-php │───▶│ Fix Code │ │ |
| 195 | +│ │ Writes Code │ │ (Analysis) │ │ (Guidance) │ │ |
| 196 | +│ └──────────────┘ └──────────────┘ └──────────────┘ │ |
| 197 | +│ │ │ |
| 198 | +│ ▼ │ |
| 199 | +│ ┌──────────────┐ │ |
| 200 | +│ │ php-aegis │ │ |
| 201 | +│ │ (Runtime) │ │ |
| 202 | +│ └──────────────┘ │ |
| 203 | +│ │ |
| 204 | +└─────────────────────────────────────────────────────────────┘ |
| 205 | +``` |
| 206 | + |
| 207 | +## Recommended sanctify-php Output Format |
| 208 | + |
| 209 | +When `sanctify-php` detects a vulnerability, it should suggest the `php-aegis` fix: |
| 210 | + |
| 211 | +``` |
| 212 | +VULNERABILITY: XSS in output context |
| 213 | +FILE: theme/template.php:42 |
| 214 | +CODE: echo $user_input; |
| 215 | +
|
| 216 | +RECOMMENDATION: |
| 217 | + Use php-aegis Sanitizer for proper encoding: |
| 218 | +
|
| 219 | + Before: echo $user_input; |
| 220 | + After: echo \PhpAegis\Sanitizer::html($user_input); |
| 221 | +
|
| 222 | + Install: composer require hyperpolymath/php-aegis |
| 223 | +``` |
| 224 | + |
| 225 | +## Priority Recommendations Summary |
| 226 | + |
| 227 | +| Priority | Issue | Effort | |
| 228 | +|----------|-------|--------| |
| 229 | +| P0 | Pre-built binaries / Docker image | Medium | |
| 230 | +| P0 | PHP 8.x syntax support | High | |
| 231 | +| P1 | WordPress-specific rulesets | Medium | |
| 232 | +| P1 | RDF/Turtle context detection | Medium | |
| 233 | +| P2 | IndieWeb protocol patterns | Low | |
| 234 | +| P2 | php-aegis fix suggestions in output | Low | |
| 235 | + |
| 236 | +## Contact |
| 237 | + |
| 238 | +For questions about this integration or to coordinate between repos: |
| 239 | +- php-aegis: https://github.com/hyperpolymath/php-aegis |
| 240 | +- Integration tested in: wp-sinople-theme |
| 241 | + |
| 242 | +--- |
| 243 | + |
| 244 | +*Generated from real-world WordPress semantic theme integration experience.* |
0 commit comments