Skip to content

Commit

Permalink
add samesite csrf protection to sessionMiddleware, csp + cors middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
killua-eu committed Dec 4, 2019
1 parent 0cbe2ce commit 5e70173
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 12 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ The glue that keeps stuff together in Glued. To all microservices, core provides
- content-addressable file storage (CAS)
- internationalization
- assets management and caching
- (some of the) security
- CSRF prevention (session cookie) via the SessionMiddleware;
- TODO / CSRF prevention (other cookies) - hack this https://github.com/selective-php/samesite-cookie/blob/master/src/SameSiteCookieMiddleware.php
- CSP prevention
- XSS prevention

### Spider

Expand Down
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
"php": "^7.3",
"slim/slim": "^4.3",
"slim/twig-view": "3.0.0-beta",
"slim/csrf": "^1.0.0",
"slim/flash": "^0.4.0",
"slim/http": "^0.8",
"nyholm/psr7": "^1.1",
Expand All @@ -50,7 +49,10 @@
"granam/czech-vocative": "^2.0",
"dfridrich/ares": "^1.2",
"spatie/browsershot": "^3.33",
"google/apiclient": "^2.4"
"google/apiclient": "^2.4",
"php-imap/php-imap": "^3.0",
"tuupola/cors-middleware": "^1.1",
"middlewares/csp": "^3.0"
},
"scripts": {
"start": "php -S localhost:8080 -t public",
Expand Down
19 changes: 19 additions & 0 deletions glued/Core/Middleware/SessionMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
*/
final class SessionMiddleware implements MiddlewareInterface
{

protected $settings;
public function __construct($settings)
{
$this->settings = $settings;
}

/**
* Invoke middleware.
*
Expand All @@ -20,6 +27,18 @@ final class SessionMiddleware implements MiddlewareInterface
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if (session_status() !== PHP_SESSION_ACTIVE) {

if (ini_get('session.use_cookies')) {
$ini_defs = session_get_cookie_params();
}
session_set_cookie_params([
'lifetime' => $this->settings['glued']['session_cookie_lifetime'],
'path' => $ini_defs['path'],
'domain' => $ini_defs['domain'],
'secure' => $this->settings['glued']['session_cookie_secure'],
'httponly' => $this->settings['glued']['session_cookie_httponly'],
'samesite' => $this->settings['glued']['session_cookie_samesite'],
]);
session_start();
}
$response = $handler->handle($request);
Expand Down
1 change: 0 additions & 1 deletion glued/Core/Views/signup.twig
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">{{ __('Sign up') }}</button>
{{ csrf.field | raw }}
</div>
</form>
</div>
Expand Down
7 changes: 7 additions & 0 deletions glued/Core/Views/templates/default.twig
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@
<li><a class="nav-link" href="#">Statistics</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="nav-link has-dropdown" data-toggle="dropdown"><i class="fas fa-mail-bulk"></i> <span>Mail</span></a>
<ul class="dropdown-menu">
<li><a class="nav-link" href="{{ url_for('mail.accounts.web') }}">{{ __('Accounts') }}</a></li>
<li><a class="nav-link" href="{{ url_for('mail.opera.web') }}">{{ __('Opera') }}</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="nav-link has-dropdown" data-toggle="dropdown"><i class="fas fa-spider"></i> <span>Spider</span></a>
<ul class="dropdown-menu">
Expand Down
27 changes: 27 additions & 0 deletions glued/Mail/Controllers/MailController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Glued\Mail\Controllers;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Glued\Core\Controllers\AbstractTwigController;
use Respect\Validation\Validator as v;

class MailController extends AbstractTwigController
{
/**
* @param Request $request
* @param Response $response
* @param array $args
*
* @return Response
*/
public function __invoke(Request $request, Response $response, array $args = []): Response
{
return $this->render($response, 'Mail/Views/opera.twig', [
'pageTitle' => 'Opera',
]);
}
}
21 changes: 21 additions & 0 deletions glued/Mail/Views/opera.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{% extends '/Core/Views/templates/default.twig' %}

{% block content %}
<section class="section">
<div class="section-header">
<h1>{{ __('Hello, dear') }} {{ name | default(__('Anonymous')) }}</h1>
</div>

<div class="section-body">
{{ __('Let\'s stick together.') }}
<form id="spider_browse_fetch" onsubmit="changeUri()">
<input type="text" name="uri">
<input type="submit" value="Fetch">
</form>
<br />
uri: <a href="{{ uri }}">{{ uri }}</a> <br />
uri valid: {{ validate }} <br />
<img width="300" src="{{ screenshot }}">
</div>
</section>
{% endblock %}
13 changes: 13 additions & 0 deletions glued/Mail/routes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
use Slim\Routing\RouteCollectorProxy;
use Glued\Mail\Controllers\MailController;
use Glued\Core\Middleware\RedirectIfAuthenticated;
use Glued\Core\Middleware\RedirectIfNotAuthenticated;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

// Define the app routes.
$app->group('/mail', function (RouteCollectorProxy $group) {
$group->get ('/accounts[/{uri}]', MailController::class)->setName('mail.accounts.web'); // ->add(new RedirectIfNotAuthenticated());
$group->get ('/opera[/{uri}]', MailController::class)->setName('mail.opera.web'); // ->add(new RedirectIfNotAuthenticated());
});
5 changes: 4 additions & 1 deletion glued/container.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php

use DI\Container;
use Glued\Core\Classes\Users;
use Glued\Core\Middleware\TranslatorMiddleware;
use DI\Container;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Monolog\Processor\UidProcessor;
Expand All @@ -11,6 +11,7 @@
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;
use Slim\App;
use Slim\Csrf\Guard;
use Slim\Factory\AppFactory;
use Slim\Flash\Messages;
use Slim\Interfaces\RouteParserInterface;
Expand Down Expand Up @@ -57,6 +58,8 @@
return new Glued\Core\Classes\Validation\Validator;
});



$container->set('routerParser', $app->getRouteCollector()->getRouteParser());


Expand Down
28 changes: 23 additions & 5 deletions glued/middleware.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
<?php

use DI\Container;
use Glued\Core\Middleware\LocaleSessionMiddleware;
use Glued\Core\Middleware\SessionMiddleware;
use Glued\Core\Middleware\Timer;
use Glued\Core\Middleware\TranslatorMiddleware;
use Middlewares\Csp;
use Middlewares\TrailingSlash;
use Nyholm\Psr7\Response as Psr7Response;
use ParagonIE\CSPBuilder\CSPBuilder;
use Slim\App;
use Slim\Exception\HttpNotFoundException;
use Slim\Middleware\ErrorMiddleware;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
use Slim\addRoutingMiddleware;
use Glued\Core\Middleware\LocaleSessionMiddleware; // Twig-translation
use Glued\Core\Middleware\TranslatorMiddleware; // Twig-translation
use Glued\Core\Middleware\Timer;
use Glued\Core\Middleware\SessionMiddleware;
use Tuupola\Middleware\CorsMiddleware;


// =================================================
Expand Down Expand Up @@ -80,7 +83,22 @@


$app->add(\Glued\Core\Middleware\ValidationFormsMiddleware::class);
$app->add(SessionMiddleware::class);
//$app->add(SessionMiddleware::class);


$csp = new CSPBuilder([
'script-src' => ['self' => true],
'object-src' => ['self' => true],
'frame-ancestors' => ['self' => true],
]);

$app->add(new Middlewares\Csp($csp));

$app->add(new Tuupola\Middleware\CorsMiddleware);
// TODO add sane defaults to CorsMiddleware

$sessionMiddleware = new SessionMiddleware($settings);
$app->add($sessionMiddleware);


// =================================================
Expand Down
10 changes: 7 additions & 3 deletions glued/settings.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,13 @@

// Glued globals
'glued' => [
'hostname' => 'glued.example.com',
'session_def_timeout' => 7200,
'session_min_timeout' => 300,
//'hostname' => 'glued.example.com',
//'session_def_timeout' => 7200,
//'session_min_timeout' => 300,
'session_cookie_lifetime' => 0,
'session_cookie_secure' => true,
'session_cookie_httponly' => true,
'session_cookie_samesite' => 'Lax',
'timezone' => 'Europe/Prague',
'password_hash_algo' => PASSWORD_ARGON2ID,
'password_hash_opts' => [
Expand Down

0 comments on commit 5e70173

Please sign in to comment.