Skip to content

Commit

Permalink
Merge pull request #29 from igorhrcek/issue-3
Browse files Browse the repository at this point in the history
Issue 3
  • Loading branch information
igorhrcek authored Mar 21, 2022
2 parents 201d1de + 924030d commit 7c0b8e1
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.env
vendor/
.idea/
.phpunit.result.cache
Expand Down
1 change: 0 additions & 1 deletion src/RuleContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

class RuleContent {


public array $content;
public array $templateVars;

Expand Down
33 changes: 33 additions & 0 deletions src/SecureCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use WP_CLI;
use WP_CLI_Command;
use WP_CLI_Secure\SubCommands\AddSecurityHeaders;
use WP_CLI_Secure\SubCommands\BlockAccessToCustomSensitiveFiles;
use WP_CLI_Secure\SubCommands\BlockAccessToHtaccess;
use WP_CLI_Secure\SubCommands\BlockAccessToSensitiveDirectories;
Expand Down Expand Up @@ -282,6 +283,38 @@ public function block_author_scanning($args, $assoc_args) : void {
(new BlockAuthorScanning($assoc_args))->output();
}

/**
* Set Security Headers.
*
* ## OPTIONS
*
* [--remove]
* : Removes the rule from .htaccess or nginx.conf.
*
* [--headers]
* : Custom comma separated header list to add.
*
* [--output]
* : Use this option to display the actual code that you can manually copy and paste into some other file
*
* [--headers=<headers>]
* : List of headers you want to be added.
*
* [--server=<server>]
* : Set a server type. Possible options are "apache" and "nginx". Default is "apache" and all rules are stored in
* .htaccess file
*
* ## EXAMPLES
*
* $ wp secure add_security_headers
* Success: Add Security Headers rule has been deployed.
*
* @when before_wp_load
*/
public function add_security_headers($args, $assoc_args) : void {
(new AddSecurityHeaders($assoc_args))->output();
}

/**
* Removes all WP CLI Secure rules
*
Expand Down
50 changes: 50 additions & 0 deletions src/SubCommands/AddSecurityHeaders.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace WP_CLI_Secure\SubCommands;

class AddSecurityHeaders extends SubCommand {
public string $ruleTemplate = 'add_security_headers';
public string $ruleName = 'SECURITY HEADERS';
public string $successMessage = 'Add Security Headers rule has been deployed.';
public string $removalMessage= 'Add Security Headers rule has been removed.';

public function getTemplateVars() {

$default_headers = [
'Strict-Transport-Security' => '"max-age=63072000; includeSubDomains; preload"',
'Referrer-Policy' => 'strict-origin-when-cross-origin',
'X-Content-Type-Options' => 'nosniff',
'X-Frame-Options' => 'SAMEORIGIN',
'X-XSS-Protection' => '"1; mode=block"'
];

$headers = isset( $this->commandArguments['headers'] ) ? $this->commandArguments['headers'] : array_keys( $default_headers );
if ( ! empty( $headers ) ) {
if ( is_string( $headers ) ) {
$headers = explode( ',', $headers );
}
$headers = array_map( 'trim', $headers );

foreach ( $headers as $h ) {
$header = '';
$value = '';
foreach ( $default_headers as $key => $v ) {
if ( strtolower( $key ) === strtolower( $h ) ) {
$header = $key;
$value = $v;
}
}
if ( empty( $header ) ) {
continue;
}
$headers_array[] =
[
'header' => $header,
'value' => $value
];
}
return $headers_array;
}
return [];
}
}
4 changes: 3 additions & 1 deletion src/SubCommands/BlockAccessToSensitiveDirectories.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ public function getTemplateVars() {
if ( ! empty( $directories ) ) {
$directories = explode( ',', $directories );
$directories = array_map( 'trim', $directories );
return [

return [
[ 'directories' => implode( '|', array_map( 'preg_quote', $directories ) ) ]
];
}

return [];
}
}
1 change: 1 addition & 0 deletions src/Templates/apache/add_security_headers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Header always set {{header}} {{value}}
1 change: 1 addition & 0 deletions src/Templates/nginx/add_security_headers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_header {{header}} {{value}} always;
40 changes: 40 additions & 0 deletions tests/Feature/AddSecurityHeadersTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Tests\Feature;

use Tests\BaseTestCase;
use WP_CLI_Secure\SubCommands\AddSecurityHeaders;

class AddSecurityHeadersTest extends BaseTestCase {
public function setUp(): void {
parent::setUp();

$command = new AddSecurityHeaders($this->nginxAssocArgs);
$command->output();

$command = new AddSecurityHeaders($this->apacheAssocArgs);
$command->output();

exec('cd ' . dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . $_ENV['WORDPRESS_NGINX_PATH'] . '&& ddev exec nginx -s reload');
}

public function testItWillContainAllHeadersOnNginx() : void {
$response = $this->nginxHttpClient->get('', ['http_errors' => false]);

$this->assertNotEmpty($response->getHeaderLine( 'Strict-Transport-Security' ));
$this->assertNotEmpty($response->getHeaderLine( 'Referrer-Policy' ));
$this->assertNotEmpty($response->getHeaderLine( 'x-content-type-options' ));
$this->assertNotEmpty($response->getHeaderLine( 'X-Frame-Options' ));
$this->assertNotEmpty($response->getHeaderLine( 'X-XSS-Protection' ));
}

public function testItWillContainAllHeadersOnApache() : void {
$response = $this->apacheHttpClient->get('', ['http_errors' => false]);

$this->assertNotEmpty($response->getHeaderLine( 'Strict-Transport-Security' ));
$this->assertNotEmpty($response->getHeaderLine( 'Referrer-Policy' ));
$this->assertNotEmpty($response->getHeaderLine( 'x-content-type-options' ));
$this->assertNotEmpty($response->getHeaderLine( 'X-Frame-Options' ));
$this->assertNotEmpty($response->getHeaderLine( 'X-XSS-Protection' ));
}
}

0 comments on commit 7c0b8e1

Please sign in to comment.