Skip to content
Security
Skill

/auditing-php-applications

Audit PHP web application source for critical vulnerabilities using PHP's specific sink and footgun catalog — object injection via unserialize and phar:// POP chains, type-juggling and magic-hash auth bypass, LFI/RFI through php:// and phar:// wrappers, dynamic includes and

BOOST
From plugin
secskills
17094 skills
Install
$ npx -y skills add trilwu/secskills --skill auditing-php-applications --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/auditing-php-applications

Context preview

The summary Claude sees to decide when to auto-load this skill.

Audit PHP web application source for critical vulnerabilities using PHP's specific sink and footgun catalog — object injection via unserialize and phar:// POP chains, type-juggling and magic-hash auth bypass, LFI/RFI through php:// and phar:// wrappers, dynamic includes and

SKILL.md

auditing-php-applications.SKILL.md
name: auditing-php-applications
description: Audit PHP web application source for critical vulnerabilities using PHP's specific sink and footgun catalog — object injection via unserialize and phar:// POP chains, type-juggling and magic-hash auth bypass, LFI/RFI through php:// and phar:// wrappers, dynamic includes and extract()/superglobal trust, SQL injection in string-built and legacy mysql_* queries, command-execution sinks, and SSRF. Use when reviewing a PHP codebase, a WordPress/Magento/Laravel app, or a plugin for exploitable bugs. Defers general audit methodology to auditing-code-for-vulnerabilities.
verified: 2026-07-27

Auditing PHP Applications

This is the PHP-specific layer on top of `auditing-code-for-vulnerabilities`. Take the methodology from that skill — context → attack surface → bug-class hunt → variant analysis → the four-question verification gate — and apply the PHP sink catalog below to it. This skill exists because PHP has footguns no language-agnostic methodology carries: features that turn a file read into remote code execution, and comparison rules that turn `==` into an auth bypass.

The collection deliberately has no per-language audit skills except this one. PHP earns the exception because it dominates the legacy-web and WordPress/Magento space where critical bugs actually live, and because its dynamic features fail in ways a reviewer must be primed for specifically.

When to Use

  • Reviewing a PHP codebase or plugin for exploitable vulnerabilities
  • Auditing a WordPress, Magento, Joomla, or Laravel application's source
  • Tracing a suspected RCE, LFI, SQLi, or object-injection path in PHP
  • Deciding whether a `unserialize`, `include`, or `==` on user input is exploitable

When NOT to Use

  • **General audit methodology, or a non-PHP language** — use

`auditing-code-for-vulnerabilities`; this skill assumes it

  • **Finding a planted webshell or backdoor** rather than a vulnerability — use

`hunting-web-backdoors`

  • **Building the deserialization exploit chain** once you have the sink — use

`exploiting-deserialization`

  • **Black-box testing a running app** — use `testing-web-applications`
  • **Reviewing only the diff of a change** — use `reviewing-code-changes`

Sinks by Bug Class

Trace user input (superglobals, headers, uploaded filenames, DB values that were once user input) to each of these. A sink is only a bug when a source reaches it.

Remote code execution

  • **Direct eval sinks:** `eval`, `assert` (string arg, pre-8.0),

`preg_replace` with `/e` (pre-7.0), `create_function` (pre-8.0), `mb_ereg_replace`/`mb_eregi_replace` with the `e` option.

  • **Command execution:** `system`, `exec`, `passthru`, `shell_exec`, backticks,

`proc_open`, `popen`, `pcntl_exec`. Watch `escapeshellarg` vs `escapeshellcmd` misuse — `escapeshellcmd` does **not** prevent argument injection.

  • **Dynamic dispatch:** `$func()` where `$func` derives from input,

`call_user_func`/`call_user_func_array`, `array_map`/`usort`/ `preg_replace_callback` with a user-influenced callback.

Object injection (the PHP-defining bug)

  • `unserialize()` on any user-controlled data is object injection. Exploitation

is a **POP chain**: existing classes with `__wakeup`, `__destruct`, `__toString`, or `__call` magic methods that do something dangerous when the object is materialized. The vulnerable file often contains no dangerous code at all — the gadget lives in a framework or dependency.

  • **`phar://` is unserialize in disguise — but version-gated.** On **PHP

before 8.0**, any file operation (`file_exists`, `fopen`, `include`, `getimagesize`, …) on a `phar://` path automatically deserializes the Phar's metadata, so a path-traversal or LFI that points a file function at an uploaded `.phar` (or any file carrying Phar metadata) is object injection with no `unserialize` call in sight. **PHP 8.0 removed that automatic unserialize** — only explicit `Phar::getMetadata()` deserializes now. So the bug is critical on the huge installed base of PHP 7.x and a non-issue on 8.x unless the code calls `getMetadata()` itself. Check the runtime version before ruling it in or out.

  • Prefer `json_decode` in remediation; flag every `unserialize` on non-trusted

data regardless of an obvious gadget — the gadget may arrive with the next dependency update.

LFI / RFI and stream wrappers

  • `include`, `require`, `include_once`, `require_once` with user input.
  • **Wrappers that change everything:** `php://filter/...` (read source, and a

known RCE chain via `convert.iconv`/compression filters), `php://input` (RFI-style body inclusion), `data://` (inline payload), `phar://` (object injection), `expect://`, `zip://`. `allow_url_include` being on turns LFI into remote RFI.

  • File-read sinks (`file_get_contents`, `readfile`, `fopen`, `highlight_file`)

with traversal give source and secret disclosure.

SQL injection

  • Legacy `mysql_query`/`mysqli_query` with string-concatenated input.
  • `$wpdb->query("... $var ...")` **without** `$wpdb->prepare()` — a `->prepare`

that is present but interpolates outside its placeholders is still injectable.

  • PDO/mysqli used with string building instead of bound parameters. Placeholder

usage on the *table/column* name (which cannot be bound) is a common real hole.

Type juggling and magic-hash auth bypass

  • **`==` and `!=` are loose.** `strcmp`/`hash_equals`/`===` are the safe forms.

The classic bypass: `if (md5($input) == $stored)` where two inputs both hash to a `0e[0-9]+` "magic hash" compare equal, because two numeric strings compare as numbers (`0e123 == 0e456` → `0.0 == 0.0`).

  • **Version matters and it is a trap.** In PHP 8.0 the number-vs-string rules

changed: `0 == "foo"` was `true` in PHP 7 and is `false` in PHP 8, so a `in_array(0, $userStrings)` or `0 == $token` bypass that worked on PHP 7 fails on PHP 8. **But the `0e` magic-hash bypass survives PHP 8**, because both sides are

Read more
Ships withsecskills

**Security skills for Claude Code that encode the judgment professionals bring, not another wrapper around a scanner.** Offense, defense, and the reverse-engineering and code-audit core both sides share. Every skill is fact-checked against primary sources.

Get the whole plugin

Other skills on secskills.