Still having problems with Slim CSRF – different approach [SOLVED]


#1

Hi,

I done a rewrite of the Slim CSRF and ended up with the same results… as my Dad use to say give-up not an option. Im missing something
Do i still need to add guard to middleware?

Controller stack dump


Container {#12 ▼
  -singletonEntries: array:33 [▶]
  -definitionSource: SourceChain {#9 ▶}
  -definitionResolver: ResolverDispatcher {#13 ▶}
  -definitionCache: array:31 [▼
    "router" => ObjectDefinition {#62 ▶}
    "settings.routerCacheFile" => ValueDefinition {#74 ▶}
    "settings" => ArrayDefinition {#72 ▶}
    "settings.httpVersion" => ValueDefinition {#75 ▶}
    "settings.responseChunkSize" => ValueDefinition {#76 ▶}
    "settings.outputBuffering" => ValueDefinition {#77 ▶}
    "settings.determineRouteBeforeAppMiddleware" => ValueDefinition {#78 ▶}
    "settings.displayErrorDetails" => ValueDefinition {#79 ▶}
    "settings.addContentLengthHeader" => ValueDefinition {#80 ▶}
    "callableResolver" => ObjectDefinition {#93 ▶}
    "Invoker\CallableResolver" => ObjectDefinition {#100 ▶}
    "Interop\Container\ContainerInterface" => AliasDefinition {#107 ▶}
    "response" => FactoryDefinition {#129 ▶}
    "request" => FactoryDefinition {#137 ▶}
    "environment" => FactoryDefinition {#138 ▶}
    "Slim\Views\Twig" => FactoryDefinition {#140 ▼
      -name: "Slim\Views\Twig"
      -scope: null
      -factory: Closure {#22 ▼
        class: "DI\Definition\Source\DefinitionFile"
        this: DefinitionFile {#7}
        parameters: {▼
          $c: {▼
            typeHint: "Interop\Container\ContainerInterface"
          }
        }
        file: "/mnt/h/www/pfa2.local/config/container.php"
        line: "31 to 44"
      }
      -parameters: []
    }
    "Ti\Support\Csrf\SlimCsrf" => FactoryDefinition {#165 ▼
      -name: "Ti\Support\Csrf\SlimCsrf"
      -scope: null
      -factory: Closure {#24 ▶}
      -parameters: []
    }
    "Slim\Csrf\Guard" => FactoryDefinition {#169 ▼
      -name: "Slim\Csrf\Guard"
      -scope: null
      -factory: Closure {#23 ▶}
      -parameters: []
    }
    "Ti\Support\Basket\Basket" => FactoryDefinition {#166 ▶}
    "Ti\Support\Storage\Contracts\StorageInterface" => FactoryDefinition {#173 ▶}
    "Ti\Models\Product" => FactoryDefinition {#171 ▶}
    "Slim\Flash\Messages" => FactoryDefinition {#168 ▶}
    "Ti\Support\Connection\CheckImg" => FactoryDefinition {#176 ▶}
    "Ti\Support\Auth\Auth" => FactoryDefinition {#179 ▶}
    "Ti\Controllers\CsrftestController" => ObjectDefinition {#149 ▼
      -name: "Ti\Controllers\CsrftestController"
      -className: null
      -constructorInjection: MethodInjection {#202 ▼
        -methodName: "__construct"
        -parameters: array:7 [▼
          0 => EntryReference {#196 ▼
            -name: "Slim\Views\Twig"
          }
          1 => EntryReference {#195 ▼
            -name: "Slim\Router"
          }
          2 => EntryReference {#197 ▼
            -name: "Psr\Http\Message\ResponseInterface"
          }
          3 => EntryReference {#198 ▼
            -name: "Psr\Http\Message\ServerRequestInterface"
          }
          4 => EntryReference {#199 ▼
            -name: "Ti\Support\Validation\Contracts\ValidatorInterface"
          }
          5 => EntryReference {#200 ▼
            -name: "Ti\Support\Auth\Auth"
          }
          6 => EntryReference {#201 ▼
            -name: "Slim\Flash\Messages"
          }
        ]
      }
      -propertyInjections: []
      -methodInjections: []
      -scope: null
      -lazy: null
      -classExists: true
      -isInstantiable: true
    }
    "Slim\Router" => AliasDefinition {#203 ▶}
    "Psr\Http\Message\ResponseInterface" => FactoryDefinition {#204 ▶}
    "Psr\Http\Message\ServerRequestInterface" => FactoryDefinition {#205 ▶}
    "Ti\Support\Validation\Contracts\ValidatorInterface" => FactoryDefinition {#206 ▶}
    "foundHandler" => ObjectDefinition {#188 ▶}
    "foundHandler.invoker" => FactoryDefinition {#183 ▶}
  ]
  -entriesBeingResolved: []
  -invoker: null
  -wrapperContainer: Container {#12}
}

dump out of twig…

array(3) { ["keys"]=> array(2) { ["name"]=> string(9) "csrf_name" ["value"]=> string(10) "csrf_value" } ["name"]=> NULL ["value"]=> NULL }

File : container.php
Im adding a twig extention to twig


return [RouterInterface::class => function (ContainerInterface $container) {
        return $container->get('router');
    },
    // PS... Disable debug = true and Twig_Extension_Debug - use only for debuging 
    Twig::class => function (ContainerInterface $c) {
        $twig = new Twig(__DIR__ . '/../twig/views', ['cache' => false, 'debug' => true,]);
        $twig->addExtension(new TwigExtension($c->get('router'), $c->get('request')->getUri()));
        $twig->addExtension(new Twig_Extension_Debug());
        $twig->addExtension($c->get(SlimCsrf::class));
        $twig->getEnvironment()->addGlobal('basket', $c->get(Basket::class));
        $twig->getEnvironment()->addGlobal('flash', $c->get(Messages::class));
        $twig->getEnvironment()->addGlobal('checkimg', $c->get(CheckImg::class));
        $twig->getEnvironment()->addGlobal('auth', [
            'check' => $c->get(Auth::class)->check(),
            'user' => $c->get(Auth::class)->user(),
        ]);
        return $twig;
    },
    // Creating the Guard class
    Guard::class => function (ContainerInterface $c){
        return new \Slim\Csrf\Guard();
    },  
     // add the global settings
    SlimCsrf::class => function (ContainerInterface $c){
           return new SlimCsrf($c->get(Guard::class));
    }, 

file SlimCsrf.php

namespace Ti\Support\Csrf;
use Slim\Csrf\Guard;
use Twig\Extension\AbstractExtension;
use Twig\Extension\GlobalsInterface;

class SlimCsrf extends AbstractExtension implements GlobalsInterface
{

    protected $csrf;

    public function __construct(Guard $csrf) {
        $this->csrf = $csrf;
    }

    public function getGlobals() {
        // CSRF token name and value
        $csrfNameKey = $this->csrf->getTokenNameKey();
        $csrfValueKey = $this->csrf->getTokenValueKey();
        $csrfName = $this->csrf->getTokenName();
        $csrfValue = $this->csrf->getTokenValue();

        return [
            'csrf' => [
                'keys' => [
                    'name' => $csrfNameKey,
                    'value' => $csrfValueKey
                ],
                'name' => $csrfName,
                'value' => $csrfValue
            ]
        ];
    }

}

twig file.

<form action="{{ path_for('csrfpost') }}" method="post">

            <h4> This test csrf... if you refresh page it will give error... (Not allowed to refresh page)</h4>
            </br> </br> </br>

            <input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
            <input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">

            {{  dump(csrf| raw)  }} 
            
            <button type="submit">Update</button>
            
        </form>

The container dump was done within the this controller as displayed
file:csrttestcontroller.php extends basecontroller


amespace Ti\Controllers;
use Interop\Container\ContainerInterface;
class CsrftestController extends BaseController
{

    public function get(ContainerInterface $c) {

        dump($c);
        // dump($c->get('Slim\Csrf\Guard'));
        //return $this->view($this->response,'testcsrf/testcsrf');
        return $this->render('testcsrf/testcsrf');
    }

    public function post() {
        return 'test csrf post... after update button was pressed';
    }

}

File BaseController.

namespace Ti\Controllers;

use Ti\Support\Auth\Auth;
use Ti\Support\Validation\Contracts\ValidatorInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Flash\Messages;
use Slim\Router;
use Slim\Views\Twig;

class BaseController
{

    protected $auth;
    protected $flash;
    protected $request;
    protected $response;
    protected $router;
    protected $validator;
    protected $view;

    public function __construct(Twig $view, Router $router, Response $response, Request $request, ValidatorInterface $validator, Auth $auth, Messages $flash) {
        $this->view = $view;
        $this->router = $router;
        $this->response = $response;
        $this->request = $request;
        $this->validator = $validator;
        $this->auth = $auth;
        $this->flash = $flash;
    }

    protected function render($template, array $data = []) {
        $view = str_replace('.', '/', $template);
        $view .= '.twig';
        return $this->view->render($this->response, $view, $data);
    }

    protected function redirect($path) {
        return $this->response->withRedirect($this->router->pathFor($path));
    }

}

#2

Solution : I never linked / register Slim\Csrf to a route or register it via middleware to all routes,