Over 10 years we help companies reach their financial and branding goals. Engitech is a values-driven technology agency dedicated.

Gallery

Contacts

411 University St, Seattle, USA

engitech@oceanthemes.net

+1 -800-456-478-23

Web Application Security Testing
vulnerability scanning

CakePHP Application Cybersecurity Research – Bypassing security mechanisms in CakePHP vulnerability scanning

Vulnerability Scanning of CakePHP Applications

If you want to perform vulnerability scanning of your CakePHP-based web application, you have to make sure to correctly configure your scanner. Otherwise, it won’t be effective and you will get a false sense of security because it won’t find web application vulnerabilities. For a CakePHP-based web application, it may be very difficult or even impossible to correctly configure a tool performing vulnerability scanning. However, there are ways to solve this problem and perform successful vulnerability scanning. The examples I’m showing here are based on the Burp Suite Pro scanner. This is one of the most popular DAST scanners used by cybersecurity experts, penetration testers, bug hunters, and organizations that implement it as part of their CI/CD process.

!This is the third article in the “CakePHP Application Cybersecurity Research” series where I describe the security mechanisms in web applications based on CakePHP framework such as authentication, blackholing, and CSRF protection. I’m also showing how to bypass those protections to successfully perform vulnerability scanning. Here you can find the other articles in the series:

In this article you will find:

Vulnerability scanning vs the authentication

Authentication is one of the most important security mechanisms in most web applications, not only present in applications based on CakePHP. Authentication is a process of verifying the identity of the user. Whenever you provide your username and password to login to the application, this is the authentication process. If the application implements multi factor authentication or social media login, this is also part of authentication.

To ensure that the vulnerability scanning process scans as many endpoints as possible, we must ensure that the scanner can successfully authenticate to the application. Otherwise, the scanner will only see the login page and a few other pages that are available to unauthenticated users.

The CakePHP framework allows web developers to implement authentication using various plugins. The most common plugin is the Authentication plugin created by the developers of the CakePHP framework. There are other plugins that support other types of authentications, such as JWT, social media, two factor authentication, and more. All of these methods will require different configurations before vulnerability scanning can begin. In this article, I will focus on the most popular plugin created by the CakePHP developers.

CEO, Cybersecurity Expert

If you would like to conduct a white box penetration testing of your web application leave your email and I will contact you.

Book a chat with me

    Authenticated vulnerability scanning using Burp Pro scanner

    From a security perspective, authentication using login and password in CakePHP applications is very similar to authentication in other applications. In this case we can configure the vulnerability scanning tool to properly authenticate before conducting the scan.

    In the Burp Suite Pro scanner, we can do this when creating a new scan. First, you need to click on the New Scan button in the dashboard tab:

    Second, you need to specify the URLs to scan and define the scan type as shown below:

    Once you get to the Application Login section, you will need to create new login credentials:

    After this stage, you can click OK to start the scan:

    Once the scan starts, you can click on the “View details” link and go to the Logger tab:

    In the Logger tab you can see that at some point, the scanner will authenticate to the application to access other features.

    In the screenshot below you can see the credentials we provided in the vulnerability scanning configuration. The application authenticates the scanner correctly:

    Note that some configurations may use the authentication credentials differently. This can result in limited vulnerability scanning due to account lockout. In our example above we used the “Light Only” scanning configuration.

    If your scanner cannot pass the authentication process you can still bypass the authentication using an alternate method described in the “Disabling authentication in CakePHP” section of this article.

    Limiting web application vulnerabilities with authorization and access control

    Authentication is often confused with authorization. The purpose of authorization is not to verify the identity of the user but to verify already authenticated user’s privileges and permissions to data and functionality of the application. The simplest example of this would be an e-commerce application. You can imagine that two users authenticate to the application, place orders for different products, and receive an invoice for their respective orders. It seems obvious that one user should not be able to see the invoice of the other user, even though they are both authenticated to the application. Equally, if not more important, a non -customer should not be able to see either invoice. This protection is called authorization.

    Authorization and access control in CakePHP

    When analyzing the permissions and privileges of users in an application based on CakePHP, access control is a synonym for the authorization.

    However, there are situations where these terms are not interchangeable. In such situations, authorization is a process of defining the levels of access for sepcific users, user types, roles, groups, and so on. Access control, on the other hand enforces these definitions, sometimes adding additional policies such as geographic restrictions, device type restrictions, and so on.

    Regardless of the situation, these two terms are used closely together.

    In CakePHP web applications, authorization is also implemented by plugins, similarly the most common plugin is from CakePHP development team “Authorization”.

    The implementation of the authorization process can actually vary from application to application.

    For example, Cerebrate defines which resources can be accessed by which type of users in a dedicated ACLComponent.

    In the screenshot below, you can see that some controller-action pairs can be accessed by users with the “perm_admin” role, and others can be accessed by any authenticated user.

    Other applications can specify the required roles or permissions within actions in controller files. An example is the PassBolt addPost action of the UsersAdd controller:

    This is often the case when a different behavior of the action is triggered depending on the user’s role who performs the action.

    The application can also indicate controllers that are accessible to unauthenticated users by calling the skipAuthorization method of the Authorization component. It is worth looking for this in the code to find the most exposed areas of the application.

    Security Component in CakePHP

    The CakePHP SecurityComponent protects against several types of web application vulnerabilities. It can be implemented in the application’s controllers using the following instruction:

    $this->loadComponent(‘Security’);

    Once it’s loaded, the form tampering prevention is enabled.

    Discovering more web application vulnerabilities by bypassing form tampering prevention

    By default, form tampering prevention in the CakePHP framework validates all POST requests and ensures that only the expected parameters are provided. This mechanism blocks all requests that match at least one of the following conditions:

    • An unexpected field is added to the POST request
    • A required POST field has been removed from the request
    • Hidden field value has been modified

    It is essentially an advanced whitelisting mechanism for POST request body parameters.

    This means that if you intercept a POST request and add a new parameter to it, CakePHP will block it.

    The CakePHP framework’s SecurityComponent implements this protection by calculating a hash of the expected parameters and sending that hash in POST requests. This is done in the SecurityComponent.php file, in the _validatePost method:

    protected function _validatePost(Controller $controller): void
    {
           $token = $this->_validToken($controller);
           $hashParts = $this->_hashParts($controller);
           $check = hash_hmac('sha1', implode('', $hashParts), Security::getSalt());
    
    
           if (hash_equals($check, $token)) {
               return;
           }
    

    Line 1 is the extraction of the token sent in the HTTP request _Token[fields].

    Line 2 extracts the information from the request that will be hashed later. The $hashParts is an array containing the following information:

    1. URL path. For example: /EncryptionKeys/edit/2
    2. Serialized and sorted POST parameter names associated with this particular request. For example: “a:3:{i:0;s:14:”encryption_key”;i:1;s:7:”revoked”;i:2;s:4:”type”;}”
      This does not include generic parameters such as _method, _csrfToken, or _Token and excludes unlocked parameters.
    3. The value of the _Token[unlocked].
    4. Session identifier

    Elements of this array are concatenated into a string. A SHA1 hash is then calculated using the application salt in line 3.

    If the calculated hash matches the hash provided in the _Token[fields], the request passes validation and proceeds to further verification.

    Bypassing form tampering prevention in white box penetration testing

    Is it possible to bypass this protection?

    The first thing to note is that some controller actions may have disabled this protection.

    To look for the disabled actions in the controller source code files look for lines similar to the following:

    $this->Security->setConfig('unlockedActions', ['edit']);

    The above line disables the edit action.

    Sometimes the protection can be disabled for the entire controller or even the entire application. The following line disables the protection for the controller:

    $this->Security->setConfig('validatePost', false);

    If you are performing a black-box penetration testing of a web application, you can blindly detect it by adding a parameter to all POST requests of various controller actions.

    Sometimes, applications disable form tampering prevention for API requests. You can try adding the Accept request header with JSON/XML value or the X-Requested-With header.

    In a white box penetration testing you can freely add your parameters but you must make sure that you provide a proper hash of the POST body. In order to do that, you need to get access to the salt, which is stored in the config files or in the SECURITY_SALT environmental variable.

    Once you have it, you can use the following script to generate a simple post body token:

    import argparse
    
    
    from urllib.parse import unquote
    import hmac
    
    
    
    
    def parse_arguments():
       parser = argparse.ArgumentParser()
       parser.add_argument(
           "-s",
           "--salt",
           help="CakePHP application salt",
           required=True,
       )
       parser.add_argument(
           "-p",
           "--path",
           help=f"URL Path",
           required=True,
       )
       parser.add_argument(
           "-b",
           "--body",
           help=f"POST body",
           required=True,
       )
       parser.add_argument(
           "--ssid",
           help=f"Session ID",
           required=True,
       )
       args = parser.parse_args()
       return args
    
    
    
    
    def serialize(array):
       result = f"a:{len(array)}:{{"
       for i in range(len(array)):
           element = array[i]
           result += f"i:{i};s:{len(element)}:\"{element}\";"
       result += "}"
       return result
    
    
    
    
    def main():
       args = parse_arguments()
    
    
       post_body = unquote(args.body)
    
    
       fields_flat = post_body.split("&")
       fields = []
       skip = ["_method", "_csrfToken", "_Token"]
       for val in fields_flat:
           k, v = val.split("=", 1)
           if(k == "_Token[unlocked]"):
               unlocked = v
           if "[" in k:
               k = k[:k.find("[")]
           if k not in skip:
               fields.append(k)
    
    
       fields.sort()
       serialized = serialize(fields)
       hashParts = [args.path, serialized, unlocked, args.ssid]
       hmac1 = hmac.new(key=args.salt.encode(), msg="".join(hashParts).encode(), digestmod="sha1")
       digest = hmac1.hexdigest()
    
    
       print(digest)
    
    
    
    
    if __name__ == '__main__':
       main()
    

    This script won’t work if you want to add an array like this: name[key1]=value. It’s a script that works for simple name=value parameters. 

    To fully automate it, you can create a reverse proxy that parses your POST requests and automatically appends the calculated hash for you.

    Let me know in the comments if you want to see how to create one.

    Keep in mind that if you discover a vulnerability that requires the addition of a new POST parameter, you must make sure that the form tampering protection is bypassed. Otherwise, the vulnerability cannot be exploited and has no real impact.

    CSRF protection reduces the vulnerability scanning coverage

    Cross-Site Request Forgery is a vulnerability that allows attackers to unknowingly trick privileged users into performing actions on the application.

    CakePHP has a dedicated middleware to defend against this type of attack. It’s called CsrfProtectionMiddleware.

    The CSRF protection starts with the generation of the token that is stored in cookies and inserted as a hidden field in each form of the web application.

    When a user sends the request to change the state of the application (POST, PUT, DELETE, and other methods) two stages of the verification happen:

    First, the cookie is verified:

           $decoded = base64_decode($token, true);
           // ...
           $key = substr($decoded, 0, static::TOKEN_VALUE_LENGTH);
           $hmac = substr($decoded, static::TOKEN_VALUE_LENGTH);
    
    
           $expectedHmac = hash_hmac('sha1', $key, Security::getSalt());
    
    
           return hash_equals($hmac, $expectedHmac);

    • In line 1, the cookie token is base64 decoded. 
    • Lines 3 and 4 split the token into the main part – the key (usually 16 or 32 bytes) and the HMAC.
    • In line 6, the application calculates the SHA1 hash of the key using the salt. This part is similar to the form tampering prevention mechanism.
    • In line 8, the calculated hash of the key is compared to the hmac in the cookie.
    • In practice the cookie looks like this:

    csrfToken=7Jn8bE1rg7NPJRcWp67GljAwM2RlMTk2MGViYTU5OTY5YzY4Mzg4NjBjYzQ5ZWI3ZTRiNGRhYjk=

    The second step is to check that the token provided in the POST body matches the token in the cookie.

    If both checks pass, the CSRF middleware forwards the request further.

    CakePHP Blackholing

    Blackholing is a process of redirecting all potentially malicious requests without actually starting to execute the MVC flow. If any of the security checks conducted by the SecurityComponent fail, your HTTP request will be blocked and it will not reach your desired controller, model, and view.

    Instead of that, the application will present you with the information about the black-holing request:

    Another example of a black-holed request due to CSRF protection:

    This is basically the result of the protections explained above being triggered.

    Some applications may implement custom black-hole pages so you may see a different error message.

    Bypassing protections by modifying the CakePHP framework code

    If you are conducting a white box penetration testing you can modify the CakePHP source code and disable these protections. This way you can conduct vulnerability scanning without worrying about CakePHP blocking some requests.

    Disabling authentication in CakePHP

    To disable the authentication implemented by the Authentication plugin, I created a patch that you can apply in the /vendor/cakephp/authentication/src directory:

    patch AuthenticationService.php AuthenticationService.php.patch

    You will also need to copy the fake identifier file into the Identifier directory as shown in the following screenshot:

    Once you do this, all future HTTP requests to the application will be authenticated as the first user in the database:

    You can see that there is no session cookie, and yet the web application responds with an HTTP 200 and a list of users.

    The patch and the fake identifier remove the authentication with the following steps:

    1. First we register the fake identifier inside the AuthenticationService constructor (patch line 16).
    2. Then, we replace the real authentication with our fake authentication method (patch line 24).
    3. In the fake authentication method we load the fake identifier (patch line 45), and retrieve the first user’s data from the database (patch line 47).
    4. If this went successful we populate the Results object with the user’s data (patch line 52) and return the result (patch line 57).

    If you want to go back to the original state where requests must be authenticated, revert the patch by running:

    patch --reverse AuthenticationService.php AuthenticationService.php.patch

    Disabling blackholing and form tampering protection

    There may be some cases where other CakePHP protections trigger a blackhole event. To avoid this you can comment out the execution of the blackHole method in the SecurityComponent.php file.

    Disabling CSRF protection

    CSRF protection can be disabled by adding a simple return; at the beginning of these methods:

    CLASSMETHODLINK
    CsrfProtectionMiddleware_validateTokenhttps://github.com/cakephp/cakephp/blob/4.x/src/Http/Middleware/CsrfProtectionMiddleware.php#L385
    SessionCsrfProtectionMiddlewarevalidateTokenhttps://github.com/cakephp/cakephp/blob/4.x/src/Http/Middleware/SessionCsrfProtectionMiddleware.php#L243

    Once you have done this, the code should look similar to the following.

    SessionCsrfProtectionMiddleware:

    CsrfProtectionMiddleware:

    Keep in mind that this alone does not disable the form tampering protection. You need to do it as described above.

    !In the next article we are going to show you an example of a critical SQL injection vulnerability in MISP, CakePHP-based software. This type of vulnerability is very difficult to detect and very impactful at the same time.

    Cybersecurity Research Service

    Finding security professionals who can perform services such as vulnerability assessment or penetration testing is not an easy task. It is even more difficult is to find a team whose findings reflect their knowledge and understanding of the technologies involved in cybersecurity research.

    If you are looking for deep technical expertise in cybersecurity we offer a cybersecurity research service where we dive deep into difficult cybersecurity problems and produce solutions that go beyond a typical service or a tool offering.

    Visit the cybersecurity service page.

    Resources:

    web application penetration tests information

    Is this article helpful to you? Share it with your friends.

    Author

    Dawid Czarnecki