Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
paramonovav committed Aug 7, 2015
1 parent 43b21e1 commit 6c47c5c
Show file tree
Hide file tree
Showing 12 changed files with 287 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
.env.*.php
.env.php
.env
/vendor
composer.phar
composer.lock
.DS_Store
28 changes: 28 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "paramonovav/laravel4-header-csp",
"description": "Provides support for enforcing Content Security Policy with headers in Laravel 4 responses.",
"keywords": ["laravel", "laravel 4", "header", "response", "content security policy", "xss protection", "csp"],
"license": "MIT",
"homepage": "https://github.com/paramonovav/laravel4-header-csp",
"authors": [
{
"name": "Anton Paramonov",
"email": "[email protected]",
"homepage": "https://github.com/paramonovav",
"role": "Developer"
}
],
"require": {
"php": ">=5.4.0",
"illuminate/support": "4.2.*"
},
"autoload": {
"classmap": [
"src/migrations"
],
"psr-0": {
"Paramonovav\\Laravel4HeaderCsp\\": "src/"
}
},
"minimum-stability": "stable"
}
18 changes: 18 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
>
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
Empty file added public/.gitkeep
Empty file.
154 changes: 154 additions & 0 deletions src/Paramonovav/Laravel4HeaderCsp/Laravel4HeaderCspServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<?php namespace Paramonovav\Laravel4HeaderCsp;

use Illuminate\Support\Facades\Config;
use Illuminate\Support\ServiceProvider;

class Laravel4HeaderCspServiceProvider extends ServiceProvider {

/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;

/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$this->package('paramonovav/laravel4-header-csp');

$this->app['router']-> post(
Config::get('laravel4-header-csp::report-uri-route-uri', 'content-security-policy-report'),
array(
'as' => Config::get('laravel4-header-csp::report-uri-route-name', 'header-csp-report'),
function(){

$post_data = file_get_contents('php://input');

if (empty($post_data))
{
return;
}

$report_folder_path = storage_path().'/logs/content-security-policy-report';

if (!is_dir($report_folder_path))
{
mkdir($report_folder_path, 0777, TRUE);
}

file_put_contents($report_folder_path.'/'.date('Y-m-d').'.log', $post_data."\r\n", FILE_APPEND | LOCK_EX);
}
));

$this->app['router']-> filter(
'response.secure',
function($route, $request, $response, $value = ''){

$profiles = Config::get('laravel4-header-csp::default', 'global');

if (!empty($value))
{
$profiles .= '-'.$value;
}
$profiles = explode('-', $profiles);
$profiles = array_map('trim', $profiles);

$config_profiles = Config::get('laravel4-header-csp::profiles');

if (empty($config_profiles) || empty($profiles))
{
return;
}

$csp = array();
foreach ($profiles as $profile)
{
if (empty($config_profiles[$profile]))
{
continue;
}

$config_profile = $config_profiles[$profile];

if (!empty($config_profile['csp']) && is_array($config_profile['csp']))
{
foreach ($config_profile['csp'] as $key => $value)
{
if (!is_array($value))
{
if ('report-uri' == $key)
{
$value = route($value);
}
$value = array($value);
}

foreach ($value as $val)
{
$csp[$key][$val] = $val;
}
}
}

if (!empty($config_profile['custom']) && is_array($config_profile['custom']))
{
foreach ($config_profile['custom'] as $key => $value)
{
$response-> headers->set($key, $value);
}
}
}

foreach ($csp as $key => $vals)
{
if (isset($vals["'none'"]) && count($vals) > 1)
{
unset($vals["'none'"]);
}

$csp_parts[$key] = $key.' '.implode(' ', $vals);
}

$csp_line = implode('; ', $csp_parts).';';

if (FALSE === Config::get('laravel4-header-csp::csp-report-only', FALSE))
{
$response-> headers->set('X-Webkit-CSP', $csp_line);
$response-> headers->set('X-Content-Security-Policy', $csp_line);
$response-> headers->set('Content-Security-Policy', $csp_line);
}
else
{
$response-> headers->set('X-Content-Security-Policy-Report-Only', $csp_line);
$response-> headers->set('Content-Security-Policy-Report-Only', $csp_line);
}
}
);
}

/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}

/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array();
}

}
Empty file added src/config/.gitkeep
Empty file.
83 changes: 83 additions & 0 deletions src/config/config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php
/*
*
* http://content-security-policy.com/
* http://www.sitepoint.com/improving-web-security-with-the-content-security-policy/
* https://www.owasp.org/index.php/List_of_useful_HTTP_headers
*
*/

return array(

'report-uri-route-uri' => 'content-security-policy-report',
'report-uri-route-name' => 'header-csp-report',

'default' => 'global',

'csp-report-only' => FALSE,

'profiles' => array(
'global' => array(
'csp' => array(
'default-src' => "'none'",
'img-src' => "'self'",
'script-src' => "'self'",
'style-src' => "'self'",
'font-src' => "'self'",
'object-src' => "'none'",
'media-src' => "'none'",
'frame-src' => "'none'",
'connect-src' => "'self'",
//'report-uri' => 'header-csp-report',
//'sandbox' => 'allow-forms allow-same-origin allow-scripts allow-top-navigation',
),
'custom' => array(
'x-frame-options' => 'DENY',
'x-content-type-options' => 'nosniff',
'x-xss-protection' => '1; mode=block'
)
),
'google' => array(
'csp' => array(
'script-src' => array(
"'unsafe-inline'",
"'unsafe-eval'",
'*.google.com',
'*.gstatic.com',
'*.google-analytics.com',
'stats.g.doubleclick.net'
),
'style-src' => array(
"'unsafe-inline'",
'*.googleapis.com'
),
'font-src' => array(
'*.gstatic.com',
'*.googleapis.com',
'data:'
),
'img-src' => array(
'*.google-analytics.com',
'data:'
),
'frame-src' => array(
'*.google.com'
),
)
),
'gravatar' => array(
'csp' => array(
'img-src' => array(
'*.gravatar.com'
)
)
),
'flickr' => array(
'csp' => array(
'img-src' => array(
'*.staticflickr.com'
)
)
)
)
);
Empty file added src/controllers/.gitkeep
Empty file.
Empty file added src/lang/.gitkeep
Empty file.
Empty file added src/migrations/.gitkeep
Empty file.
Empty file added src/views/.gitkeep
Empty file.
Empty file added tests/.gitkeep
Empty file.

0 comments on commit 6c47c5c

Please sign in to comment.