如何修复 codeigniter 中的漏洞问题?(权限提升、会话重放攻击和 HSTS 缺失)
How to fix vulnerable issue in codeigniter?(Privilege Escalation, Session Replay Attack and HSTS Missing)
我有 codeigniter 网络应用程序。当我使用 burp 扫描应用程序时,我遇到了一些安全问题-suite.Can 你告诉我要解决以下安全问题。
问题是:
非随机 CSRF 令牌 -
建议生成每个用户会话唯一的随机令牌,随机值大,并且
由加密安全随机数生成器生成。
易受跨站请求伪造攻击 -
推荐使用 Token Based Mitigation;通过在 html 请求
中实现同步器令牌模式
权限升级 -
建议妥善处理普通用户无法访问受限 URL
的会话
会话重放攻击-
建议开发会话处理方法以确保用户会话在浏览器终止时结束
仅设置没有 HTTP 标志的 Cookie
- 未启用安全通信强制。 (HTTPS 服务器缺少 HSTS)
我的login.php
<script type="text/javascript">
$(document).ready(function(){
$.ajaxSetup({
data: {
'<?php echo $this->security->get_csrf_token_name(); ?>' : '<?php echo $this->security->get_csrf_hash(); ?>'
}
});
});
</script>
<form>
<input type="hidden" name="<?php echo $this->security->get_csrf_token_name(); ?>" value="<?php echo $this->security->get_csrf_hash(); ?>" />
<input autocorrect="off" maxlength="50" autocapitalize="off" autocomplete="off" name='email' id='email' type='text' />
<input name='current_url' id='current_url' value="<?php echo $current_url; ?>" type='hidden'/>
<input name='password' id='password' maxlength="50" type='password' autocorrect="off" autocapitalize="off" autocomplete="off" />
<input type="submit" value="Login" name="btnsubmit" />
</form>
这是我的config.php
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_token_myapp';
$config['csrf_cookie_name'] = 'csrf_cookie_myapp';
$config['csrf_expire'] = 1200;
$config['csrf_regenerate'] = TRUE;
$config['cookie_prefix'] = 'myweb_c_';
$config['cookie_domain'] = '';
$config['cookie_path'] = '/';
$config['cookie_secure'] = FALSE;
$config['cookie_httponly'] = TRUE;
$config['sess_driver'] = 'files';
$config['sess_cookie_name'] = 'pay_web';
$config['sess_expiration'] = 900;
$config['sess_save_path'] = '\storage\'
$config['sess_match_ip'] = TRUE;
$config['sess_time_to_update'] = 60;
$config['sess_regenerate_destroy'] = TRUE;
$config['charset'] = 'UTF-8';
$config['enable_hooks'] = FALSE;
$config['cache_query_string'] = FALSE;
$config['encryption_key'] = 'MKNNWNnsanas^@&#(@(*88899';
$config['composer_autoload'] = FALSE;
我需要加密当前 url、用户名和密码。下面一行是我从 burp-suite 得到的。
csrf_token_myapp=3d44fd27c845cf3eb8cb521233c52150&csrf_token_myapp=3d44fd27c845cf3eb8cb521233c52150&email=admin%40test.lk¤t_url=&password=test1234567&btnsubmit=Login
预期方法的用法是将前端表单的值加密后发送到服务器,然后从服务器端使用PHP解密。中间层可以将提交的结果视为加密值。
加密: 使用 CryptoJS
中的 AES
(在浏览器中):
(function() {
var encrypted = CryptoJS.AES.encrypt("I am a hacker", "MYKEY");
console.log(encrypted.toString());
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
解密:使用openssl_decrypt
中的aes-256-cbc
(在PHP中):
<?php
function decryptAES($edata, $password)
{
$data = base64_decode($edata);
$salt = substr($data, 8, 8);
$ct = substr($data, 16);
$rounds = 3;
$data00 = $password . $salt;
$md5_hash = array();
$md5_hash[0] = md5($data00, true);
$result = $md5_hash[0];
for ($i = 1; $i < $rounds; $i++) {
$md5_hash[$i] = md5($md5_hash[$i - 1] . $data00, true);
$result .= $md5_hash[$i];
}
$key = substr($result, 0, 32);
$iv = substr($result, 32, 16);
$decrypted = openssl_decrypt($ct, 'aes-256-cbc', $key, true, $iv);
return $decrypted;
}
$password = 'MYKEY';
$edata = 'U2FsdGVkX1+H/Mqv5QgZzAHAXdoGVE1kY9uyfYJKbaA=';
echo decryptAES($edata, $password) . "\n";
// Output - I am a hacker
This encryption way is not a perfect way to encrypt form data since you store the secret key at the front-end side which can be decrypted over the browser developer tools. The best way is to focus on strong security validations from your server-side.
我有 codeigniter 网络应用程序。当我使用 burp 扫描应用程序时,我遇到了一些安全问题-suite.Can 你告诉我要解决以下安全问题。
问题是:
非随机 CSRF 令牌 -
建议生成每个用户会话唯一的随机令牌,随机值大,并且 由加密安全随机数生成器生成。易受跨站请求伪造攻击 - 推荐使用 Token Based Mitigation;通过在 html 请求
中实现同步器令牌模式
权限升级 - 建议妥善处理普通用户无法访问受限 URL
的会话
会话重放攻击- 建议开发会话处理方法以确保用户会话在浏览器终止时结束
仅设置没有 HTTP 标志的 Cookie
- 未启用安全通信强制。 (HTTPS 服务器缺少 HSTS)
我的login.php
<script type="text/javascript">
$(document).ready(function(){
$.ajaxSetup({
data: {
'<?php echo $this->security->get_csrf_token_name(); ?>' : '<?php echo $this->security->get_csrf_hash(); ?>'
}
});
});
</script>
<form>
<input type="hidden" name="<?php echo $this->security->get_csrf_token_name(); ?>" value="<?php echo $this->security->get_csrf_hash(); ?>" />
<input autocorrect="off" maxlength="50" autocapitalize="off" autocomplete="off" name='email' id='email' type='text' />
<input name='current_url' id='current_url' value="<?php echo $current_url; ?>" type='hidden'/>
<input name='password' id='password' maxlength="50" type='password' autocorrect="off" autocapitalize="off" autocomplete="off" />
<input type="submit" value="Login" name="btnsubmit" />
</form>
这是我的config.php
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_token_myapp';
$config['csrf_cookie_name'] = 'csrf_cookie_myapp';
$config['csrf_expire'] = 1200;
$config['csrf_regenerate'] = TRUE;
$config['cookie_prefix'] = 'myweb_c_';
$config['cookie_domain'] = '';
$config['cookie_path'] = '/';
$config['cookie_secure'] = FALSE;
$config['cookie_httponly'] = TRUE;
$config['sess_driver'] = 'files';
$config['sess_cookie_name'] = 'pay_web';
$config['sess_expiration'] = 900;
$config['sess_save_path'] = '\storage\'
$config['sess_match_ip'] = TRUE;
$config['sess_time_to_update'] = 60;
$config['sess_regenerate_destroy'] = TRUE;
$config['charset'] = 'UTF-8';
$config['enable_hooks'] = FALSE;
$config['cache_query_string'] = FALSE;
$config['encryption_key'] = 'MKNNWNnsanas^@&#(@(*88899';
$config['composer_autoload'] = FALSE;
我需要加密当前 url、用户名和密码。下面一行是我从 burp-suite 得到的。
csrf_token_myapp=3d44fd27c845cf3eb8cb521233c52150&csrf_token_myapp=3d44fd27c845cf3eb8cb521233c52150&email=admin%40test.lk¤t_url=&password=test1234567&btnsubmit=Login
预期方法的用法是将前端表单的值加密后发送到服务器,然后从服务器端使用PHP解密。中间层可以将提交的结果视为加密值。
加密: 使用 CryptoJS
中的 AES
(在浏览器中):
(function() {
var encrypted = CryptoJS.AES.encrypt("I am a hacker", "MYKEY");
console.log(encrypted.toString());
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
解密:使用openssl_decrypt
中的aes-256-cbc
(在PHP中):
<?php
function decryptAES($edata, $password)
{
$data = base64_decode($edata);
$salt = substr($data, 8, 8);
$ct = substr($data, 16);
$rounds = 3;
$data00 = $password . $salt;
$md5_hash = array();
$md5_hash[0] = md5($data00, true);
$result = $md5_hash[0];
for ($i = 1; $i < $rounds; $i++) {
$md5_hash[$i] = md5($md5_hash[$i - 1] . $data00, true);
$result .= $md5_hash[$i];
}
$key = substr($result, 0, 32);
$iv = substr($result, 32, 16);
$decrypted = openssl_decrypt($ct, 'aes-256-cbc', $key, true, $iv);
return $decrypted;
}
$password = 'MYKEY';
$edata = 'U2FsdGVkX1+H/Mqv5QgZzAHAXdoGVE1kY9uyfYJKbaA=';
echo decryptAES($edata, $password) . "\n";
// Output - I am a hacker
This encryption way is not a perfect way to encrypt form data since you store the secret key at the front-end side which can be decrypted over the browser developer tools. The best way is to focus on strong security validations from your server-side.