Skip to content

Commit

Permalink
Fixed bugs with firewall, packaged up TwistProtect, added settings
Browse files Browse the repository at this point in the history
  • Loading branch information
danrwalker committed Nov 1, 2018
1 parent f7ea0c4 commit 409ac7f
Show file tree
Hide file tree
Showing 13 changed files with 170 additions and 75 deletions.
2 changes: 1 addition & 1 deletion dist/packages/install/Data/install.sql
Expand Up @@ -19,7 +19,7 @@ ALTER DATABASE /*TWIST_DATABASE_NAME*/ CHARACTER SET utf8mb4 COLLATE utf8mb4_uni
CREATE TABLE IF NOT EXISTS /*TWIST_DATABASE_TABLE_PREFIX*/`settings` (
`package` char(64) COLLATE utf8mb4_unicode_ci NOT NULL,
`group` enum('core','package') COLLATE utf8mb4_unicode_ci NOT NULL,
`key` char(32) COLLATE utf8mb4_unicode_ci NOT NULL,
`key` char(64) COLLATE utf8mb4_unicode_ci NOT NULL,
`value` text COLLATE utf8mb4_unicode_ci NOT NULL,
`title` char(128) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` text COLLATE utf8mb4_unicode_ci NOT NULL,
Expand Down
82 changes: 73 additions & 9 deletions dist/packages/install/Data/settings.json
Expand Up @@ -570,23 +570,23 @@
"RESOURCE_VERSION_OVERRIDE":{
"title":"Resource Version Override",
"description":"Allow calls to Resource->extendLibrary to override existing (matching) version of a file, for example jQuery v2.1.1 from the core would be over-ridden by the new jQuery v2.1.1 where as jQuery v2.1.2 would be added as a new resource.",
"default":1,
"default":"1",
"type":"boolean",
"options":"1,0",
"null":0
},
"RESOURCE_INCLUDE_ONCE":{
"title":"Resource Include Once",
"description":"When using the resource View tags, css and js resources will only be included once per page load/render.",
"default":1,
"default":"1",
"type":"boolean",
"options":"1,0",
"null":0
},
"ROUTE_CASE_SENSITIVE":{
"title":"Case Sensitive URI Routing",
"description":"Enable case sensitive URI routing in the routes module, turning this off may result in multiples of a single page being indexed by search engines. This setting dose not effect the wild card portion of URIs.",
"default":1,
"default":"1",
"type":"boolean",
"options":"1,0",
"null":0
Expand All @@ -602,15 +602,15 @@
"USER_REGISTER_PASSWORD":{
"title":"User Register Password",
"description":"The user must enter a password during the registration process (enables a password field on registration form)",
"default":1,
"default":"1",
"type":"boolean",
"options":"1,0",
"null":0
},
"USER_PASSWORD_CHANGE_EMAIL":{
"title":"Send Password Change Email",
"description":"Determine if an email should be send when a user changes their account password (Excludes password reset)",
"default":0,
"default":"0",
"type":"boolean",
"options":"1,0",
"null":0
Expand All @@ -634,7 +634,7 @@
"USER_AUTO_AUTHENTICATE":{
"title":"Auto Authenticate",
"description":"Automatically log the user in upon successful registration. This will only work if USER_EMAIL_VERIFICATION is 'off' and USER_REGISTER_PASSWORD is 'on'",
"default":0,
"default":"0",
"type":"boolean",
"options":"1,0",
"null":1
Expand All @@ -650,23 +650,23 @@
"USER_COMMON_PASSWORD_FILTER":{
"title":"Common Password Filter",
"description":"Stop the user from using any of the top 10,000 most common passwords",
"default":1,
"default":"1",
"type":"boolean",
"options":"1,0",
"null":0
},
"USER_EMAIL_VERIFICATION":{
"title":"Verify Email",
"description":"Verify a registered user by email before they can login to their account",
"default":0,
"default":"0",
"type":"boolean",
"options":"1,0",
"null":0
},
"USER_PASSWORD_CHANGE":{
"title":"Force Temporary Password Change",
"description":"Require a user to change there password upon login (if the password is a temporary one)",
"default":1,
"default":"1",
"type":"boolean",
"options":"1,0",
"null":0
Expand Down Expand Up @@ -710,5 +710,69 @@
"type":"integer",
"options":"",
"null":0
},
"TWISTPROTECT_FIREWALL":{
"title":"Enable TwistProtect Firewall",
"description":"Enable the firewall that will block visitors that are up to no good",
"default":"1",
"type":"boolean",
"options":"1,0",
"null":0
},
"TWISTPROTECT_FIREWALL_LOGIN_LIMIT":{
"title":"Login Limit",
"description":"Failed logins before soft ban (TwistProtect Firewall)",
"default":5,
"type":"integer",
"options":"",
"null":0
},
"TWISTPROTECT_FIREWALL_RESET_LIMIT":{
"title":"Reset Limit",
"description":"Failed password resets before soft ban (TwistProtect Firewall)",
"default":3,
"type":"integer",
"options":"",
"null":0
},
"TWISTPROTECT_FIREWALL_INITIAL_BAN":{
"title":"Initial Ban (Seconds)",
"description":"Time in seconds to soft ban a user (TwistProtect Firewall)",
"default":300,
"type":"integer",
"options":"",
"null":0
},
"TWISTPROTECT_FIREWALL_FULL_BAN":{
"title":"Full Ban (Seconds)",
"description":"Time in seconds for a full ban to last, set to 0 for permanent ban (TwistProtect Firewall)",
"default":0,
"type":"integer",
"options":"",
"null":0
},
"TWISTPROTECT_FIREWALL_MAX_SOFTBANS":{
"title":"Maximum SoftBans",
"description":"Amount of soft bans before a full ban is put in place (TwistProtect Firewall)",
"default":1,
"type":"integer",
"options":"",
"null":0
},
"TWISTPROTECT_FIREWALL_RESET_AFTER_DAYS":{
"title":"Reset After X Days",
"description":"Reset visitor ban history after X days of last ban (TwistProtect Firewall)",
"default":30,
"type":"integer",
"options":"",
"null":0
},
"TWISTPROTECT_FIREWALL_RESET_AFTER_SUCCESS":{
"title":"Reset After Success",
"description":"Reset soft ban limits after visitor's successful login",
"default":"1",
"type":"boolean",
"options":"1,0",
"null":0
}
}
2 changes: 2 additions & 0 deletions dist/packages/install/Data/updates/4.0.0.sql
@@ -0,0 +1,2 @@

ALTER TABLE `twist_settings` CHANGE `key` `key` CHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
31 changes: 18 additions & 13 deletions dist/packages/manager/Controllers/Manager.controller.php
Expand Up @@ -25,10 +25,10 @@
namespace Packages\manager\Controllers;

use Packages\install\Models\Install;
use \Twist\Core\Models\Security\CodeScanner;
use Twist\Core\Models\Protect\Firewall;
use \Twist\Core\Models\Protect\CodeScanner;
use \Twist\Core\Controllers\BaseUser;
use \Twist\Core\Models\ScheduledTasks;
use Twist\Core\Models\Security\Protect;

/**
* The route controller for the framework manager, generates the pages of the manager tool.
Expand Down Expand Up @@ -319,7 +319,8 @@ public function scanner(){
public function settings(){

if(array_key_exists('import',$_GET) && $_GET['import'] == 'core'){
Install::importSettings(sprintf('%ssettings.json',TWIST_FRAMEWORK_INSTALL));

\Twist\Core\Models\Install::importSettings(sprintf('%sData/settings.json',TWIST_PACKAGE_INSTALL));
\Twist::redirect('./settings');
}

Expand Down Expand Up @@ -525,23 +526,27 @@ public function firewall(){
if(array_key_exists('list_action',$_POST) && array_key_exists('ip_address',$_POST)){

if($_POST['list_action'] == 'ban'){
Protect::banIP($_POST['ip_address'],'',true);
Firewall::banIP($_POST['ip_address'],'',true);
\Twist::successMessage('IP address '.$_POST['ip_address'].' has been banned!');
}elseif($_POST['list_action'] == 'whitelist'){
Protect::whitelistIP($_POST['ip_address']);
Firewall::whitelistIP($_POST['ip_address']);
\Twist::successMessage('IP address '.$_POST['ip_address'].' has been whitelisted!');
}

}elseif(array_key_exists('unban',$_POST)){
Protect::unbanIP($_POST['unban']);
\Twist::successMessage('IP address '.$_POST['ip_address'].' has been unbanned!');
}elseif(array_key_exists('unwhitelist',$_POST)){
Protect::unwhitelistIP($_POST['unwhitelist']);
\Twist::successMessage('IP address '.$_POST['ip_address'].' has been removed from the whitelisted!');
}elseif(array_key_exists('unban',$_GET)){
Firewall::unbanIP($_GET['unban']);
\Twist::successMessage('IP address '.$_GET['ip_address'].' has been unbanned!');
}elseif(array_key_exists('unwhitelist',$_GET)){
Firewall::unwhitelistIP($_GET['unwhitelist']);
\Twist::successMessage('IP address '.$_GET['ip_address'].' has been removed from the whitelisted!');
}

$arrTags = array();
$arrData = Protect::info();
$arrData = Firewall::info();

$arrTags['whitelist_count'] = count($arrData['whitelist_ips']);
$arrTags['blocked_count'] = count($arrData['banned_ips']);
$arrTags['watched_count'] = count($arrData['failed_actions']);

$arrTags['blocked_ips'] = '';
foreach($arrData['banned_ips'] as $mxdIPAddress => $arrSubData){
Expand All @@ -556,7 +561,7 @@ public function firewall(){
$arrTags['whitelist_ips'] = '';
foreach($arrData['whitelist_ips'] as $mxdIPAddress => $arrSubData){
$arrSubData['ip_address'] = $mxdIPAddress;
$arrTags['whitelist_ips'] .= $this->_view('components/firewall/whitelist-ip.tpl',$arrSubData);
$arrTags['whitelist_ips'] .= $this->_view('components/firewall/whitelisted-ip.tpl',$arrSubData);
}

if($arrTags['whitelist_ips'] == ''){
Expand Down
30 changes: 20 additions & 10 deletions dist/packages/manager/Data/menu.json
Expand Up @@ -4,28 +4,38 @@
"uri": "",
"icon": "fa-tachometer",
"order": 10,
"sections": []
"sub-sections": []
},
{
"name": "Settings",
"uri": "settings",
"icon": "fa-cogs",
"order": 20,
"sections": []
"sub-sections": []
},
{
"name": "Cache",
"uri": "cache",
"icon": "fa-file-archive-o",
"order": 30,
"sections": []
"sub-sections": []
},
{
"name": "TwistProtect",
"uri": "firewall",
"icon": "fa-padlock",
"uri": "/",
"icon": "fa-lock",
"order": 40,
"sections": []
"sub-sections": [
{
"name": "Firewall",
"uri": "firewall",
"order": 10
},{
"name": "Code Scanner",
"uri": "scanner",
"order": 20
}
]
},
{
"name": ".htaccess",
Expand All @@ -39,27 +49,27 @@
"uri": "packages",
"icon": "fa-puzzle-piece",
"order": 60,
"sections": []
"sub-sections": []
},
{
"name": "ScheduledTasks",
"uri": "scheduled-tasks",
"icon": "fa-clock-o",
"order": 70,
"sections": []
"sub-sections": []
},
{
"name": "API Keys",
"uri": "apikeys",
"icon": "fa-key",
"order": 80,
"sections": []
"sub-sections": []
},
{
"name": "Logout",
"uri": "logout",
"icon": "fa-sign-out",
"order": 90,
"sections": []
"sub-sections": []
}
]
2 changes: 2 additions & 0 deletions dist/packages/manager/Views/pages/dashboard.tpl
Expand Up @@ -12,6 +12,8 @@
<p class="{data:data-caching=='Off'?'warning':'success'}"><small class="float-right">[<a href="{route:registered_uri}../../../../index.php">Turn {data:data-caching=='Off'?'On':'Off'}</a>]</small><strong>Data Caching:</strong> {data:data-caching}</p>
<p class="{data:development-mode=='Off'?'success':'warning'}"><small class="float-right">[<a href="{route:registered_uri}../../../../index.php">Turn {data:development-mode=='Off'?'On':'Off'}</a>]</small><strong>Development Mode:</strong> {data:development-mode}</p>
<p class="{data:debug-bar=='Off'?'success':'warning'}"><small class="float-right">[<a href="{route:registered_uri}../../../../index.php">Turn {data:debug-bar=='Off'?'On':'Off'}</a>]</small><strong>Debug Bar:</strong> {data:debug-bar}</p>
<p class="{data:debug-bar=='Off'?'success':'warning'}"><small class="float-right">[<a href="{route:registered_uri}../../../../index.php">Turn {data:debug-bar=='Off'?'On':'Off'}</a>]</small><strong>TwistProtect: Firewall</strong> {data:debug-bar}</p>
<p class="{data:debug-bar=='Off'?'success':'warning'}"><small class="float-right">[<a href="{route:registered_uri}../../../../index.php">Turn {data:debug-bar=='Off'?'On':'Off'}</a>]</small><strong>TwistProtect: Scanner</strong> {data:debug-bar}</p>
</div>
<div class="clear"></div>
<div class="grid-100 tablet-grid-100 mobile-grid-100">
Expand Down
13 changes: 7 additions & 6 deletions dist/packages/manager/Views/pages/firewall.tpl
@@ -1,14 +1,15 @@
<div class="grid-100 tablet-grid-100 mobile-grid-100">
<h2 class="no-top-padding">TwistProtect: Firewall</h2>

<a href="?status=enable" class="button fat blue float-right"><i class="fa fa-key"></i> Enable Firewall</a>
<p>Visitors that have been blocked from accessing the site, these visitors will see a 403 error message for a specified period of time. Reasons for being block are too many failed login attempts, too many password resets, too many 403,404 requests or being manually blocked.</p>

<dl>
<dt>Watched IPs</dt><dd></dd>
<dt>Blocked IPs</dt>
<dd>Temporary</dd>
<dd>Permanent</dd>
<dt>Whitelisted IPs</dt><dd></dd>
{messages:all}

<dl class="inline">
<dt>Watched IPs</dt><dd>{data:watched_count}</dd>
<dt>Blocked IPs</dt><dd>{data:blocked_count}</dd>
<dt>Whitelisted IPs</dt><dd>{data:whitelist_count}</dd>
</dl>

<h3>Blocked IPs</h3>
Expand Down
2 changes: 1 addition & 1 deletion dist/packages/manager/Views/pages/scanner.tpl
@@ -1,5 +1,5 @@
<div class="grid-100 tablet-grid-100 mobile-grid-100">
<h2 class="no-top-padding">Malicious Code Scanner</h2>
<h2 class="no-top-padding">TwistProtect: Code Scanner</h2>
<a href="?scan-now=1" class="button fat blue float-right"><i class="fa fa-play"></i> Scan Now</a>
<p>Automatically scans your site for malicious PHP code, adjust the settings to get better results. You can also enable as a cron job to help protect your site on a daily basis.</p>
<dl class="inline">
Expand Down
3 changes: 2 additions & 1 deletion dist/twist/Core/Controllers/BaseUser.controller.php
Expand Up @@ -25,6 +25,7 @@
namespace Twist\Core\Controllers;
use \Twist\Core\Models\User\Auth;
use \Twist\Core\Models\UserAgent;
use Twist\Core\Models\Protect\Firewall;

/**
* An User base controller that can be used instead of Base when you require login, authentication and other user pages. This controller should be used as an extension to a route controller class.
Expand Down Expand Up @@ -186,7 +187,7 @@ public function POSTforgottenpassword(){
$resUser->commit();
}

Protect::passwordReset();
Firewall::passwordReset();

\Twist::Session()->data('site-login_message','If registered a temporary password will be sent to the provided email address');
\Twist::redirect('./login');
Expand Down
Expand Up @@ -22,7 +22,7 @@
* @link https://twistphp.com
*/

namespace Twist\Core\Models\Security;
namespace Twist\Core\Models\Protect;

set_time_limit(0);

Expand Down

0 comments on commit 409ac7f

Please sign in to comment.