Skip to content

Commit

Permalink
Support for ip bans in Apache 2.4 without compat module
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisgraham committed May 24, 2019
1 parent 54f5046 commit 579e45b
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 19 deletions.
12 changes: 10 additions & 2 deletions docs/pages/comcode_custom/EN/sup_professional_upgrading.txt
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -106,8 +106,16 @@ Additionally you can upload and run the first two steps of Composr's installer a
! † {$INC,step_num}{$GET,step_num} ! † {$INC,step_num}{$GET,step_num}
| Create [tt]<webroot>/<codename>/_temp[/tt] and put a [tt].htaccess[/tt] file in it | Create [tt]<webroot>/<codename>/_temp[/tt] and put a [tt].htaccess[/tt] file in it
| [code="htaccess"] | [code="htaccess"]
order deny,allow # < Apache 2.4
deny from all <IfModule !mod_authz_core.c>
Order Allow,Deny
Deny from all
</IfModule>

# >= Apache 2.4
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
[/code] [/code]
|- |-
! &dagger; {$INC,step_num}{$GET,step_num} ! &dagger; {$INC,step_num}{$GET,step_num}
Expand Down
18 changes: 14 additions & 4 deletions docs/pages/comcode_custom/EN/tut_security.txt
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -479,10 +479,20 @@ To provide additional protection beyond the master password you may want to set


Follows are sample access rules for an Apache [tt].htaccess[/tt] file to provide a temporary access block: Follows are sample access rules for an Apache [tt].htaccess[/tt] file to provide a temporary access block:
[code="htaccess"] [code="htaccess"]
<FilesMatch ^((rootkit_detection|upgrader|uninstall|data/upgrader2|config_editor|code_editor)\.php)$> # < Apache 2.4
Order allow,deny <IfModule !mod_authz_core.c>
Deny from all <FilesMatch ^((rootkit_detection|upgrader|uninstall|data/upgrader2|config_editor|code_editor)\.php)$>
</FilesMatch> Order Allow,Deny
Deny from all
</FilesMatch>
</IfModule>

# >= Apache 2.4
<IfModule mod_authz_core.c>
<FilesMatch ^((rootkit_detection|upgrader|uninstall|data/upgrader2|config_editor|code_editor)\.php)$>
Require all denied
</FilesMatch>
</IfModule>
[/code] [/code]


For IIS, the [tt]web.config[/tt] file's [tt]hiddenSegments[/tt] can be extended: For IIS, the [tt]web.config[/tt] file's [tt]hiddenSegments[/tt] can be extended:
Expand Down
12 changes: 12 additions & 0 deletions install.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3129,10 +3129,22 @@ function test_htaccess($conn)
/*REWRITE RULES END*/ /*REWRITE RULES END*/


$clauses[] = <<<END $clauses[] = <<<END
# < Apache 2.4
<IfModule !mod_authz_core.c>
order allow,deny order allow,deny
allow from all allow from all
# IP bans go here (leave this comment here! If this file is writeable, Composr will write in IP bans below, in sync with its own DB-based banning - this makes DOS/hack attack prevention stronger) # IP bans go here (leave this comment here! If this file is writeable, Composr will write in IP bans below, in sync with its own DB-based banning - this makes DOS/hack attack prevention stronger)
# deny from xxx.xx.x.x (leave this comment here!) # deny from xxx.xx.x.x (leave this comment here!)
</IfModule>
# >= Apache 2.4
<IfModule mod_authz_core.c>
<RequireAll>
require all granted
# IP bans go here (leave this comment here! If this file is writeable, Composr will write in IP bans below, in sync with its own DB-based banning - this makes DOS/hack attack prevention stronger)
# require not ip xxx.xx.x.x (leave this comment here!)
</RequireAll>
</IfModule>
END; END;


$base = str_replace('\\', '/', dirname(cms_srv('SCRIPT_NAME'))); $base = str_replace('\\', '/', dirname(cms_srv('SCRIPT_NAME')));
Expand Down
11 changes: 11 additions & 0 deletions plain.htaccess
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -87,8 +87,19 @@ RewriteRule ^([^/\&\?]+)\.htm$ index.php\?page=$1 [L,QSA]
</IfModule> </IfModule>




# < Apache 2.4
<IfModule !mod_authz_core.c>
order allow,deny order allow,deny
allow from all allow from all
# IP bans go here (leave this comment here! If this file is writeable, Composr will write in IP bans below, in sync with its own DB-based banning - this makes DOS/hack attack prevention stronger) # IP bans go here (leave this comment here! If this file is writeable, Composr will write in IP bans below, in sync with its own DB-based banning - this makes DOS/hack attack prevention stronger)
# deny from xxx.xx.x.x (leave this comment here!) # deny from xxx.xx.x.x (leave this comment here!)
</IfModule>


# >= Apache 2.4
<IfModule mod_authz_core.c>
<RequireAll>
require all granted
# IP bans go here (leave this comment here! If this file is writeable, Composr will write in IP bans below, in sync with its own DB-based banning - this makes DOS/hack attack prevention stronger)
# require not ip xxx.xx.x.x (leave this comment here!)
</RequireAll>
</IfModule>
12 changes: 12 additions & 0 deletions recommended.htaccess
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -159,7 +159,19 @@ RewriteRule ^([^/\&\?]+)\.htm$ index.php\?page=$1 [L,QSA]
</IfModule> </IfModule>




# < Apache 2.4
<IfModule !mod_authz_core.c>
order allow,deny order allow,deny
allow from all allow from all
# IP bans go here (leave this comment here! If this file is writeable, Composr will write in IP bans below, in sync with its own DB-based banning - this makes DOS/hack attack prevention stronger) # IP bans go here (leave this comment here! If this file is writeable, Composr will write in IP bans below, in sync with its own DB-based banning - this makes DOS/hack attack prevention stronger)
# deny from xxx.xx.x.x (leave this comment here!) # deny from xxx.xx.x.x (leave this comment here!)
</IfModule>

# >= Apache 2.4
<IfModule mod_authz_core.c>
<RequireAll>
require all granted
# IP bans go here (leave this comment here! If this file is writeable, Composr will write in IP bans below, in sync with its own DB-based banning - this makes DOS/hack attack prevention stronger)
# require not ip xxx.xx.x.x (leave this comment here!)
</RequireAll>
</IfModule>
23 changes: 17 additions & 6 deletions sources/failure.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -769,13 +769,19 @@ function add_ip_ban($ip, $descrip = '', $ban_until = null, $ban_positive = true)
$GLOBALS['SITE_DB']->query_insert('banned_ip', array('ip' => $ip, 'i_descrip' => $descrip, 'i_ban_until' => $ban_until, 'i_ban_positive' => $ban_positive ? 1 : 0), false, true); // To stop weird race-like conditions $GLOBALS['SITE_DB']->query_insert('banned_ip', array('ip' => $ip, 'i_descrip' => $descrip, 'i_ban_until' => $ban_until, 'i_ban_positive' => $ban_positive ? 1 : 0), false, true); // To stop weird race-like conditions
persistent_cache_delete('IP_BANS'); persistent_cache_delete('IP_BANS');
if ((is_writable_wrap(get_file_base() . '/.htaccess')) && (is_null($ban_until))) { if ((is_writable_wrap(get_file_base() . '/.htaccess')) && (is_null($ban_until))) {
$original_contents = cms_file_get_contents_safe(get_file_base() . '/.htaccess'); $contents = unixify_line_format(cms_file_get_contents_safe(get_file_base() . '/.htaccess'));
$ip_cleaned = str_replace('*', '', $ip); $ip_cleaned = str_replace('*', '', $ip);
$ip_cleaned = str_replace('..', '.', $ip_cleaned); $ip_cleaned = str_replace('..', '.', $ip_cleaned);
$ip_cleaned = str_replace('..', '.', $ip_cleaned); $ip_cleaned = str_replace('..', '.', $ip_cleaned);
if (strpos($original_contents, "\n" . 'deny from ' . $ip_cleaned) === false) { if ((stripos($contents, "\n" . 'deny from ' . $ip_cleaned) === false) && (stripos($contents, "\n" . 'require not ip ' . $ip_cleaned) === false)) {
require_code('files'); require_code('files');
$contents = str_replace('# deny from xxx.xx.x.x (leave this comment here!)', '# deny from xxx.xx.x.x (leave this comment here!)' . "\n" . 'deny from ' . $ip_cleaned, $original_contents);
// < Apache 2.4
$contents = str_ireplace('# deny from xxx.xx.x.x (leave this comment here!)', '# deny from xxx.xx.x.x (leave this comment here!)' . "\n" . 'deny from ' . $ip_cleaned, $contents);

// >= Apache 2.4
$contents = str_ireplace('# require not ip xxx.xx.x.x (leave this comment here!)', '# require not ip xxx.xx.x.x (leave this comment here!)' . "\n" . 'require not ip ' . $ip_cleaned, $contents);

cms_file_put_contents_safe(get_file_base() . '/.htaccess', $contents, FILE_WRITE_FIX_PERMISSIONS | FILE_WRITE_SYNC_FILE); cms_file_put_contents_safe(get_file_base() . '/.htaccess', $contents, FILE_WRITE_FIX_PERMISSIONS | FILE_WRITE_SYNC_FILE);
} }
} }
Expand All @@ -797,14 +803,19 @@ function remove_ip_ban($ip)
$GLOBALS['SITE_DB']->query_delete('banned_ip', array('ip' => $ip), '', 1); $GLOBALS['SITE_DB']->query_delete('banned_ip', array('ip' => $ip), '', 1);
persistent_cache_delete('IP_BANS'); persistent_cache_delete('IP_BANS');
if (is_writable_wrap(get_file_base() . '/.htaccess')) { if (is_writable_wrap(get_file_base() . '/.htaccess')) {
$contents = cms_file_get_contents_safe(get_file_base() . '/.htaccess'); $contents = unixify_line_format(cms_file_get_contents_safe(get_file_base() . '/.htaccess'));
$ip_cleaned = str_replace('*', '', $ip); $ip_cleaned = str_replace('*', '', $ip);
$ip_cleaned = str_replace('..', '.', $ip_cleaned); $ip_cleaned = str_replace('..', '.', $ip_cleaned);
$ip_cleaned = str_replace('..', '.', $ip_cleaned); $ip_cleaned = str_replace('..', '.', $ip_cleaned);
if (trim($ip_cleaned) != '') { if (trim($ip_cleaned) != '') {
require_code('files'); require_code('files');
$contents = str_replace("\n" . 'deny from ' . $ip_cleaned . "\n", "\n", $contents);
$contents = str_replace("\r" . 'deny from ' . $ip_cleaned . "\r", "\r", $contents); // Just in case // < Apache 2.4
$contents = str_ireplace("\n" . 'deny from ' . $ip_cleaned . "\n", "\n", $contents);

// >= Apache 2.4
$contents = str_ireplace("\n" . 'require not ip ' . $ip_cleaned . "\n", "\n", $contents);

cms_file_put_contents_safe(get_file_base() . '/.htaccess', $contents, FILE_WRITE_FIX_PERMISSIONS | FILE_WRITE_SYNC_FILE); cms_file_put_contents_safe(get_file_base() . '/.htaccess', $contents, FILE_WRITE_FIX_PERMISSIONS | FILE_WRITE_SYNC_FILE);
} }
} }
Expand Down
2 changes: 1 addition & 1 deletion sources/form_templates.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1511,7 +1511,7 @@ function make_previewable_url_absolute($url)
} }


$htaccess_path = $image_path . '/.htaccess'; $htaccess_path = $image_path . '/.htaccess';
if ((is_file($htaccess_path)) && (strpos(file_get_contents($htaccess_path), 'deny from all') !== false)) { if ((is_file($htaccess_path)) && (stripos(file_get_contents($htaccess_path), 'deny from all') !== false) && (stripos(file_get_contents($htaccess_path), 'require not ip') !== false)) {
return array($_url, $is_image); return array($_url, $is_image);
} }


Expand Down
4 changes: 2 additions & 2 deletions sources/global3.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2234,10 +2234,10 @@ function ip_banned($ip, $force_db = false, $handle_uncertainties = false)
global $SITE_INFO; global $SITE_INFO;
if ((!$force_db) && (((isset($SITE_INFO['known_suexec'])) && ($SITE_INFO['known_suexec'] == '1')) || (is_writable_wrap(get_file_base() . '/.htaccess')))) { if ((!$force_db) && (((isset($SITE_INFO['known_suexec'])) && ($SITE_INFO['known_suexec'] == '1')) || (is_writable_wrap(get_file_base() . '/.htaccess')))) {
$bans = array(); $bans = array();
$ban_count = preg_match_all('#\ndeny from (.*)#', cms_file_get_contents_safe(get_file_base() . '/.htaccess'), $bans); $ban_count = preg_match_all('#\n(deny from|require not ip) (.*)#i', cms_file_get_contents_safe(get_file_base() . '/.htaccess'), $bans);
$ip_bans = array(); $ip_bans = array();
for ($i = 0; $i < $ban_count; $i++) { for ($i = 0; $i < $ban_count; $i++) {
$ip_bans[] = array('ip' => $bans[1][$i]); $ip_bans[$bans[1][$i]] = array('ip' => $bans[1][$i]);
} }
} else { } else {
$ip_bans = function_exists('persistent_cache_get') ? persistent_cache_get('IP_BANS') : null; $ip_bans = function_exists('persistent_cache_get') ? persistent_cache_get('IP_BANS') : null;
Expand Down
18 changes: 14 additions & 4 deletions sources_custom/hooks/systems/addon_registry/cns_tapatalk.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -207,10 +207,20 @@ public function get_description()
If a [tt]mobiquo/logging.dat[/tt] file exists and is writable then full logging will be written to it. If a [tt]mobiquo/logging.dat[/tt] file exists and is writable then full logging will be written to it.
Never use this on a live site as it is not secure, unless you limit access via an [tt]data_custom/.htaccess[/tt] file: Never use this on a live site as it is not secure, unless you limit access via an [tt]data_custom/.htaccess[/tt] file:
[code] [code]
<Files logging.dat> # < Apache 2.4
Order Allow,Deny <IfModule !mod_authz_core.c>
Deny from all <Files logging.dat>
</Files> Order Allow,Deny
Deny from all
</Files>
</IfModule>
# >= Apache 2.4
<IfModule mod_authz_core.c>
<Files logging.dat>
Require all denied
</Files>
</IfModule>
[/code] [/code]
(don\'t blindingly trust this, test you cannot download the file by URL) (don\'t blindingly trust this, test you cannot download the file by URL)
Expand Down

0 comments on commit 579e45b

Please sign in to comment.