Skip to content

Commit b1b292b

Browse files
VINADES.,JSChoaquynhtim99
VINADES.,JSC
authored andcommitted
Anti XSS from external resources
1 parent 0b7113b commit b1b292b

File tree

9 files changed

+83
-10
lines changed

9 files changed

+83
-10
lines changed

.htaccess

+9-9
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@
1010

1111
RedirectMatch 404 ^.*\/(config|mainfile)\.php(.*)$
1212

13-
ErrorDocument 400 /error.php?code=400&nvDisableRewriteCheck=1
14-
ErrorDocument 403 /error.php?code=403&nvDisableRewriteCheck=1
15-
ErrorDocument 404 /error.php?code=404&nvDisableRewriteCheck=1
16-
ErrorDocument 405 /error.php?code=405&nvDisableRewriteCheck=1
17-
ErrorDocument 408 /error.php?code=408&nvDisableRewriteCheck=1
18-
ErrorDocument 500 /error.php?code=500&nvDisableRewriteCheck=1
19-
ErrorDocument 502 /error.php?code=502&nvDisableRewriteCheck=1
20-
ErrorDocument 503 /error.php?code=503&nvDisableRewriteCheck=1
21-
ErrorDocument 504 /error.php?code=504&nvDisableRewriteCheck=1
13+
ErrorDocument 400 /error.php?code=400
14+
ErrorDocument 403 /error.php?code=403
15+
ErrorDocument 404 /error.php?code=404
16+
ErrorDocument 405 /error.php?code=405
17+
ErrorDocument 408 /error.php?code=408
18+
ErrorDocument 500 /error.php?code=500
19+
ErrorDocument 502 /error.php?code=502
20+
ErrorDocument 503 /error.php?code=503
21+
ErrorDocument 504 /error.php?code=504
2222

2323
<IfModule mod_deflate.c>
2424
<FilesMatch "\.(css|js|xml|ttf)$">

admin/settings/security.php

+27
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,30 @@
6262
$array_config_global['two_step_verification'] = $nv_Request->get_int('two_step_verification', 'post', 0);
6363
$array_config_global['admin_2step_opt'] = $nv_Request->get_typed_array('admin_2step_opt', 'post', 'title', []);
6464
$array_config_global['admin_2step_default'] = $nv_Request->get_title('admin_2step_default', 'post', '');
65+
$array_config_global['domains_restrict'] = (int) $nv_Request->get_bool('domains_restrict', 'post', false);
66+
67+
$domains = $nv_Request->get_textarea('domains_whitelist', '', NV_ALLOWED_HTML_TAGS, true);
68+
$domains = explode('<br />', strip_tags($domains, '<br>'));
69+
70+
$array_config_global['domains_whitelist'] = [];
71+
foreach ($domains as $domain) {
72+
if (!empty($domain)) {
73+
$domain = parse_url($domain);
74+
if (is_array($domain)) {
75+
if (sizeof($domain) == 1 and !empty($domain['path'])) {
76+
$domain['host'] = $domain['path'];
77+
}
78+
if (!isset($domain['scheme'])) {
79+
$domain['scheme'] = 'http';
80+
}
81+
$domain_name = nv_check_domain($domain['host']);
82+
if (!empty($domain_name)) {
83+
$array_config_global['domains_whitelist'][] = $domain_name;
84+
}
85+
}
86+
}
87+
}
88+
$array_config_global['domains_whitelist'] = empty($array_config_global['domains_whitelist']) ? '' : json_encode(array_unique($array_config_global['domains_whitelist']));
6589

6690
if ($array_config_global['login_number_tracking'] < 1) {
6791
$array_config_global['login_number_tracking'] = 5;
@@ -126,6 +150,7 @@
126150
$array_config_define['nv_anti_iframe'] = NV_ANTI_IFRAME;
127151
$array_config_define['nv_allowed_html_tags'] = NV_ALLOWED_HTML_TAGS;
128152
$array_config_global['admin_2step_opt'] = empty($global_config['admin_2step_opt']) ? [] : explode(',', $global_config['admin_2step_opt']);
153+
$array_config_global['domains_whitelist'] = empty($global_config['domains_whitelist']) ? '' : implode("\n", $global_config['domains_whitelist']);
129154
}
130155

131156
$array_config_flood = [];
@@ -556,9 +581,11 @@
556581
$xtpl->assign('ANTI_IFRAME', $array_config_define['nv_anti_iframe'] ? ' checked="checked"' : '');
557582

558583
$xtpl->assign('IS_LOGIN_BLOCKER', ($array_config_global['is_login_blocker']) ? ' checked="checked"' : '');
584+
$xtpl->assign('DOMAINS_RESTRICT', ($array_config_global['domains_restrict']) ? ' checked="checked"' : '');
559585
$xtpl->assign('LOGIN_NUMBER_TRACKING', $array_config_global['login_number_tracking']);
560586
$xtpl->assign('LOGIN_TIME_TRACKING', $array_config_global['login_time_tracking']);
561587
$xtpl->assign('LOGIN_TIME_BAN', $array_config_global['login_time_ban']);
588+
$xtpl->assign('DOMAINS_WHITELIST', $array_config_global['domains_whitelist']);
562589

563590
foreach ($captcha_array as $gfx_chk_i => $gfx_chk_lang) {
564591
$array = array(

includes/core/admin_functions.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ function nv_save_file_config_global()
145145
$config_variable['error_send_email'] = $config_variable['error_send_email'];
146146

147147
$config_name_array = ['file_allowed_ext', 'forbid_extensions', 'forbid_mimes', 'allow_sitelangs', 'allow_request_mods', 'config_sso'];
148-
$config_name_json = ['crosssite_valid_domains', 'crosssite_valid_ips', 'crossadmin_valid_domains', 'crossadmin_valid_ips'];
148+
$config_name_json = ['crosssite_valid_domains', 'crosssite_valid_ips', 'crossadmin_valid_domains', 'crossadmin_valid_ips', 'domains_whitelist'];
149149

150150
foreach ($config_variable as $c_config_name => $c_config_value) {
151151
if (in_array($c_config_name, $config_name_array)) {

includes/language/en/admin_settings.php

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
$lang_module['nv_allowed_html_tags'] = 'HTML code was approved in the system';
5151
$lang_module['nv_debug'] = 'Debug mode';
5252
$lang_module['nv_debug_help'] = 'If this option is enabled, the system will display errors to help developers easily check in the programming process. If your website is operating in a real environment, <strong>disable</strong> this option';
53+
$lang_module['domains_restrict'] = 'Limit domain names to dangerous HTML tags (iframe, object, embed...)';
54+
$lang_module['domains_whitelist'] = 'Trusted domain name (one domain per line). If enabled limit the domain name in the section above, the system will allow use of resources and links from these domains';
5355
$lang_module['captcha_type'] = 'Captcha type';
5456
$lang_module['captcha_type_0'] = 'Default captcha';
5557
$lang_module['captcha_type_1'] = 'Cool php captcha';

includes/language/fr/admin_settings.php

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
$lang_module['nv_allowed_html_tags'] = 'Code HTML est accepté par le système';
5151
$lang_module['nv_debug'] = 'Mode développeur';
5252
$lang_module['nv_debug_help'] = 'Si cette option est activée, le système affichera des erreurs pour aider les développeurs à vérifier facilement le processus de programmation. Si votre site Web fonctionne dans un environnement réel, <strong>désactivez</strong> cette option.';
53+
$lang_module['domains_restrict'] = 'Limitez les noms de domaine aux balises HTML dangereuses (iframe, object, embed...)';
54+
$lang_module['domains_whitelist'] = 'Nom de domaine approuvé (un domaine par ligne). S\'il est activé, limitez le nom de domaine dans la section ci-dessus, le système autorisera l\'utilisation des ressources et des liens de ces domaines';
5355
$lang_module['captcha_type'] = 'Type de captcha';
5456
$lang_module['captcha_type_0'] = 'Défaut captcha';
5557
$lang_module['captcha_type_1'] = 'Bon php captcha';

includes/language/vi/admin_settings.php

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
$lang_module['nv_allowed_html_tags'] = 'Mã HTML được chấp nhận sử dụng trong hệ thống';
5353
$lang_module['nv_debug'] = 'Chế độ nhà phát triển';
5454
$lang_module['nv_debug_help'] = 'Nếu bật tùy chọn này, hệ thống sẽ hiển thị các lỗi để giúp nhà phát triển dễ dàng kiểm tra trong quá trình lập trình. Nếu website đang hoạt động trên môi trường thật, bạn <strong>nên tắt</strong> tùy chọn này';
55+
$lang_module['domains_restrict'] = 'Giới hạn tên miền ở các thẻ HTML nguy hiểm (iframe, object, embed...)';
56+
$lang_module['domains_whitelist'] = 'Tên miền tin cậy (mỗi tên miền một dòng). Nếu kích hoạt giới hạn tên miền ở mục bên trên, hệ thống sẽ cho phép sử dụng tài nguyên, liên kết từ các tên miền này';
5557

5658
$lang_module['captcha_type'] = 'Loại captcha';
5759
$lang_module['captcha_type_0'] = 'Captcha mặc định';

install/data.php

+2
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@
148148
$sql_create_table[] = "INSERT INTO " . NV_CONFIG_GLOBALTABLE . " (lang, module, config_name, config_value) VALUES ('sys', 'global', 'crossadmin_restrict', '1')";
149149
$sql_create_table[] = "INSERT INTO " . NV_CONFIG_GLOBALTABLE . " (lang, module, config_name, config_value) VALUES ('sys', 'global', 'crossadmin_valid_domains', '')";
150150
$sql_create_table[] = "INSERT INTO " . NV_CONFIG_GLOBALTABLE . " (lang, module, config_name, config_value) VALUES ('sys', 'global', 'crossadmin_valid_ips', '')";
151+
$sql_create_table[] = "INSERT INTO " . NV_CONFIG_GLOBALTABLE . " (lang, module, config_name, config_value) VALUES ('sys', 'global', 'domains_whitelist', '[\"youtube.com\",\"www.youtube.com\",\"google.com\",\"www.google.com\",\"drive.google.com\"]')";
152+
$sql_create_table[] = "INSERT INTO " . NV_CONFIG_GLOBALTABLE . " (lang, module, config_name, config_value) VALUES ('sys', 'global', 'domains_restrict', '1')";
151153
$sql_create_table[] = "INSERT INTO " . NV_CONFIG_GLOBALTABLE . " (lang, module, config_name, config_value) VALUES ('sys', 'define', 'nv_gfx_width', '150')";
152154
$sql_create_table[] = "INSERT INTO " . NV_CONFIG_GLOBALTABLE . " (lang, module, config_name, config_value) VALUES ('sys', 'define', 'nv_gfx_height', '40')";
153155
$sql_create_table[] = "INSERT INTO " . NV_CONFIG_GLOBALTABLE . " (lang, module, config_name, config_value) VALUES ('sys', 'define', 'nv_max_width', '1500')";

themes/admin_default/modules/settings/security.tpl

+12
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@
105105
<td><strong>{LANG.nv_allowed_html_tags}</strong></td>
106106
<td><textarea name="nv_allowed_html_tags" class="form-control" style="height: 100px" class="required">{NV_ALLOWED_HTML_TAGS}</textarea></td>
107107
</tr>
108+
<tr>
109+
<td><strong>{LANG.domains_restrict}</strong></td>
110+
<td>
111+
<input type="checkbox" name="domains_restrict" value="1"{DOMAINS_RESTRICT}>
112+
</td>
113+
</tr>
114+
<tr>
115+
<td><strong>{LANG.domains_whitelist}</strong></td>
116+
<td>
117+
<textarea name="domains_whitelist" class="form-control" rows="5">{DOMAINS_WHITELIST}</textarea>
118+
</td>
119+
</tr>
108120
</tbody>
109121
<tfoot>
110122
<tr>

vendor/vinades/nukeviet/Core/Request.php

+26
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ class Request
135135
'base'
136136
];
137137

138+
protected $remoteAttrCheck = [
139+
'action' => ['form'],
140+
'src' => ['iframe', 'embed'],
141+
'data' => ['object']
142+
];
143+
138144
/**
139145
* Các attr bị cấm, sẽ bị lọc bỏ.
140146
* - Tất cả các arrt bắt đầu bằng on
@@ -191,6 +197,9 @@ class Request
191197

192198
protected $isIpValid = false;
193199

200+
protected $isRestrictDomain = true;
201+
protected $validDomains = [];
202+
194203
/**
195204
* @param array $config
196205
* @param string $ip Client IP
@@ -243,6 +252,9 @@ public function __construct($config, $ip)
243252
$this->validCrossIPs = !empty($config['crosssite_valid_ips']) ? ((array) $config['crosssite_valid_ips']) : [];
244253
}
245254

255+
$this->isRestrictDomain = !empty($config['domains_restrict']) ? true : false;
256+
$this->validDomains = !empty($config['domains_whitelist']) ? ((array) $config['domains_whitelist']) : [];
257+
246258
if (preg_match('#^(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$#', $ip)) {
247259
$ip2long = ip2long($ip);
248260
} else {
@@ -724,6 +736,20 @@ private function filterAttr($attrSet, $tagName, &$isvalid)
724736
];
725737
$value = preg_replace(array_values($search), array_keys($search), $value);
726738

739+
// Giới hạn link từ các tên miền bên ngoài
740+
if ($this->isRestrictDomain and isset($this->remoteAttrCheck[$attrSubSet[0]]) and in_array($tagName, $this->remoteAttrCheck[$attrSubSet[0]])) {
741+
$url_info = parse_url($value);
742+
if (isset($url_info['host'])) {
743+
$domain = $url_info['host'];
744+
$callBack = function ($domain_allowed) use ($domain) {
745+
return preg_match('/^' . preg_quote($domain, '/') . '$/iu', $domain_allowed);
746+
};
747+
if (!array_filter($this->validDomains, $callBack)) {
748+
continue;
749+
}
750+
}
751+
}
752+
727753
// Security remove object param tag
728754
if ('param' == $tagName and 'name' == $attrSubSet[0] and preg_match('/^[\r\n\s\t]*(allowscriptaccess|allownetworking)/isu', strtolower($value))) {
729755
return [];

0 commit comments

Comments
 (0)