StackHawk
Hamburger Icon

Angular Excessive
Data Exposure:
Examples and Prevention

stackhawk

StackHawk|May 15, 2022

Understand what excessive data exposure is with examples and learn how you can prevent it in your angular application.

As a front-end developer, you've built tons of great features. You've handcrafted amazing UI/UX elements. You've probably also catered to security concerns in a web application. But when it comes to back-end interactions, you might feel limited in what you control, especially with respect to the data that comes back from the server. 

Even with the utmost caution, a common yet lethal vulnerability in your application can be introduced. The reason for this could be simply because the server sends back unnecessary or extra sensitive data back to the client. This leads to excessive data exposure in your application. So what can we do about it? How can we prevent it? 

In this post, I'll show you what excessive data exposure is, and I'll provide you with some examples. Then I'll walk you through how you can prevent it in your Angular application.

What is Excessive Data Exposure?

Let's say you have an Angular application that interacts with a remote back-end server to get a bunch of data for different pages. Whenever your users loads a page, you request the required data from the back end and display it to the user. So, for example, if your user is visiting an "offers" page, you display them a bunch of cool offers on your website. 

Now, if they visit a different page, say an "about" page, you display your website's "about" information fetched from an API. But are your Angular components really aware of what data each API is returning? Or are they only concerned with the data that they require in that instance? 

Angular Excessive Data Exposure: Examples and Prevention
 image

I bet it's the latter. This is because how your back-end APIs are structured is immaterial to your front-end codebase. So when you visited the "offers" page, maybe the API returned the offers data alongside some extra information that you're not using. But wait, no big deal, right? As long as the front end receives the data it wants, everything else can be ignored, correct? 

Not exactly. We know that browsers make it really simple to inspect network requests via the developer tools.

The extra sensitive data that your back-end API returns can be of significant use to an attacker.

They can use it to steal some information about your users. 

This is called excessive data exposure. It's a situation where critical and sensitive data is unnecessarily exposed by your application. If this was hard to understand, let's dive deeper into it with an example. 

Excessive Data Exposure: Example

Let's say your Angular app is a social media application. Your users can create their own profile, share posts, etc. Let's say your users can share someone's profile with other users. So when you click the Share button, you can see that user's profile. Sounds good and safe, right? 

But now let's say that the back-end API that fetches a user's data accidentally also fetches that user's access token. You'll probably ignore it, or you may not even notice it since you don't make use of that data on the front end anywhere. However, that piece of information is sensitive, and literally anyone can extract it by inspecting the network request on that page. 

Here's the entire flow demonstrated visually: 

Angular Excessive Data Exposure: Examples and Prevention
 image

This is an example of excessive data exposure. An attacker who gains access to a user's access token can easily break into their accounts. Then they can modify their information in your database. They can even gain access to data such as their passwords, bank details, etc. 

Methods to Prevent Excessive Data Exposure

We'll talk about two primary methods to prevent excessive data exposure. Each of these methods assumes a different kind of API architecture for your application. 

Back End Based Prevention

First, if you're using REST APIs, you need to refactor those APIs in terms of what data they're sending back. Sometimes an API runs a query to grab all the data in a row of a table and dumps it back to the client. With this, it may send data that's of no use to the client and is also considered sensitive from a security standpoint. 

For instance, in the previous example, the API was sending back access tokens for a user. The way around this is to have the API filter out this data on the back end, either directly in the database query, if possible, or at the time of processing. 

Front End Based Prevention

However, what happens when you're using third-party APIs? Or what do you do in cases where you don't want to modify your back end? Let's assume your front end consumes data from GraphQL-based APIs. 

GraphQL gives your front end full control over what data it receives and processes. You can more responsibly update your GraphQL query to only request data that you need. You can also carefully craft your query such that you don't end up requesting sensitive data points that can be avoided. 

In case you're not using GraphQL for your backend APIs, you can ensure that your front end does all of the following: 

  • Doesn't leak sensitive data via browser storage (local storage and session storage) or cookies that can be easily spotted.

  • Doesn't store sensitive data in local variables or in data attributes of DOM elements that can be extracted via client-side JavaScript.

  • Ensures client and server interaction happens over only HTTPS, which encrypts data by default.

However, these are just some best practices you can adopt to add another layer of security to your front end. It doesn't necessarily protect sensitive data from being exposed, since the attacker can always see such information in the network tab of the browser. 

Practical Prevention of Excessive Data Exposure in Angular

We've seen a lot of theory, but let's put it into some practice. For this tutorial, we'll use an open GraphQL API called GraphQLZero. If you wish to explore this API, you can do so in the GraphQL playground here. You can generate the query for getting response back from the API and then update the query to see how the response changes. 

For now, let's first go ahead and create a new Angular app. 

Create a New Angular App

Inside a directory of your choice, run the following command to create a fresh Angular project: 

ng new angular-excessive-data-exposure-app

We won't need routing or any additional configuration, so feel free to skip that when prompted in the CLI. Once you do that, you should have a new Angular project created for you. Now, let's update its app.component.html file with the following code: 

<h1>Angular Excessive Data Exposure App</h1>

Now, let's kickstart the Angular local development server by running the following command inside the root directory: 

ng serve

If you now visit http:///localhost:4200, you should see the following page: 

Angular Excessive Data Exposure: Examples and Prevention
 image

Awesome! Let's move ahead.

Introducing a Case of Excessive Data Exposure

First, we'll create a case of excessive data exposure by requesting extra data from the API. Head over to the app.component.ts and add the following variables inside it: 

apiUrl='https://graphqlzero.almansi.me/api'
  query=`{
    user(id: 1) {
      id
      username
      email
      address {
        geo {
          lat
          lng
        }
      }
    }
  }`
  userData:any;

The apiUrl simply holds a string to the query endpoint. Then, we have a query string object that we'll use when we make a request to the GraphQL API. Finally, we have a userData variable to store the user data that we get back from the API as response. 

Now let's make the request to the endpoint. Inside the ngOnInit lifecycle method, add the following code:

 ngOnInit() {
    fetch(this.apiUrl, {
      "method": "POST",
      "headers": { "content-type": "application/json" },
      "body": JSON.stringify({
        query: this.query
      })
    }).then(res => res.json()).then((data)=>{
      this.userData=data.data.user
      console.log(this.userData)
    })
  }

We simply use the fetch API to make a request to the above GraphQL API. We also pass the query string inside the JSON body. Then we process the data and store the relevant result inside the userData variable. Makes sense? 

Now, we'll consume this data in our template. Head over to the app.component.html file and update it with the following code: 

<h1>Angular Excessive Data Exposure App</h1>

<p>username : <span>{{userData?.username}}</span></p>
<p>email : <span>{{userData?.email}}</span></p>
<p>location : <span>{{userData?.address?.geo?.lat}}</span>, <span>{{userData?.address?.geo?.lng}}</span></p>

Now go back to your app and you should see that data displayed on the page: 

Angular Excessive Data Exposure: Examples and Prevention
 image

Great! Looks like you did everything correctly, right? Well, not exactly. We're only using the user's username, email and location fields from the response in the UI. But let's inspect the entire request and response from the browser's network tab:

Angular Excessive Data Exposure: Examples and Prevention
 image

Notice that we also get back the user's ID. Imagine if this ID is an access or authentication token equivalent. It's a sensitive piece of information that's clearly not of any use here. Looks like we have an excessive data exposure vulnerability! 

How to Prevent Excessive Data Exposure

Remember when I said that with GraphQL, a front end has complete control over what data it requests and what information the API sends back in response? 

If you look closely at the query, we explicitly ask for the user's ID. If we remove it from the query, the API should not send that data back at all. So let's try to do that. Here's what the updated query string should look like: 

query=`{
    user(id: 1) {
      username
      email
      address {
        geo {
          lat
          lng
        }
      }
    }
  }`
Angular Excessive Data Exposure: Examples and Prevention
 image

We now no longer receive the id field back. Great! We have just prevented excessive data exposure by cautiously modifying the GraphQL query. 

Find and Fix Security Vulnerabilities

Conclusion

If you're not using GraphQL but instead using REST for your back-end APIs, your front end can't do a lot to protect your application from excessive data exposure. So always make sure your REST APIs are structured in such a way that they only send back the data needed. However, as wise front-end developers, you can prompt your back-end team to be more cautious about what data they're sending and play your own part in responsibly preventing excessive data exposure in your application. Until next time! 

This post was written by Siddhant Varma. Siddhant is a full stack JavaScript developer with expertise in frontend engineering. He’s worked with scaling multiple startups in India and has experience building products in the Ed-Tech and healthcare industries. Siddhant has a passion for teaching and a knack for writing. He's also taught programming to many graduates, helping them become better future developers.


StackHawk  |  May 15, 2022

Read More

Add AppSec to Your CircleCI Pipeline With the StackHawk Orb

Add AppSec to Your CircleCI Pipeline With the StackHawk Orb

Application Security is Broken. Here is How We Intend to Fix It.

Application Security is Broken. Here is How We Intend to Fix It.

Using StackHawk in GitLab Know Before You Go (Live)

Using StackHawk in GitLab Know Before You Go (Live)