AgentStack
SKILL unreviewed Apache-2.0 Self-run

Eresus Php Audit

skill-eresussecurity-appsec-skills-eresus-php-audit · by EresusSecurity

>

No reviews yet
0 installs
11 views
0.0% view→install

Install

$ agentstack add skill-eresussecurity-appsec-skills-eresus-php-audit

Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Dangerous shell/eval execution.

What it can access

  • Network access No
  • Filesystem access Used
  • Shell / process execution Used
  • Environment & secrets Used
  • Dynamic code execution Used

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Eresus Php Audit? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

PHP Security Audit

Purpose

Perform a comprehensive, depth-first security audit of PHP codebases. This skill provides the complete knowledge of Kunlun-M's CVI rule set, organized by vulnerability class, plus framework-specific patterns for Laravel, WordPress, Symfony, and modern PHP 8.x applications.

Use view_file and grep_search exclusively. No terminal commands.


Audit Workflow

Phase 1: Reconnaissance

  1. Identify the PHP framework/CMS (Laravel, WordPress, Symfony, CodeIgniter, raw PHP)
  2. Check composer.json / composer.lock for known vulnerable dependencies
  3. Map entry points: routes, controllers, REST endpoints, admin pages, AJAX handlers
  4. Identify the autoloader and class loading mechanism
  5. Check PHP version requirements (php constraint in composer.json)

Phase 2: Entry Point Discovery

Inspired by Kunlun-M's EntranceFinder plugin — systematically find all user-facing entry points:

  1. Direct file access — find all .php files that can be accessed directly (not included/required)
  2. Route definitions — check framework routing files
  3. AJAX handlers — WordPress wp_ajax_*, Laravel API routes, custom handlers
  4. CLI entry — Artisan commands, WP-CLI commands, custom scripts
  5. Cron jobs — scheduled tasks that process external data

Search patterns for entry points:

  • Files with $_GET, $_POST, $_REQUEST, $_FILES, $_COOKIE, $_SERVER
  • Files with file_get_contents('php://input')
  • Laravel: Route::get, Route::post, Route::any, Route::resource
  • WordPress: add_action('wp_ajax_, add_action('rest_api_init
  • Symfony: #[Route(, @Route(, routing.yaml definitions

CVI Rules — Injection

CVI-1001: SSRF

Search for HTTP request functions with user-controlled URLs:

curl_setopt($ch, CURLOPT_URL, $userInput)
file_get_contents($userUrl)
fopen($userUrl, 'r')
$client->get($userInput)  // Guzzle
$client->request('GET', $userInput)

Severity: HIGH — can lead to internal service access, cloud metadata theft Trace: Check if URL comes from $_GET, $_POST, database with user data

CVI-1002: SQL Injection

Search for raw SQL construction:

$db->query("SELECT * FROM users WHERE id = " . $_GET['id'])
$wpdb->query("SELECT * FROM $table WHERE id = $id")
$pdo->query("SELECT ... $var ...")
mysqli_query($conn, "... $var ...")

Safe patterns: $pdo->prepare(), $wpdb->prepare(), Eloquent query builder Severity: CRITICAL when user input reaches query without parameterization

CVI-1003: Command Injection

Search for shell execution functions:

system($userInput)
exec($userInput)
passthru($userInput)
shell_exec($userInput)
`$userInput`  (backticks)
popen($userInput, 'r')
proc_open($userInput, ...)
pcntl_exec($userInput)

Severity: CRITICAL — always results in RCE if input is user-controlled

CVI-1004: Code Injection

Search for dynamic code execution:

eval($userInput)
assert($userInput)  // PHP 
print($userInput)
printf("%s", $userInput)  // in HTML context

Safe patterns: htmlspecialchars($var, ENT_QUOTES, 'UTF-8'), esc_html() (WP), {{ $var }} (Blade) Dangerous: {!! $var !!} (Laravel Blade raw), | raw (Twig)

CVI-1006: File Inclusion (LFI/RFI)

include($userInput)
include_once($userInput)
require($userInput)
require_once($userInput)

Severity: CRITICAL if path is user-controlled Check: Is allow_url_include enabled? (RFI)

CVI-1007: File Operations

file_get_contents($userInput)     // path traversal read
file_put_contents($userInput, $data)  // arbitrary file write
unlink($userInput)                // arbitrary file delete
copy($src, $userInput)            // arbitrary file placement
rename($old, $userInput)          // arbitrary file move
readfile($userInput)              // information disclosure

Severity: HIGH to CRITICAL depending on operation

CVI-1008: XML External Entity (XXE)

$doc = new DOMDocument()
$doc->loadXML($userInput)              // XXE if no protection
simplexml_load_string($userInput)       // XXE
$reader = new XMLReader()
$reader->xml($userInput)               // XXE

Safe: libxml_disable_entity_loader(true) (deprecated PHP 8.0+, secure by default)


CVI Rules — Deserialization

CVI-2001: PHP Object Injection

unserialize($userInput)
unserialize($_COOKIE['data'])
unserialize(base64_decode($_GET['data']))

Severity: CRITICAL — Property-Oriented Programming (POP) chain exploitation Gadget hunting: Search for classes with:

  • __wakeup() — called on deserialization
  • __destruct() — called on object destruction
  • __toString() — called on string cast
  • __call() — called on undefined method
  • __get() / __set() — called on property access

CVI-2002: PHP Unserialize Chain Discovery

Kunlun-M's phpunserializechain plugin methodology — trace POP chains:

  1. Find the entry sink: unserialize() with user input
  2. Find gadget classes: Classes with magic methods that perform I/O
  3. Trace the chain: __destruct() → calls method → file write / command exec
  4. Popular chains:
  • Laravel: PendingBroadcast__destruct()dispatch()
  • Symfony: Process__destruct()stop() → command execution
  • WordPress: Various plugin-specific chains
  • Monolog: BufferHandler__destruct()close() → arbitrary write

CVI Rules — Authentication & Authorization

CVI-3001: Authentication Bypass

// Weak comparison
if ($_POST['password'] == $storedPassword)  // type juggling: "0" == 0
if (md5($_POST['password']) == $storedHash)  // magic hash: "0e..." == 0

// Missing auth check
// Check if sensitive functions lack is_admin(), current_user_can(), auth check

Key pattern: == vs === for authentication — PHP type juggling attack

CVI-3002: Session & Cookie Security

session_set_cookie_params(['secure' => false])
setcookie($name, $value)  // missing secure, httponly, samesite flags
$_SESSION['admin'] = $_POST['is_admin']  // user-controlled session data
session_id($_GET['sessid'])  // session fixation

CVI-3003: CSRF

// Missing CSRF token verification
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // No token check before processing
}

// WordPress: Missing nonce verification
// check_ajax_referer() missing
// wp_verify_nonce() missing

CVI Rules — Configuration & Information Disclosure

CVI-4001: Information Disclosure

phpinfo()
error_reporting(E_ALL)
display_errors = On
var_dump($sensitiveData)
print_r($debug)

CVI-4002: Hardcoded Secrets

$password = "hardcoded"
$apiKey = "sk_live_..."
$dbPassword = "root"
define('DB_PASSWORD', 'actual_password')

CVI-4003: Dangerous PHP Configuration

allow_url_fopen = On      // enables RFI via include()
allow_url_include = On    // enables remote file inclusion
expose_php = On           // version disclosure
register_globals = On     // variable injection (legacy)
magic_quotes_gpc = Off    // no auto-escaping (legacy)
open_basedir               // check if properly set
disable_functions          // check if dangerous funcs are disabled

Framework-Specific Deep Checks

Laravel

  • Check .env file exposure (web-accessible .env)
  • Check APP_DEBUG=true in production
  • Check APP_KEY rotation
  • Check for {!! !!} raw Blade output with user data
  • Check Eloquent mass assignment: $fillable vs $guarded
  • Check Gate/Policy authorization on controllers
  • Check Route::any() over-permissive routing
  • Check file upload handling: stored path, extension validation
  • Check queue job deserialization (jobs are serialized/unserialized)

WordPress

  • Check for direct file access without defined('ABSPATH') check
  • Check $wpdb->prepare() usage (must use %s, %d placeholders)
  • Check update_option() / add_option() with user input
  • Check wp_remote_get() / wp_remote_post() for SSRF
  • Check is_admin() (checks admin page, NOT admin privilege — use current_user_can())
  • Check nonce verification on all form handlers
  • Check esc_html(), esc_attr(), esc_url(), wp_kses() usage
  • Check REST API permission callbacks (permission_callback must not be __return_true for sensitive data)
  • Check sanitize_text_field(), absint(), wp_unslash() input sanitization

Symfony

  • Check @Route with missing security annotations
  • Check Twig | raw filter with user data
  • Check kernel.debug in production
  • Check voter/access decision manager configuration
  • Check CSRF token service usage

Supply Chain Checks

Composer Dependencies

  • Check composer.lock for known CVEs (compare against advisories)
  • Check for abandoned packages
  • Check for packages with eval(), system(), exec() in install scripts
  • Check post-install/post-update scripts in composer.json

Red Flags Checklist

  • [ ] Any use of unserialize() with external data
  • [ ] Any use of eval(), assert(), create_function()
  • [ ] == comparison for authentication/authorization
  • [ ] $_GET/$_POST directly in SQL queries
  • [ ] $_GET/$_POST in include()/require()
  • [ ] File operations with user-controlled paths
  • [ ] echo/print of user input without encoding
  • [ ] Missing CSRF token verification on state-changing actions
  • [ ] APP_DEBUG=true or display_errors=On in production
  • [ ] Hardcoded credentials in source code
  • [ ] allow_url_include enabled
  • [ ] WordPress: is_admin() used for privilege checks (wrong function)
  • [ ] Laravel: {!! $userInput !!} in Blade templates

Report Format

For each finding, report:

### CVI-[ID]: [Vulnerability Class]

**Severity**: [LOW/MEDIUM/HIGH/CRITICAL]
**Confidence**: [LOW/MEDIUM/HIGH]
**File**: [path]:[line]

**Vulnerable Code**:
[show the code]

**Data Flow**:
[source] → [intermediaries] → [sink]

**Impact**: [what an attacker achieves]
**Remediation**: [specific fix with code example]
**CVI Reference**: CVI-[xxxx]

Tooling Constraints

Use ONLY:

  • view_file — read source code
  • grep_search — find patterns across the codebase

Do NOT use any terminal commands.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.