Skip to content

Commit 6817434

Browse files
committed
Beta to test
1 parent 486477f commit 6817434

13 files changed

+330
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.swp
2+
.vimrc
3+
composer.lock
4+
/vendor

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Yii2 headers security
2+
================

composer.json

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "bicf/yii2-security-headers",
3+
"description": "Security oriented headers management",
4+
"keywords": ["yii2"],
5+
"type": "yii2-extension",
6+
"license": "GPL2",
7+
"authors": [
8+
{
9+
"name": "Ivan Buttinoni",
10+
"email": "[email protected]"
11+
}
12+
],
13+
"require": {
14+
"yiisoft/yii2": "*"
15+
},
16+
"repositories": [
17+
{
18+
"type": "composer",
19+
"url": "https://asset-packagist.org"
20+
}
21+
],
22+
"autoload": {
23+
"psr-4": {
24+
"bicf\\securityheaders\\": "src"
25+
}
26+
}
27+
}

src/Response.php

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
use bicf\securityheaders;
3+
4+
/**
5+
* Class Response
6+
* ```php
7+
* [
8+
* 'components' => [
9+
* 'response' => [
10+
* 'class' => 'bicf\securityheaders\Response',
11+
* 'on afterPrepare' => ['bicf\securityheaders\Response','modulesInit'],
12+
* 'on afterSend' => ['bicf\securityheaders\Response','modulesSendHeaders'],
13+
* 'modules' => [
14+
* 'XContentTypeOptions'=>[
15+
* 'class' => 'bicf\securityheaders\modules\HeaderXContentTypeOptions',
16+
* 'value' => 'nosniff',
17+
* ],
18+
* 'AccessControlAllowMethods'=>[
19+
* 'class' => 'bicf\securityheaders\modules\HeaderAccessControlAllowMethods',
20+
* 'value' => 'GET',
21+
* ],
22+
* 'AccessControlAllowOrigin'=>[
23+
* 'class' => 'bicf\securityheaders\modules\HeaderAccessControlAllowOrigin',
24+
* 'value' => 'https://api.example.com',
25+
* ],
26+
* 'ContentSecurityPolicyAcl'=>[
27+
* 'class' => 'bicf\securityheaders\modules\HeaderContentSecurityPolicyAcl',
28+
* 'enabled' => false,
29+
* 'policies' => [
30+
* 'default-src' => "'self'",
31+
* 'frame-src' => "'self' www.facebook.com www.youtube.com www.google.com",
32+
* 'img-src' => "'self' www.google-analytics.com",
33+
* 'font-src' => "'self' fonts.gstatic.com maxcdn.bootstrapcdn.com",
34+
* 'media-src' => "'self'",
35+
* 'script-src' => "'self' www.google-analytics.com",
36+
* 'style-src' => "'self' maxcdn.bootstrapcdn.com",
37+
* 'connect-src' => "'self'",
38+
* 'report-uri' => "/report-csp-acl",
39+
* ],
40+
* ],
41+
* 'ContentSecurityPolicyMonitor'=>[
42+
* 'class' => 'bicf\securityheaders\modules\HeaderContentSecurityPolicyMonitor',
43+
* 'policies' => [
44+
* 'default-src' => "'self'",
45+
* 'frame-src' => "'self' www.facebook.com www.youtube.com www.google.com",
46+
* 'img-src' => "'self' www.google-analytics.com",
47+
* 'font-src' => "'self' fonts.gstatic.com maxcdn.bootstrapcdn.com",
48+
* 'media-src' => "'self'",
49+
* 'script-src' => "'self' www.google-analytics.com",
50+
* 'style-src' => "'self' maxcdn.bootstrapcdn.com",
51+
* 'connect-src' => "'self'",
52+
* 'report-uri' => "/report-csp-acl",
53+
* ],
54+
* ],
55+
* ],
56+
* ],
57+
* ],
58+
* ]
59+
*
60+
* ```
61+
*/
62+
class Response extends \yii\web\Response
63+
{
64+
/** @var array of header modules default is empty
65+
* use the configuration to populate the array
66+
*/
67+
public $modules=array();
68+
69+
protected function modulesInit()
70+
{
71+
foreach ($this->modules as $module){
72+
$module->init();
73+
}
74+
}
75+
76+
protected function modulesSendHeaders()
77+
{
78+
foreach ($this->modules as $module){
79+
$module->run();
80+
}
81+
}
82+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace bicf\securityheaders\modules;
4+
use yii\base\BaseObject;
5+
6+
/**
7+
* Class HeaderAccessControlAllowMethods
8+
* @package bicf\securityheaders\modules
9+
*/
10+
class HeaderAccessControlAllowMethods extends HeaderModuleBase
11+
{
12+
private $defaultValue='GET';
13+
public $value;
14+
15+
public function init()
16+
{
17+
if($this->value === null){
18+
$this->value =$this->defaultValue;
19+
}
20+
}
21+
22+
public function run()
23+
{
24+
if(!$this->enabled){
25+
return;
26+
}
27+
\Yii::$app->response->headers->set('Access-Control-Allow-Methods',$this->value);
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace bicf\securityheaders\modules;
4+
use yii\base\BaseObject;
5+
6+
/**
7+
* Class HeaderAccessControlAllowOrigin
8+
* @package bicf\securityheaders\modules
9+
*/
10+
class HeaderAccessControlAllowOrigin extends HeaderModuleBase
11+
{
12+
public $value;
13+
14+
public function run()
15+
{
16+
if(!$this->enabled){
17+
return;
18+
}
19+
if($this->value === null){
20+
return;
21+
}
22+
\Yii::$app->response->headers->set('Access-Control-Allow-Origin',$this->value);
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace bicf\securityheaders\modules;
4+
5+
/**
6+
* Class HeaderContentSecurityPolicyAcl
7+
* @package bicf\securityheaders\modules
8+
*/
9+
class HeaderContentSecurityPolicyAcl extends HeaderContentSecurityPolicyBase
10+
{
11+
protected $headerName='Content-Security-Policy';
12+
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace bicf\securityheaders\modules;
4+
use yii\base\BaseObject;
5+
6+
/**
7+
* Class HeaderContentSecurityPolicyBase
8+
* @package bicf\securityheaders\modules
9+
*/
10+
abstract class HeaderContentSecurityPolicyBase extends HeaderModuleBase
11+
{
12+
const DEFAULT_SRC = 'default-src';
13+
const FRAME_SRC = 'frame-src';
14+
const IMG_SRC = 'img-src';
15+
const FONT_SRC = 'font-src';
16+
const MEDIA_SRC = 'media-src';
17+
const SCRIPT_SRC = 'script-src';
18+
const STYLE_SRC = 'style-src';
19+
const CONNECT_SRC = 'connect-src';
20+
const REPORT_URI = 'report-uri';
21+
22+
private static $token;
23+
protected $headerName;
24+
25+
public $policies = array();
26+
27+
public $nonceEnabled = true;
28+
29+
public static function getToken()
30+
{
31+
if(self::$token === null){
32+
self::$token= \Yii::$app->security->generateRandomString();
33+
}
34+
return self::$token;
35+
}
36+
37+
/**
38+
* add the security header
39+
*/
40+
public function run(){
41+
if(!$this->enabled){
42+
return;
43+
}
44+
if($this->nonceEnabled){
45+
$scriptSrc = isset($this->policies[self::SCRIPT_SRC])?$this->policies[self::SCRIPT_SRC]:'';
46+
$this->policies[self::SCRIPT_SRC] = "$scriptSrc 'nonce-".self::getToken()."'";
47+
}
48+
49+
$sep=$value='';
50+
foreach ($this->policies as $k => $v){
51+
$value .="$sep$k $v; ";
52+
$sep ="; ";
53+
}
54+
\Yii::$app->response->headers->set($this->headerName,$value);
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace bicf\securityheaders\modules;
4+
5+
/**
6+
* Class HeaderContentSecurityPolicyMonitor
7+
* @package bicf\securityheaders\modules
8+
*/
9+
class HeaderContentSecurityPolicyMonitor extends HeaderContentSecurityPolicyBase
10+
{
11+
protected $headerName='Content-Security-Policy-Report-Only';
12+
13+
14+
15+
}

src/modules/HeaderModuleBase.php

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: ivan
5+
* Date: 9/1/18
6+
* Time: 12:21 AM
7+
*/
8+
9+
namespace bicf\securityheaders\modules;
10+
11+
12+
use yii\base\BaseObject;
13+
14+
/**
15+
* Class HeaderModuleBase
16+
* @package bicf\securityheaders\modules
17+
* @property boolean $enabled
18+
*/
19+
abstract class HeaderModuleBase extends BaseObject implements HeaderModuleInterface
20+
{
21+
/**
22+
* @var bool whether to enabled the module or not. Allows to turn the module header
23+
* on and off according to specific conditions.
24+
*/
25+
public $enabled=true;
26+
}

src/modules/HeaderModuleInterface.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: ivan
5+
* Date: 9/1/18
6+
* Time: 12:21 AM
7+
*/
8+
9+
namespace bicf\securityheaders\modules;
10+
11+
12+
interface HeaderModuleInterface
13+
{
14+
public function init();
15+
public function run();
16+
}
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
namespace bicf\securityheaders\modules;
3+
4+
use yii\base\BaseObject;
5+
6+
/**
7+
* Class HeaderXContentTypeOptions
8+
* @package bicf\securityheaders\modules
9+
*/
10+
class HeaderXContentTypeOptions extends HeaderModuleBase
11+
{
12+
private $defaultValue='nosniff';
13+
public $value;
14+
15+
public function init()
16+
{
17+
if($this->value === null){
18+
$this->value =$this->defaultValue;
19+
}
20+
}
21+
22+
23+
public function run()
24+
{
25+
if(!$this->enabled){
26+
return;
27+
}
28+
\Yii::$app->response->headers->set('X-Content-Type-Options',$this->value);
29+
}
30+
}

0 commit comments

Comments
 (0)