> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/hacking-tools/web/php-security-scanner.md).

# PHP Security Scanner

PHP Security Scanner function finder for dangerous PHP functions, risky patterns, exploitation impact, triage notes, and remediation guidance.

PHP Security Scanner is a subscriber-only static review tool for finding dangerous PHP functions, weak configuration, risky source-to-sink paths, and privilege escalation indicators in PHP applications.

Use the function finder as the main triage view: search by function name, category, impact, or severity.

## Function Finder

<table data-view="cards" data-full-width="true" data-search="true"><thead><tr><th>Function / Pattern</th><th>Category</th><th>Severity</th><th>Impact</th><th>Scanner Check</th><th>Fix</th></tr></thead><tbody><tr><td><code>system()</code></td><td>Command execution</td><td>Critical</td><td>RCE as web user</td><td>Flag tainted command strings, interpolation, concatenation, and user-controlled arguments.</td><td>Use native PHP APIs or strict allow-listed commands and arguments.</td></tr><tr><td><code>exec()</code></td><td>Command execution</td><td>Critical</td><td>RCE, command output capture</td><td>Check whether request, cookie, DB, file, or CLI input reaches the command.</td><td>Remove shell usage or isolate fixed commands behind allow-lists.</td></tr><tr><td><code>shell_exec()</code></td><td>Command execution</td><td>Critical</td><td>RCE with returned output</td><td>Detect dynamic command construction and output rendered to responses.</td><td>Replace with safe library calls.</td></tr><tr><td><code>passthru()</code></td><td>Command execution</td><td>Critical</td><td>RCE with raw output</td><td>Escalate when reachable from web routes or file processing.</td><td>Avoid shell calls; validate fixed input sets.</td></tr><tr><td><code>proc_open()</code></td><td>Process control</td><td>Critical</td><td>RCE, process interaction</td><td>Review command, descriptor spec, environment, and working directory.</td><td>Use constrained workers and fixed command templates.</td></tr><tr><td><code>popen()</code></td><td>Process control</td><td>Critical</td><td>RCE through process stream</td><td>Flag tainted command strings and stream reads.</td><td>Replace with PHP stream/file APIs where possible.</td></tr><tr><td><code>pcntl_exec()</code></td><td>Process control</td><td>Critical</td><td>Process replacement, privesc risk</td><td>Escalate in CLI, cron, SUID, sudo, and worker contexts.</td><td>Remove privileged interpreter execution paths.</td></tr><tr><td><code>`backticks`</code></td><td>Command execution</td><td>Critical</td><td>Hidden shell execution</td><td>Detect variable interpolation inside backtick expressions.</td><td>Replace with explicit safe APIs.</td></tr><tr><td><code>eval()</code></td><td>Code execution</td><td>Critical</td><td>Arbitrary PHP execution</td><td>Flag all use; escalate when evaluated string is dynamic.</td><td>Use closures, parsers, fixed dispatch maps, or safe templates.</td></tr><tr><td><code>assert()</code></td><td>Code execution</td><td>High</td><td>Legacy code execution risk</td><td>Flag string assertions in old PHP codebases.</td><td>Use boolean assertions only; remove dynamic strings.</td></tr><tr><td><code>create_function()</code></td><td>Code execution</td><td>High</td><td>Legacy evaluated code</td><td>Detect old plugins and PHP 5/7 compatibility code.</td><td>Replace with anonymous functions.</td></tr><tr><td><code>preg_replace()</code> with <code>/e</code></td><td>Code execution</td><td>High</td><td>Legacy evaluated replacement</td><td>Flag legacy regex replacement evaluation.</td><td>Use <code>preg_replace_callback()</code>.</td></tr><tr><td><code>mb_ereg_replace()</code> with <code>e</code></td><td>Code execution</td><td>High</td><td>Evaluated replacement risk</td><td>Review dynamic patterns and replacement values.</td><td>Use callback-safe logic without evaluation.</td></tr><tr><td><code>include</code></td><td>File inclusion</td><td>Critical</td><td>LFI/RFI to code execution</td><td>Flag user-controlled paths, wrappers, and extension tricks.</td><td>Map user choices to fixed files.</td></tr><tr><td><code>include_once</code></td><td>File inclusion</td><td>Critical</td><td>LFI/RFI to code execution</td><td>Check dynamic include paths and autoload side effects.</td><td>Use fixed include maps and canonical paths.</td></tr><tr><td><code>require</code></td><td>File inclusion</td><td>Critical</td><td>Application code execution</td><td>Escalate when path contains request data.</td><td>Reject dynamic filesystem input.</td></tr><tr><td><code>require_once</code></td><td>File inclusion</td><td>Critical</td><td>Application code execution</td><td>Review framework loaders, plugin loaders, and template paths.</td><td>Use allow-listed modules only.</td></tr><tr><td><code>file_get_contents()</code></td><td>File / network read</td><td>High</td><td>LFI, SSRF, secret disclosure</td><td>Flag tainted paths, URLs, and <code>php://input</code> parsing.</td><td>Canonicalize paths and block risky schemes.</td></tr><tr><td><code>readfile()</code></td><td>File read</td><td>High</td><td>Direct file disclosure</td><td>Detect path traversal and public download handlers.</td><td>Serve files by ID from approved directories.</td></tr><tr><td><code>fopen()</code></td><td>File / network access</td><td>High</td><td>LFI, SSRF, arbitrary write</td><td>Track mode, path source, and URL wrappers.</td><td>Validate scheme, mode, and canonical path.</td></tr><tr><td><code>file()</code></td><td>File read</td><td>High</td><td>Line-based file disclosure</td><td>Flag user-controlled filenames.</td><td>Use fixed storage paths and boundary checks.</td></tr><tr><td><code>SplFileObject</code></td><td>File access</td><td>High</td><td>LFI, path traversal</td><td>Detect dynamic constructor arguments.</td><td>Apply <code>realpath()</code> boundary enforcement.</td></tr><tr><td><code>file_put_contents()</code></td><td>File write</td><td>Critical</td><td>Web shell, overwrite, config poisoning</td><td>Escalate when filename and content are tainted or path is public.</td><td>Generate filenames and write outside web root.</td></tr><tr><td><code>fwrite()</code></td><td>File write</td><td>High</td><td>Arbitrary file modification</td><td>Trace handle origin from <code>fopen()</code>.</td><td>Restrict writable directories and file types.</td></tr><tr><td><code>copy()</code></td><td>File write / move</td><td>High</td><td>File planting or overwrite</td><td>Check source and destination taint.</td><td>Use fixed destinations and collision-safe names.</td></tr><tr><td><code>rename()</code></td><td>File move</td><td>High</td><td>Upload bypass, overwrite</td><td>Flag user-controlled destination paths.</td><td>Use generated storage names.</td></tr><tr><td><code>unlink()</code></td><td>File delete</td><td>High</td><td>Arbitrary file deletion</td><td>Detect tainted paths and traversal.</td><td>Delete by object ID, not raw path.</td></tr><tr><td><code>chmod()</code></td><td>Permissions</td><td>High</td><td>Privilege weakening</td><td>Flag broad modes like <code>0777</code> and tainted paths.</td><td>Use least-privilege modes and fixed paths.</td></tr><tr><td><code>chown()</code> / <code>chgrp()</code></td><td>Ownership</td><td>High</td><td>Privilege manipulation</td><td>Review deployment and admin scripts.</td><td>Do not expose ownership changes to app input.</td></tr><tr><td><code>mkdir()</code></td><td>Filesystem</td><td>Medium</td><td>Path traversal, weak permissions</td><td>Flag dynamic paths and permissive modes.</td><td>Normalize paths and set strict permissions.</td></tr><tr><td><code>touch()</code></td><td>Filesystem</td><td>Medium</td><td>File creation, timestamp abuse</td><td>Escalate in cron or privileged directories.</td><td>Use fixed paths and ownership checks.</td></tr><tr><td><code>unserialize()</code></td><td>Deserialization</td><td>Critical</td><td>PHP object injection</td><td>Flag all use with request, cookie, upload, DB, cache, or queue data.</td><td>Use JSON or restrict <code>allowed_classes</code>.</td></tr><tr><td><code>Phar</code> / <code>phar://</code></td><td>Deserialization</td><td>High</td><td>Metadata-triggered object injection</td><td>Flag accepted <code>phar://</code> paths and file functions touching uploads.</td><td>Block wrappers and avoid object-bearing metadata paths.</td></tr><tr><td><code>__wakeup()</code></td><td>Magic method</td><td>High</td><td>Object injection gadget</td><td>Review file, SQL, command, and network actions.</td><td>Keep magic methods side-effect free.</td></tr><tr><td><code>__destruct()</code></td><td>Magic method</td><td>High</td><td>Object injection gadget</td><td>Escalate if it deletes, writes, includes, or executes.</td><td>Avoid dangerous destructor side effects.</td></tr><tr><td><code>__toString()</code></td><td>Magic method</td><td>Medium</td><td>Implicit gadget execution</td><td>Check template rendering and logging paths.</td><td>Keep conversion methods pure.</td></tr><tr><td><code>curl_exec()</code></td><td>Network / SSRF</td><td>High</td><td>SSRF, internal service access</td><td>Track URL, redirects, headers, proxy, and protocol options.</td><td>Allow-list hosts and block private ranges.</td></tr><tr><td><code>fsockopen()</code></td><td>Network</td><td>High</td><td>Raw internal network access</td><td>Flag dynamic host and port values.</td><td>Restrict destinations and egress.</td></tr><tr><td><code>pfsockopen()</code></td><td>Network</td><td>High</td><td>Persistent internal network access</td><td>Review long-lived service connections.</td><td>Use fixed endpoints.</td></tr><tr><td><code>stream_socket_client()</code></td><td>Network</td><td>High</td><td>SSRF and protocol abuse</td><td>Flag dynamic schemes, hosts, and ports.</td><td>Use allow-listed network targets.</td></tr><tr><td><code>SoapClient</code></td><td>Network</td><td>Medium</td><td>SSRF-style requests</td><td>Review dynamic WSDL and endpoint values.</td><td>Use fixed WSDLs and block redirects.</td></tr><tr><td><code>mysqli_query()</code></td><td>SQL</td><td>High</td><td>SQL injection</td><td>Flag concatenated or interpolated SQL.</td><td>Use prepared statements.</td></tr><tr><td><code>mysqli_multi_query()</code></td><td>SQL</td><td>High</td><td>Stacked SQL injection</td><td>Escalate dynamic multi-statement queries.</td><td>Avoid multi-query APIs for user-influenced data.</td></tr><tr><td><code>PDO::query()</code></td><td>SQL</td><td>High</td><td>SQL injection</td><td>Flag raw query strings containing variables.</td><td>Use <code>prepare()</code> and bound parameters.</td></tr><tr><td><code>PDO::exec()</code></td><td>SQL</td><td>High</td><td>SQL injection or destructive SQL</td><td>Review admin actions and migrations.</td><td>Use parameterized statements.</td></tr><tr><td><code>call_user_func()</code></td><td>Dynamic dispatch</td><td>High</td><td>Callback abuse</td><td>Flag tainted callback names.</td><td>Use fixed dispatch maps.</td></tr><tr><td><code>call_user_func_array()</code></td><td>Dynamic dispatch</td><td>High</td><td>Callback abuse with dynamic args</td><td>Track callback and argument sources.</td><td>Use explicit handlers and typed inputs.</td></tr><tr><td><code>$fn()</code></td><td>Variable function</td><td>High</td><td>Arbitrary function dispatch</td><td>Flag function names from request or DB data.</td><td>Map names to fixed functions.</td></tr><tr><td><code>$object->$method()</code></td><td>Dynamic method</td><td>High</td><td>Method dispatch abuse</td><td>Flag method names from input.</td><td>Use allow-listed method maps.</td></tr><tr><td><code>ReflectionFunction</code></td><td>Reflection</td><td>Medium</td><td>Dynamic invocation</td><td>Review reflected names and invocation.</td><td>Restrict reflection to internal tooling.</td></tr><tr><td><code>register_shutdown_function()</code></td><td>Deferred callback</td><td>Medium</td><td>Hidden execution path</td><td>Flag dynamic callbacks and arguments.</td><td>Use explicit fixed callbacks.</td></tr><tr><td><code>move_uploaded_file()</code></td><td>Upload</td><td>High</td><td>Web shell, overwrite, path traversal</td><td>Check destination path, extension logic, public storage, and original filename use.</td><td>Rename files, allow-list extensions, store outside web root.</td></tr><tr><td><code>getimagesize()</code></td><td>Upload validation</td><td>Medium</td><td>Weak content validation</td><td>Flag when used as the only upload validation.</td><td>Combine extension, MIME, content, and storage controls.</td></tr><tr><td><code>ZipArchive::extractTo()</code></td><td>Archive extraction</td><td>High</td><td>Zip slip, arbitrary write</td><td>Check archive entry names and extraction directory.</td><td>Canonicalize each extracted path.</td></tr><tr><td><code>phpinfo()</code></td><td>Information disclosure</td><td>Medium</td><td>Config, path, module, and environment leak</td><td>Flag if reachable outside local development.</td><td>Remove from production.</td></tr><tr><td><code>var_dump()</code> / <code>print_r()</code></td><td>Debug output</td><td>Low</td><td>Data and secret leakage</td><td>Escalate when used in responses or exception paths.</td><td>Use structured logs with redaction.</td></tr><tr><td><code>debug_backtrace()</code></td><td>Debug output</td><td>Medium</td><td>Path and argument disclosure</td><td>Review error handlers and debug routes.</td><td>Disable verbose debug output in production.</td></tr></tbody></table>

## Configuration Finder

<table data-view="cards" data-full-width="true" data-search="true"><thead><tr><th>Directive</th><th>Severity</th><th>Risk</th><th>Scanner Check</th></tr></thead><tbody><tr><td><code>disable_functions</code></td><td>High</td><td>Dangerous execution functions remain available.</td><td>Report missing or incomplete hardening, especially when command sinks exist.</td></tr><tr><td><code>open_basedir</code></td><td>Medium</td><td>PHP can access broader filesystem paths.</td><td>Flag absent, empty, or overly broad values.</td></tr><tr><td><code>allow_url_fopen</code></td><td>Medium</td><td>File APIs can fetch URLs.</td><td>Escalate URL-based file reads and SSRF-prone functions.</td></tr><tr><td><code>allow_url_include</code></td><td>Critical</td><td>Dynamic includes may load remote resources.</td><td>Critical when enabled with dynamic include paths.</td></tr><tr><td><code>display_errors</code></td><td>Medium</td><td>Stack traces, paths, and secrets may leak.</td><td>Flag enabled production configs.</td></tr><tr><td><code>expose_php</code></td><td>Low</td><td>PHP version disclosure.</td><td>Recommend disabling in production.</td></tr><tr><td><code>file_uploads</code></td><td>Info</td><td>Upload attack surface exists.</td><td>Pair with upload path, size, extension, and content validation checks.</td></tr><tr><td><code>upload_max_filesize</code></td><td>Medium</td><td>Oversized uploads and storage abuse.</td><td>Flag values larger than the application requires.</td></tr><tr><td><code>session.cookie_httponly</code></td><td>Medium</td><td>Session cookie theft via client-side script is easier.</td><td>Recommend enabled.</td></tr><tr><td><code>session.cookie_secure</code></td><td>Medium</td><td>Cookies may be sent over HTTP.</td><td>Recommend enabled on HTTPS sites.</td></tr><tr><td><code>session.cookie_samesite</code></td><td>Low</td><td>CSRF exposure may increase.</td><td>Recommend explicit <code>Lax</code> or <code>Strict</code>.</td></tr></tbody></table>

## Source-to-Sink Inputs

| Source             | Examples                                                 |
| ------------------ | -------------------------------------------------------- |
| Request            | `$_GET`, `$_POST`, `$_REQUEST`                           |
| Cookies / sessions | `$_COOKIE`, session values                               |
| Uploads            | `$_FILES`, original filenames, temp paths                |
| Headers            | `$_SERVER['HTTP_*']`, `getallheaders()`                  |
| Raw body           | `php://input`, decoded JSON/XML                          |
| CLI / workers      | `$argv`, `STDIN`, environment variables                  |
| Stored data        | Database rows, cache entries, queues, serialized columns |
| Local files        | Config files, CSV imports, temporary files               |

## Rule IDs

| Rule ID            | Severity | Meaning                                                          |
| ------------------ | -------- | ---------------------------------------------------------------- |
| `PHP-CMD-001`      | Critical | Tainted input reaches command execution.                         |
| `PHP-EVAL-001`     | Critical | Tainted input reaches PHP code evaluation.                       |
| `PHP-INCL-001`     | Critical | Tainted input controls include/require paths.                    |
| `PHP-DESER-001`    | Critical | Tainted input reaches `unserialize()`.                           |
| `PHP-WRITE-001`    | Critical | User-controlled file write reaches an executable or public path. |
| `PHP-UPLOAD-001`   | High     | Upload validation or storage can allow executable files.         |
| `PHP-SSRF-001`     | High     | Tainted URL reaches HTTP, stream, socket, or cURL sinks.         |
| `PHP-SQL-001`      | High     | Tainted input reaches raw SQL.                                   |
| `PHP-PATH-001`     | High     | Tainted path reaches file read/write/delete/move logic.          |
| `PHP-CALLBACK-001` | High     | Tainted function or method name reaches dynamic dispatch.        |
| `PHP-CONFIG-001`   | High     | Dangerous PHP configuration increases exploitability.            |
| `PHP-PRIV-001`     | Critical | PHP execution has SUID, sudo, cron, or privileged context.       |

## Quick Triage

| Question                                                                    | Severity Boost                |
| --------------------------------------------------------------------------- | ----------------------------- |
| Can request data reach the function?                                        | Raise to High or Critical.    |
| Does the function execute commands, PHP code, includes, or deserialization? | Critical.                     |
| Does it touch files under the web root?                                     | High or Critical.             |
| Does it accept URLs, wrappers, hosts, or ports?                             | High.                         |
| Does it run from cron, sudo, SUID, workers, or deployment hooks?            | Critical.                     |
| Is validation based on block-lists, extensions only, or MIME only?          | Raise one level.              |
| Is the value selected from a strict allow-list?                             | Lower confidence or severity. |

## Privilege Escalation Signals

| Signal                                  | Risk                                                  |
| --------------------------------------- | ----------------------------------------------------- |
| SUID PHP binary                         | PHP can execute with elevated file-owner privileges.  |
| Sudo rule allows PHP                    | User may run PHP as another user.                     |
| Root-owned cron runs writable PHP       | Writable script can become privileged execution.      |
| Writable web root                       | File write or upload bug can become code execution.   |
| World-readable secrets                  | App credentials can enable lateral movement.          |
| Composer scripts run as privileged user | Dependency or script execution can affect deployment. |

## Report Template

```json
{
  "id": "PHP-CMD-001",
  "severity": "critical",
  "function": "shell_exec",
  "file": "app/Controllers/ReportController.php",
  "line": 84,
  "source": "$_POST['format']",
  "impact": "Remote command execution as the web server user",
  "fix": "Replace shell execution with a native PHP library or strict allow-listed arguments."
}
```

## Scanner Checklist

* Parse `.php`, `.inc`, `.phtml`, `.module`, `.theme`, framework routes, controllers, jobs, and CLI scripts.
* Track request, cookie, upload, header, raw body, CLI, environment, database, cache, queue, and file-based input.
* Detect command execution, code execution, include, file, network, SQL, deserialization, upload, callback, debug, and configuration sinks.
* Score findings with reachability, sanitization, PHP version, configuration, web root, permissions, and execution context.
* Export function name, category, severity, source, sink, file, line, impact, confidence, and fix.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://hacking-notes.jord4n.pro/hacking-tools/web/php-security-scanner.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
