Critical Auth Bypass: Missing Await In Permission Checks

Alex Johnson
-
Critical Auth Bypass: Missing Await In Permission Checks

An authorization bypass vulnerability exists due to missing await keywords on asynchronous permission checks within the IDOL codebase. This article delves into the specifics of the vulnerability, its implications, and how it can be exploited, providing a comprehensive understanding for developers and security enthusiasts.

Discussion

This vulnerability, found in the cornell-dti/idol repository, stems from the improper handling of promises returned by asynchronous permission checks. Specifically, methods like PermissionsManager.isLeadOrAdmin are called without awaiting their resolution. Let's explore the core issues.

The Root Cause: Asynchronous Operations Without Await

At the heart of this vulnerability lies the omission of the await keyword when calling asynchronous permission checks. In JavaScript and TypeScript, the await keyword is crucial for pausing the execution of an async function until a promise is resolved. When an async function returns a promise, failing to await it means the program continues executing without waiting for the promise to fulfill or reject. This can lead to unexpected behavior, especially in the context of permission checks.

Consider the code snippet provided:

if (!PermissionsManager.isLeadOrAdmin(user))
  throw new PermissionError(
    'User does not have permission to update interview scheduler instance.'
  );

In this scenario, PermissionsManager.isLeadOrAdmin(user) returns a Promise. Without await, the if condition evaluates the Promise object itself, which is always truthy, rather than the boolean result of the permission check. Consequently, the permission check effectively becomes a no-op, granting unauthorized access.

Impact and Implications

The implications of this vulnerability are severe. Because the permission checks are bypassed, any authenticated user can perform administrative operations. This includes actions such as:

  • Deleting interview schedulers
  • Deleting team events
  • Modifying user portfolios

This unauthorized access can lead to data breaches, data manipulation, and other malicious activities, compromising the integrity and confidentiality of the application.

Real-World Example: Deleting Team Events

To illustrate the vulnerability, consider the example provided for deleting team events. A regular, non-admin user can delete any existing team event by sending a DELETE request to the appropriate API endpoint:

curl -X DELETE \
  https://idol.cornelldti.org/.netlify/functions/api/team-event/some-uuid \
  -H "auth-token: REGULAR_USER_TOKEN"

If the some-uuid exists, the event will be deleted, regardless of the user's permissions. If the some-uuid does not exist, the expected return would be a 403 (Forbidden) error, indicating that the user lacks permission to perform the action. However, due to the bypassed permission check, a 404 (Not Found) error is returned instead.

This example demonstrates how a seemingly minor oversight—forgetting to await a promise—can lead to a critical security vulnerability with far-reaching consequences. It underscores the importance of thorough code reviews and security testing to identify and mitigate such issues.

Identifying Vulnerable Endpoints

The report indicates that this pattern is repeated across at least 10 different API endpoints. Identifying these endpoints is crucial for remediation. Developers should conduct a thorough audit of the codebase, specifically looking for instances where asynchronous permission checks are performed without the await keyword. Tools like static analysis and linters can be configured to automatically detect such occurrences, helping to prevent future vulnerabilities.

Remediation Steps

Fixing this vulnerability requires adding the await keyword to all instances of asynchronous permission checks. For example, the code snippet mentioned earlier should be modified as follows:

if (!(await PermissionsManager.isLeadOrAdmin(user)))
  throw new PermissionError(
    'User does not have permission to update interview scheduler instance.'
  );

By adding await, the code will now wait for the promise to resolve and correctly evaluate the permission check before proceeding. This ensures that only authorized users can perform administrative operations.

Additional Security Considerations

In addition to fixing the immediate vulnerability, developers should also consider implementing additional security measures to prevent similar issues in the future. These measures include:

  • Code Reviews: Conduct thorough code reviews to identify potential security vulnerabilities.
  • Static Analysis: Use static analysis tools to automatically detect common coding errors and security flaws.
  • Security Testing: Perform regular security testing, including penetration testing and vulnerability scanning, to identify and address potential weaknesses.
  • Principle of Least Privilege: Follow the principle of least privilege, granting users only the minimum level of access required to perform their tasks.

Responsible Disclosure

The reporter of this vulnerability has demonstrated responsible disclosure by reporting the issue to the developers without exploiting it for malicious purposes. Responsible disclosure is an essential practice for maintaining the security of software systems. It allows developers to address vulnerabilities before they can be exploited by malicious actors.

Conclusion

The authorization bypass vulnerability caused by missing await keywords on asynchronous permission checks poses a significant risk to the IDOL application. By understanding the root cause of the vulnerability, its potential impact, and the necessary remediation steps, developers can effectively address the issue and prevent similar vulnerabilities in the future. Emphasizing secure coding practices, thorough code reviews, and proactive security testing is crucial for maintaining the integrity and confidentiality of software systems.

I've also identified a couple of other security issues (~ 4 more so far) across the IDOL codebase. This authorization bypass appears to be the most critical and easiest to fix, so I wanted to report it first. I might open separate, more detailed issues for the other findings as time allows.

Disclaimer: I do not have access to login as user, thus I have not and cannot used this vulnerability to access, modify, or delete any production data in any malicious manner.

For more information on secure coding practices, visit OWASP.

You may also like