Skip to content

Insecure direct object references (IDOR)

In this article I will try to give the basic explanation of Insecure Direct Object Reference (IDOR) as one of the most common types of broken access control vulnerability.

This can occur in the application where user-supplied input is used to access objects directly.

For example, this attack can occur when the server fails to validate an incoming HTTP request to access data/object. If the application cannot authenticate the user, some of the underlying object details will be public, and the attacker could easily see them. In that scenario, attackers can use revealed information such as the “id” parameter to continue the attack. In many web applications that use IDs to identify users, the admin will likely be equal to 0 or 1. A successful attack would compromise users’ sensitive information such as personal data (for example, financial details).

*Note: This attack is most seen when the database uses auto-incremental IDs, which are used to access the object via URL. There is one great article if you want to learn how to create autoincrement ID in a database.

This is one example how what it looks like when you are accessing an object by ID in URL:

https://test.com/user/id/1234

 

Application security gaps:

  • not sufficient authorization checks when accessing internal data
  • API reveals a direct reference to data or some logic that can contain helpful information for the successful attack
  • not appropriate user-supplied input validation
  • when authentication is just implemented on a front-end side of the application

All these gaps can impact unauthorized information disclosure, modification of data, destruction, and performing a function outside the user’s limits.

Types of IDOR Attacks explained on this site:

  1. Body Manipulation (modifying the value of checkboxes, API endpoints, radio buttons, and input form fields)
  2. URL Tampering Attacks (attacker alters HTTP request parameters by modifying URL parameters on the client-side: GET and POST)
  3. JSON ID Manipulation (attacker may intercept JSON data sent between APIs, servers, and the web application to gain unauthorized access to application configuration and data)
  4. Mass Assignment (attackers manipulate a record pattern to modify large data sets that they are not authorized to access)

Links for ID decoding

Keep in mind that when developing, if you are just going to encode an id which is a number that attackers can easily decode. Also, there is a site https://crackstation.net which uses massive pre-computed lookup tables to crack password hashes. So first, when you are deciding on which logic you are going to use for IDs, test them on these sites.

  1. https://gchq.github.io/CyberChef/
  2. https://www.base64encode.org/
  3. https://crackstation.net
  4. https://hashes.com/en/decrypt/hash
  5. https://www.dcode.fr/ (this site is in French, but you can translate it. If you are using Chrome; right-click on the site and press “Translate to English”)

Prevention steps: 

  • Implement access control policies to prevent user access outside of their intended permissions
  • Try to hash all sensitive data, such as functions and values
  • Try to use Globally Unique Identifiers (GUIDs) to identify reference objects, not just integers as id. GUID is a 128-bit text string that represents an identification. If you want to familiarize yourself more with GUID, you can check out this helpful site.
  • Apply authentication on the front end as well as in the back end. The best practice is to apply it on both sides, but if you need to choose, back end is the crucial side because it has direct access to the database
  • Use this approach for checking our permissions: intercept request when it is trying to access an object, check if the user has permission to view that type of resource or that resource

Use Default-Deny Approach

One of the approaches you can use is Default-Deny. 

What does it mean?

This approach first denies all access to the resource. After that, you should explicitly define the permissions and the relationships between the role and the requested object (resource).

Any request for a resource that is not explicitly allowed is automatically denied.

The alternative would be the allowed-first approach. In this case, you specify which permissions are denied, and all else will pass to the object. 

How to choose which approach to use?

The best practice when developing an application is to implement permissions before the application is in the production stage. In that time, you can see what it would be easier, depending on the application’s logic, to use deny first or allow first approach!

Use Route-Guards to secure Angular pages

You can implement route guards to allow, deny or redirect to another page view.

Route guards are used to restricting the manipulation of URLs. Imagine you have one application, and only the admin can see the users page so he can add or remove users:

https://test.com/users

If you implement a route guard in the application, you would be able to restrict who can enter the requested page.

I will show you what it looks like when the application uses Route guards. I will create one class that will present Role Guard, which implements the CanActivate interface from “@angular/router,” so we can use its canActivate method.

import { ActivatedRouteSnapshot, CanActivate, Router } from "@angular/router";
 
import { Injectable } from "@angular/core";
import { LocalStorageManager } from "app/common/services/local-storage.manager";
import { Observable } from "rxjs";
 
@Injectable()
export class RoleGuard implements CanActivate {
  constructor(
    private route: Router,
    private _localStorage: LocalStorageManager
  ) {}
 
  public canActivate(
    route: ActivatedRouteSnapshot
  ): Observable<boolean> | boolean {
    return this.isRoleAssigned(route.data.roles);
  }
 
  private isRoleAssigned(roles: string[]): boolean {
    let assignedRoles = this._localStorage.retrieveObject(
      this._localStorage.roles
    );
    if (assignedRoles.roles.filter((role) => roles.includes(role)).length > 0) {
      return true;
    } else {
      this.route.navigateByUrl("home");
      return false;
    }
  }
}

  

In this example, all roles are already stored in local storage, so we don’t call API and create an HTTP request each time when we need to get the roles.

Method isRoleAssigned is used to check if the user has a role that is the same as needed for accessing this page. If the user has the required role, then they can access the page and, in this case, it will return “true” if they don’t have the application, it will redirect tehm to the “home” page, and the method will return false.

We will get the required roles from the route.data.roles. You can see these roles in the picture below in app.routing.ts => data => roles.

The next step of the implementation is to import this class into the app module as providers:

@NgModule({
  imports: […],
declarations: […],
  providers: [ …, RoleGuard],
… })

The most important place where we will connect RouteGuard with the page (component) is in app.routing.ts

export const routes: Routes = [
  {
    path: " home",
    component: HomeComponent,
    data: { title: "Home" },
  },
  {
    path: "users",
    component: UserComponent,
    data: { title: Users, roles: ["Administrator"] },
    canActivate: [AuthGuard, RoleGuard]
  }
]

You can see in this picture that we don’t have any restrictions for the home page, but for the user page, we have added RoleGuard, and we will pass that only the Administrator can access this page.

This is some very simple code, but we have restricted the page access, so the attacker cannot manipulate and access pages from the URL! You can check out the site if you want to learn how to create AuthGuardService.

Useful links:

In one OWASP presentation there are some useful links for IDOR explanation and examples, if you want to check them out:

  1. https://codeburst.io/hunting-insecure-direct-object-reference-vulnerabilities-for-fun-and-profit-part-1-f338c6a52782
  2. https://www.gracefulsecurity.com/idor-insecure-direct-object-reference/
  3. https://medium.com/@woj_ciech/explaining-idor-in-almost-real-life-scenario-in-bug-bounty-program-c214008f8378
  4. https://blog.detectify.com/2016/05/25/owasp-top-10-insecure-direct-object-reference-4/

Conclusion

I showed some basic mistakes made while developing and some prevention steps to avoid them.

In my opinion, the most essential part of application security is authentication. This logic must be implemented in the right way. Of course, that means it needs to be tested in detail because it is too late if broken authentication passes to the production stage.

In the end, secure code is the cheapest code!

#IDOR #route_guard #vicarius_blog

Cover photo by Towfiqu barbhuiya

About Version 2 Digital

Version 2 Digital is one of the most dynamic IT companies in Asia. The company distributes a wide range of IT products across various areas including cyber security, cloud, data protection, end points, infrastructures, system monitoring, storage, networking, business productivity and communication products.

Through an extensive network of channels, point of sales, resellers, and partnership companies, Version 2 offers quality products and services which are highly acclaimed in the market. Its customers cover a wide spectrum which include Global 1000 enterprises, regional listed companies, different vertical industries, public utilities, Government, a vast number of successful SMEs, and consumers in various Asian cities.

About VRX
VRX is a consolidated vulnerability management platform that protects assets in real time. Its rich, integrated features efficiently pinpoint and remediate the largest risks to your cyber infrastructure. Resolve the most pressing threats with efficient automation features and precise contextual analysis.

Session Management Attacks – Part 2

If you are unfamiliar with Session Management, you can check out my previous article Session Management Part One

I will focus on prevention in this second part of the Session Management topic.

 It is very crucial to handle sessions properly. That means that the application needs to create, maintain, and destroy session tokens properly over the life cycle of the web session.

The two most common session management attacks are session hijacking and session fixation.

I came across a great  blog  you can check out for nice visually explained attacks.

 Session hijacking is the attack where the hacker can gather the information that will help him to reveal the session ID and hijack it and log in as a victim himself.

 After successful authentication, a session fixation attack happens when an application does not change the session ID.

 Preventing Session Management Vulnerabilities

This is an unordered list of the best prevention practices, so you can create a more secure application with “in theory” no session vulnerabilities.

  • Session identifier should remain confidential to the application. That can be achieved with:
  • Use HTTPS to transfer the session ID token
  • Don’t expose session ID in URL, in page content, hidden elements in DOM
  • Set secure flags on session ID token cookies, such as “secure” and “httpOnly” – These restrict cookie transfer to HTTPS, and cookies cannot be accessed by JavaScript. You can also check some flags you can use to secure cookies in the article Path Traversal.
  • Session ID token (cookie) should have a browser session lifetime. That means that cookies should not be stored in the file, but in the browser memory, so the content can disappear when the browser closes
  • Implementing an inactivity timeout for every session. Bellow in the text is an example how to implement timeout using Angular
  • When a user logs out, the session on the server should be terminated (proper logging out)
  • New session ID should be generated in response for the authentication to be successful
  • Use the latest web server framework to generate a new session ID token.
  • Pay attention to:
    • Session ID name should not describe details about the meaning of the content
    • Session ID length must be at least 128 bits (16 bytes).
    • Session ID must be random enough to prevent from easily guessing
    • Session ID content must be meaningless to prevent information disclosure
  • When the application is created for mobile devices, be aware that when you are invalidating a session, you should do it on the mobile and server sides. We can invalidate the session by calling session.invalidate() to destroy the session. 
  • In the mobile app, use the session timeout window. Timeout periods depend on the level of the security of the application, they are often:
    • High level – 15 min
    • Medium level – 30 min
    • Low level – 1 hour 
  • When resetting cookies, cover all authentication state changes, switch from guest user to logged-in user, one to another logged-in user, refresh after the timeout, etc.
  • In order not to be able to access data exchanged within the session, the application should use restrictive cache directives for all data that went through HTTP and HTTPS
  • Try to perform identity verification. Check the user’s usual IP address or application usage patterns in the application
  • Use a web application firewall (WAF)
  • When attackers use Brute-Force/Credential stuffing attacks, they attempt multiple logins. A good practice is to limit failed login attempts.
  • Enabling multi-factor authentication (MFA
  • Implement strong password policies
  • Implement all prevention steps to avoid XSS vulnerabilities which can be used to steal session IDs. Check out articles about XSS on Vicarius site
  • Don’t store passwords in cleartext
  • Implement solutions that match used passwords against a list of breached credentials, so users can know and not use the same credentials (breached password protection)
  • When using the secure attribute for cookie application, the “__Host” prefix can also prevent overwriting the user’s cookies.
  • Try not to use old legacy frameworks and develop with modern tools. If you need to use old technology, try to add a filter or use a configuration setting to disable dangerous functionalities. For example, J2EE supports session management via URL.
  • Use a strict CSP (Content Security Policy)
  • Use preloaded HSTS (HTTP Strict Transport Security) to force connections to the website to be encrypted. Enable protection by adding the ‘Strict-Transport-Security’ header. Include subdomains also and enable HSTS. For implementation check out site

Organization protection from session hijacking

It is also good to protect not just the application but your organization from these types of attacks. By organization, I mean the most crucial thing – customers or consumers. To protect consumers sessions, the organization can use certificates: 

  • SSL (Secure Sockets Layer) provides security to the data that is transferred between web browser and server. SSL encrypts the link between a web server and a browser which ensures that all data passed between them remain private and free from attack” – more info on site
  • TLS (Transport Layer Security) – which is more secured version of SSL. TLS ensures that no third party may eavesdrop or tampers with any message. More info on the site

Of course, there are also some steps that organizations can use these attacks, such as again

  • Keep the system up to date by setting up automatic updates on all devices.
  • Use antivirus software that can protect against session hijacking attackers
  • Incorporate web frameworks instead of inventing your own session management
  • Prevent consumers from using a public hotspot (WiFi)
  • Use a Virtual Private Network in the organization
  • Implement some checks and prevent phishing attacks. Clicking on an email session can be easily stolen.
  • Enabling multi-factor authentication (MFA)
  • Enforce using strong passwords

Tools for detecting session management attacks:

How to implement an Inactivity timer

In this example, I will show how to manually create an inactivity timer. You can also implement an Idle timeout if you want to use a third library for implementing timeout. There is a good article that describes the implementation.

Idle timeout is the time the user is inactive on the application. This timeout is needed for better security and to stop unnecessary API calls.

Implementation

  1. Create an array of events that you can check if they are not triggered for some time. That would mean that the user is inactive.
  public inactivityEvents: Array<any>[] = [
    [document, 'click'],
    [document, 'mousemove'],
    [document, 'keyup']
  ];

I added just three events as an example but don’t forget to add all necessary document and window events.

  1. Create observable out of the array of events and add subscribers. Here the time should start counting, aka inactive timer. The timer will reset when events are triggered.

Declare observableArray as an array of Observables and inactivityObservable as Observable. Also, declare timeout and implement NgZone.

We need to implement NgZone because we want to use its method runOutsideAngular because we want to do work without triggering Angular change detection.

  this.inactivityEvents.forEach(x => {
    observableArray$.push(fromEvent(x[0], x[1]))
  })
  this.inactivityObservable$ = merge(...observableArray$);
 
  this.ngZone.runOutsideAngular(() => {
 
    this.observeable$ = this.mergedObservable$
    .pipe(
      switchMap(ev => interval(1500).pipe(take(this.timeout))),
 
      tap(value => ...
        //here we can add logic for checking time left to inactivity and show notification to the user
        ),
 
      skipWhile((x) => {
        return x != this.timeout- 1
      })
    );
 
  this.subscription = this.observable$.subscribe((x) => {
   ...  
  })
  1. After the set time expires, unsubscribe the observable. That is the moment the timer runs out of time.
      this.subscription.unsubscribe();

Conclusion

I just scratched the Session Management topic and summarized it. I tried to provide some additional documentation on how to implement those preventions. As this topic is a big one, follow my next articles, where I will also present a few more prevention implementations.

You can also check out some OWASP suggestions for prevention on this site.

In the end, secure code is the cheapest code!

#session_management #inactivity_timer

Cover photo by Philipp Katzenberger

About Version 2 Digital

Version 2 Digital is one of the most dynamic IT companies in Asia. The company distributes a wide range of IT products across various areas including cyber security, cloud, data protection, end points, infrastructures, system monitoring, storage, networking, business productivity and communication products.

Through an extensive network of channels, point of sales, resellers, and partnership companies, Version 2 offers quality products and services which are highly acclaimed in the market. Its customers cover a wide spectrum which include Global 1000 enterprises, regional listed companies, different vertical industries, public utilities, Government, a vast number of successful SMEs, and consumers in various Asian cities.

About VRX
VRX is a consolidated vulnerability management platform that protects assets in real time. Its rich, integrated features efficiently pinpoint and remediate the largest risks to your cyber infrastructure. Resolve the most pressing threats with efficient automation features and precise contextual analysis.

×

Hello!

Click one of our contacts below to chat on WhatsApp

×