Search code examples
phpcodeigniter-3burp

How to fix vulnerable issue in codeigniter?(Privilege Escalation, Session Replay Attack and HSTS Missing)


I have codeigniter web apllication. i am facing some security issues when i am scanning application with burp-suite.Can you tell me to fix following security issues.

The issues are :

  1. Non-randomized CSRF Token -
    It is recommended to generate random token that is unique per user session, large random value, and also generated by a cryptographically secure random number generator.

  2. Vulnerable to Cross-Site Request Forgery Attack - It is recommended to use Token Based Mitigation; by implementing Synchronizer token pattern in html requests

  3. Privilege Escalation - It is recommended that the sessions are handled properly where a normal user cannot visit a restricted URL

  4. Session Replay Attack - It is recommended to develop session handling methodologies to make sure that a user session ends upon the termination of the browser

  5. Cookie without HTTP Flag only set

  6. Secure communication enforcing is not enabled. (HSTS Missing From HTTPS Server)

My 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>

This is my 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;

I need to encrypt current url, username and password. following line i am getting from burp-suite. csrf_token_myapp=3d44fd27c845cf3eb8cb521233c52150&csrf_token_myapp=3d44fd27c845cf3eb8cb521233c52150&email=admin%40test.lk&current_url=&password=test1234567&btnsubmit=Login


Solution

  • The usage of the expected method is to encrypt the value of the front-end form and send it to the server, then it should be decrypted from the server-side using PHP. The middle layers can see the submitted result as an encrypted value.

    Encryption: Using AES from CryptoJS (In browser):

    (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>


    Decryption: Using aes-256-cbc from openssl_decrypt (In 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.