Agent skill · security · yaklang
type-juggling
PHP type juggling and weak comparison (`==`) bypass. Use when authentication, HMAC/signature checks, or token validation uses loose equality, numeric coercion, or hash comparisons without strict types — common in legacy PHP and CTF-style code paths.
Why this skill is useful
Adds specific payloads and techniques for exploiting PHP type juggling vulnerabilities that are not widely known.
What it needs
About 7k tokens when loaded. Last updated 2026-06-16. 1,563 stars on the source repository.
What this skill does
SKILL: PHP Type Juggling — Weak Comparison & Magic Hash Bypass AI LOAD INSTRUCTION: PHP == coercion, magic hashes (0e…), HMAC/hash loose checks, NULL from bad types, and CTF-style strcmp / jsondecode / intval tricks. Use strict routing: map the sink (== vs hashequals), PHP major version, and whether both operands are attacker-controlled. Routing note: when you encounter PHP login/signature logic or code like md5($GET['x'])==md5($GET['y']), start with this skill; if hashequals/=== is already used, this path usually does not apply. 0. QUICK START First-pass goal: prove the server branch treats unequal secrets/tokens as equal via coercion, not guess the real password. First-pass payloads (auth / token shape) Minimal PHP probes (local or php -r in lab) Routing hints Clue Next step --- --- Source code uses == to compare passwords, tokens, or HMAC values Go to Sections 1-3 md5($a) == md5($b) or loose sha1 comparison Section 2 magic hashes hashhmac(...) != '0' or compared with "0" Section 3 strcmp、jsondecode(..., true)、intval Section 5 --- 1. LOOSE COMPARISON (==) — TRUTH TABLE & VERSIONS PHP compares operands with type juggling unless you use === or hashequals() for secrets. 1.1 Core examples (strings vs numbers) Expression Result Mechanism (short) --- --- --- '0010e2' == '1e3' true Both strings look numeric → compared as floats; both parse to 1000.0 (not zero — common exam trap; see next row for real “both zero”) '0e462097431906509019562988736854' == '0e830400451993494058024219903391' true Both parse as 0.0 in scientific notation '123a' == 123 true String cast to int stops at first non-digit → 123 'abc' == 0 true (PHP 7.x and earlier) Non-numeric string compared to int → string becomes 0 '' == 0 true Empty string → 0 '' == false true both “falsy” in loose rules false == NULL true loose equality 0 == false true loose equality '' == 0 == false == NULL true (chain) Each adjacent pair is true under == (''==0, 0==false, false==NULL) — classic “falsy” chain '0' == false true S …
How to use it
Reference it in AdaL, Claude Code, Cursor or any coding agent — nothing to install:
@skills yaklang/type-juggling