roots / acorn

Laravel components for WordPress plugins and themes
https://roots.io/acorn/
MIT License
815 stars 94 forks source link

The captured request data is slashed because of the insanity that is wp_magic_quotes() #408

Open stefanfisk opened 2 weeks ago

stefanfisk commented 2 weeks ago

Version

v4.3.0

What did you expect to happen?

I expected the captured request data to not be slashed because the whole idea of wp_magic_quotes is crazy.

https://core.trac.wordpress.org/ticket/18322

What actually happens?

The captured request data is slashed.

AFAICT this seems like the most appropriate fix:

// Undo wp_magic_quotes()

$_GET     = stripslashes_deep($_GET);
$_POST    = stripslashes_deep($_POST);
$_COOKIE  = stripslashes_deep($_COOKIE);
$_SERVER  = stripslashes_deep($_SERVER);
$_REQUEST = array_merge($_GET, $_POST);

// Capture request

$request = Request::capture();

// Redo wp_magic_quotes()

wp_magic_quotes();

Here's a custom bootstrap workaround that seems OK after minimal testing:

<?php

declare(strict_types=1);

namespace App\Bootstrap;

use Illuminate\Contracts\Foundation\Application;
use Illuminate\Http\Request;

class UndoWpMagicQuotes
{
    public function bootstrap(Application $app): void
    {
        /** @var Request $request */
        $request = $app->make('request');

        $request->query->replace(stripslashes_deep($_GET));
        $request->request->replace(stripslashes_deep($_POST));
        $request->cookies->replace(stripslashes_deep($_COOKIE));
        $request->server->replace(stripslashes_deep($_SERVER));
    }
}

Steps to reproduce

  1. Make a request to /?foo=\
  2. Call app('request')->get('foo')
  3. Watch the returned value be \\

System info

php:8.1-fpm docker image under Pop!_OS 22.04 LTS.

Log output

No response

Please confirm this isn't a support request.

Yes

stefanfisk commented 2 weeks ago

That workaround breaks request when it's derived from the request body.

Here's a fixed version:

<?php

declare(strict_types=1);

namespace App\Bootstrap;

use Illuminate\Contracts\Foundation\Application;
use Illuminate\Http\Request;

use function array_merge;

/**
 * Workaround for wp_magic_quotes() being applied to the captured request.
 *
 * @see https://github.com/roots/acorn/issues/408
 */
class UndoWpMagicQuotes
{
    public function bootstrap(Application $app): void
    {
        // Undo wp_magic_quotes()

        $_GET     = stripslashes_deep($_GET);
        $_POST    = stripslashes_deep($_POST);
        $_COOKIE  = stripslashes_deep($_COOKIE);
        $_SERVER  = stripslashes_deep($_SERVER);
        $_REQUEST = array_merge($_GET, $_POST);

        // Capture request

        $tempRequest = Request::capture();

        // Replace bound data

        /** @var Request $request */
        $request = $app->make('request');

        $request->query->replace($tempRequest->query->all());
        $request->request->replace($tempRequest->request->all());
        $request->cookies->replace($tempRequest->cookies->all());
        $request->server->replace($tempRequest->server->all());

        // Redo wp_magic_quotes()

        wp_magic_quotes();
    }
}