Spring Excessive Data Exposure: Examples and Prevention

Spring Excessive Data Exposure: Examples and Prevention

An API is essentially a tool to provide an interface for the client with the software—that’s what they do.

Some of the API methods modify application state and some return data to the client. Further, some methods can do both. Once we return data to the client, we need to make sure that we return only what’s necessary and don’t expose any sensitive information.

This post will cover excessive data exposure in APIs with examples and prevention methods. The examples will be given in the context of the Java Spring framework.

REST API Structure

Usually, REST APIs follow a standard structure for the API calls. The structure usually consists of a domain name, a resource, a sub-resource, and a specific endpoint. For instance, a URL that looks like this— http://domain.com/artitsts/artist/albums/album1/song3—will allow a user to use different HTTP methods (GET, POST, PUT) to retrieve, update, and upload songs from a specific album for a specific artist.

Additional endpoints can be http://domain.com/artitsts/albums/album1, which will return a list of all the songs in an album, and http://domain.com/artitsts, which will return a list of items.

API Structure-Sniffing Vulnerability

The first vulnerability associated with this structure and excessive data exposure can occur if an attacker guesses or receives a list of endpoints.

If an endpoint that exposes sensitive data doesn’t require authentication, as explained here , the attacker can gain access to data he’s not authorized to view.

That said, the attacker can use brute force to identify API endpoints. This can be achieved by randomly trying to generate URLs that’ll return a response, or by using a list of popular paths to see if the server returns a response for them.

For instance, a popular REST API path is /users/info. Another one is /admin. So, the attacker will create a script that checks those paths combined with a domain name—http://domain.com/users/info, http://domain.com/admin—and see if any of them returns a response.

Another Way of Sniffing API Structure

The REST API standard includes a specification called HATEOS, which basically means that every API response should return a list of links to other API endpoints that can be relevant to this specific endpoint.

If the API developer just blindly returns a list of all the API endpoints in the system, or returns API endpoints that should be password protected but aren’t, he exposes data for attackers.

An example of a HATEOS response, taken from the relevant Wikipedia entry, is

HTTP/1.1 200 OK 
{ "account": 
{ "account_number": 12345, "balance": { "currency": "usd", "value": 100.00 }, 
"links": 
{ "deposits": "/accounts/12345/deposits", 
"withdrawals": "/accounts/12345/withdrawals", 
"transfers": "/accounts/12345/transfers", 
"close-requests": "/accounts/12345/close-requests" } 
} 
}

API Endpoint Sniffing

Another way for the attacker to gain access to sensitive information doesn’t even require any extra effort of sniffing for undocumented API methods.

If the API endpoint returns more info than required and relies on the fronted developers to filter the extra data, that basically means that for an endpoint like this—http://domain.com/users/user1—that should return some basic details like username, email, and last login date, and the server returns additional data like a full name and address.

The server relies on the front-end developers to filter out the unwanted information and present in the browser/app only the basic details that should appear there. However, the attacker can use the browser’s developer tools or do an API request with an external tool (like postman) and see the full data that the server returns. So, where a regular user will see something like this

HTTP/1.1 200 OK { "user:
{ "username": "john doe", "email":"johndoe@gmail.com" }
{

the attacker will see the full output:

HTTP/1.1 200 OK { "user:
{ "username": "john doe", "email":"johndoe@gmail.com",
"name: John Doe Smith", "address": "Smith's road 1, NY, NY" }
{

Protecting Against Excessive Data Exposure

What makes data sensitive and what manifests excessive data exposure is highly context-based. What constitutes excessive data in one API is a perfectly reasonable response from a different API.

Thus, it means that automated tools usually can’t help you with identifying and mitigating this vulnerability. It’s up to the developer to harden the API to protect against this vulnerability.

Vulnerability Mitigation

First, I’ll provide some general guidelines for mitigating this vulnerability. After that, I’ll provide some Java Spring-specific examples.

1. Never Rely on the Front End to Sanitize Data

The back-end developers that implement the API should be the ones that return only nonsensitive data. You shouldn’t rely on the front end to filter out that data.

Even if front-end developers properly filter out the unwanted data, as seen above, an attacker can access the whole response by accessing the API independently.

I’ll provide an example of how to avoid returning excessive data in an API response in Java Spring in the next section.

2. Protect API Endpoints That Require Authentication and Authorization

As I’ve described , you should protect with authentication and authorization each API endpoint that should return sensitive data.

3. Don’t Expose All API Endpoints Via HATEOS

If you implement HATEOS as part of your REST API, don’t return the whole list of API methods. Hence, return only a list of those methods that are relevant for the specific endpoint.

Spring Boot

The Spring framework is a superb Java framework for creating web applications and enterprise applications.

In 2005, Pivotal developed the Spring framework, and it’s still very popular today. Ever since Pivotal developed the Spring framework, they’ve added various modules to the core Spring container.

Spring Boot is one of the most commonly used ones, representing the convention over configuration part of the Spring framework. Spring Boot lets you code with very minimal configuration.

Mitigating Excessive Data Exposure Vulnerability in Spring Boot

Let’s return to the API example of a user endpoint discussed earlier:

HTTP/1.1 200 OK { "user: { "username": "john doe", "email":"johndoe@gmail.com", "name: John Doe Smith", "address": "Smith's road 1, NY, NY" } {

We can represent it in Spring Boot using the following class:

public class User {
private String username;
private String email;
private String fullName;
private String address;
}

As I mentioned earlier, we want the API to respond only with the username and email. To do this, we can add the@JsonIgnore
property to the fields we want to exclude in the API response:public class User {
private String username;
private String email;
@JsonIgnore
private String fullName;
@JsonIgnore
private String address;
}

This prevents the fullName and address from appearing in the response.

Blog Banner - Automate API Security Testing in CI/CD

Conclusion

APIs are the backbone of many applications and websites. They provide critical services to clients.

Excessive data exposure vulnerability is a serious vulnerability that can pose a security risk to an organization. In this post, I’ve shown the way that this vulnerability is exploited and different attack vectors.

Likewise, I’ve added some standard ways to mitigate it, with a specific example for Java Spring Boot. Founded in 2005, this is a very popular framework for creating Java back-end applications, and it’s still one of the most popular frameworks in the Java world.

Don’t rely on the front end to filter out sensitive data; instead, manually go through your endpoints and make sure that you return only the necessary data.

In addition, avoid providing links for all the methods in the API, unless you’re building an API documentation and, in general, harden your API as much as possible.

This post was written by Alexander Fridman. Alexander is a veteran in the software industry with over 11 years of experience. He worked his way up the corporate ladder and has held the positions of Senior Software Developer, Team Leader, Software Architect, and CTO. Alexander is experienced in frontend development and DevOps, but he specializes in backend development.

Spring Excessive Data Exposure: Examples and Prevention

Laravel Excessive Data Exposure: Examples and Prevention

Laravel Excessive Data Exposure: Examples and Prevention - Picture 1

Excessive data exposure is when an API responds to a request with more data than required. Superficially, it looks like a design flaw. In reality, OWASP Lists this problem as one of the top three API Security threats. If an attacker discovers a method that returns the right fields, they can use an unprivileged account to retrieve the data. As a result, these vulnerabilities can lead to serious data compromises, including leaking user data and creating legal liabilities.

This post will look at the nature of excessive data exposure and how you can protect yourself in Laravel applications.

What Is Excessive Data Exposure?

Many mobile and web apps request API data, receive a superset of the fields they need and filter the results based on what they want to display. So, the application design implicitly relies on the server returning all of its data for a given entity.

For example, consider a typical e-commerce website. It stores client information, including names, emails, and addresses. Here’s an example API request for user Id #5 and the response.

GET http://localhost:8000/api/user/5

{
  "id": 5,
  "name": "Joe Customer",
  "email": "joe@example.com",
  "email_verified_at": null,
  "address": "23 Not Taken Rd.",
  "state": "Confusion",
  "zip": 22222,
  "phone": "(123)444-183",
  "created_at": "2022-03-13T20:19:11.000000Z",
  "updated_at": "2022-03-13T20:19:11.000000Z",
  "api_token": null,
  "password": "$2y$10$9kA9PSPPQhZ2jXpZgImZe.Ul6vCKuu8EB5xLsD6WCVKJiI9BQv6aO",
  "remember_token": null
}

This request for user Id #5 returns all of the available fields for the user, including the hashed password and an API token, two fields that no display application should even need.

The architecture behind this application expects the display to use the fields it needs and discard the rest. But filtering data in display apps doesn’t mean it’s not visible. Any application with access to the API can retrieve this excess data, too. So, an attacker with a compromised password or even a spoofed account that has access to user records can retrieve all their information.

Protecting Laravel Applications From Excessive Data Exposure

In the example above, we retrieved information for a user by Id. This idiom is typical in “CRUD” APIs, where applications request the data they need and display the relevant fields based on context.

The response came from a Laravel server. Unfortunately, getting the application to return the excess data didn’t require any extra effort. Quite the opposite: the code was from a Laravel RESTful API tutorial.

A Simple RESTful API

Laravel makes it easy to connect a web application to a database.

Most web frameworks advertise this as a feature, and they’re right. Instead of writing boilerplate database access code, the framework generates it for you, and you can get to work on your business logic. Laravel does this with its Eloquent ORM. But, from a security standpoint, you might say that its design is optimistic.

The sample code used above has a user object with basic fields for user name, email, address, and basic authentication.

Here’s the SQL table that stores the users:

create table users
(
	id bigint unsigned auto_increment
		primary key,
	name varchar(255) not null,
	email varchar(255) not null,
	email_verified_at timestamp null,
	address varchar(255) null,
	state varchar(64) null,
	zip int null,
	phone varchar(255) null,
	created_at timestamp null,
	updated_at timestamp null,
	api_token varchar(60) null,
	password varchar(255) not null,
	remember_token varchar(100) null,
	constraint users_api_token_unique
		unique (api_token),
	constraint users_email_unique
		unique (email)
)
collate=utf8mb4_unicode_ci;

When we give Laravel an empty model class, it figures out how to add, update, retrieve, and delete users from this table for us.

So, here’s the model:

class User extends Model
{
}

And here’s the controller (with the authentication code removed:)

<?php

namespace AppHttpControllers;

use IlluminateHttpRequest;
use AppModelsUser;
use IlluminateSupportFacadesConfig;
use IlluminateSupportFacadesLog;

class UserController extends Controller
{

    public function index()
    {
        return User::all();
    }

    public function show(Request $request, $id)
    {
        return User::find($id);
    }

    public function store(Request $request)
    {
        $user = User::create($request->all());
        return response()->json($user, 201);
    }

    public function update(Request $request, $id)
    {
            $user = User::findOrFail($id);
            $user->update($request->all());
            return response()->json($user, 200);
    }

    public function delete(Request $request, $id)
    {
            $user = User::findOrFail($id);
            $user->delete();
            return response()->json(null, 204);
    }
}

This code needs a few routes (that we don’t need to see here), and we have a working API.

But as we saw above, the default behavior is to return all of the fields in the model. This is true for any model that uses the default code.

The good news is that there are a few ways to make this code more secure.

Move Your Fields to a Different Table

If your application uses a SQL database, you might consider moving the fields related to authentication to a different table and giving them their own model. Separating concerns this way makes sense from both an architectural and maintenance standpoint. It’ll be easier to update your authentication model in the future and often makes your code easier to read.

But if you’re using a NoSQL database or have inherited a “mature” codebase, this might not be possible.

Laravel Excessive Data Exposure: Examples and Prevention - Picture 2

Filter Your Fields From JSON

The default model code is generating a SQL query that looks something like this:

select * from users where id=5

If we were writing the application by hand, we would probably consider rewriting the query to only select the fields we need. We could take that approach now and modify the model to use a similar query.

But, that would create some new problems. While the display applications should never see hashed passwords, the authentication system needs them. As soon as we started crippling the model, we created the need for multiple interfaces or even a second model for the back end. As a result, we’d only add a new set of maintenance issues.

Laravel addresses this problem by making it possible to retrieve all the data from the data store while hiding the excess data from JSON. As a result, it’s easy to prevent API clients from seeing certain fields while still making them accessible to backend model users. You do this by adding a $hidden field to the model class.

Let’s hide the password field:

class User extends Model
{
protected $hidden = ['password'];
}

Now, we rerun the query for user #5:

GET http://localhost:8000/api/user/5

{
  "id": 5,
  "name": "Joe Customer",
  "email": "joe@example.com",
  "email_verified_at": null,
  "address": "23 Not Taken Rd.",
  "state": "Confusion",
  "zip": 22222,
  "phone": "(123)444-183",
  "created_at": "2022-03-13T20:19:11.000000Z",
  "updated_at": "2022-03-13T20:19:11.000000Z",
  "api_token": null,
  "remember_token": null
}

Laravel omitted the password field from the response.

The $hidden field is an array, so you can use it to filter out all of the unwanted data.

class User extends Model
{
protected $hidden = ['password', 'created_at', 'updated_at', 'api_token', 'remember_token', 'email_verified_at' ];
}

Now we have a simple mechanism for ensuring the no display application sees critical backend data:

GET http://localhost:8000/api/user/5

{
  "id": 5,
  "name": "Joe Customer",
  "email": "joe@example.com",
  "address": "23 Not Taken Rd.",
  "state": "Confusion",
  "zip": 22222,
  "phone": "(123)444-183"
}

That Which Is Not Explicitly Permitted Is Denied

The $hidden field hides fields by name. It’s a powerful tool, but it might not be enough. Web code moves fast, and you may inadvertently add a new field to your model and forget to hide it.

A safer security model is to define a set of fields that are allowed and only pass them to API users.

The $visible field defines the fields that are available to JSON. Laravel will not provide fields missing from this array to API requests.

Let’s list name and email as the only visible fields:

class User extends Model
{
protected $visible = ['name', 'email'];
}

Then run a query.

GET http://localhost:8000/api/user/5
{
"name": "Joe Customer",
"email": "joe@example.com"
}

That’s nice and clean!

So, we have two robust mechanisms for filtering backend information from display clients and potential hackers. Depending on how you want to address the problem, you can either list the fields that are visible or hidden.

Blog Banner - Find and Fix Security Vulnerabilities Banner

Filter Laravel Fields to Avoid Excess Data Exposure

We’ve looked at the problem of excess data exposure and how it can compromise your application’s security. Laravel’s robust model-viewer-controller features make it easy to put a RESTful API together, with a small amount of code. But, its behavior isn’t always what you want or need. We saw how the default model provides all available data to requestors. Then we looked at the tools Eloquent provides to make filtering fields from API request easy.

So, you have the tools you need to address Excess Data Exposure in your Laravel code. It’s time to take the next step: StackHawk has the tools you need to keep your code and your clients safe. Sign up for a free account and see how!

This post was written by Eric Goebelbecker. Eric has worked in the financial markets in New York City for 25 years, developing infrastructure for market data and financial information exchange (FIX) protocol networks. He loves to talk about what makes teams effective (or not so effective!).

Spring Excessive Data Exposure: Examples and Prevention

Rust Broken Authentication Guide: Examples and Prevention

Rust is a fast and reliable language that supports asynchronous, and it is quickly becoming the premier choice for performance-focused network and web applications. Authentication is the process of verifying the identity of a user, and it’s an integral part of software development. For example, people trying to get access to the system must prove that they’re legitimate users. This way, unauthorized users won’t get access to the system.

For a language with high performance like Rust, what happens when authentication is broken? This means that cybercriminals can impersonate a legitimate user to cause havoc to the system. When this happens, the system is vulnerable to attacks. In this article, we will explore broken authentication, the different types, and how to avoid them in Rust applications.

What Is Authentication?

Authentication recognizes and verifies the identity of a user, and it happens at the start of the application. The user provides their credentials, which the system can compare with what’s in the database. For example, the credentials are usually a match of the user’s username and password. If the credentials don’t match that of the database, the user won’t get access to the system. This is because the system will consider them an illegitimate user.

While there are different means of authentication for different systems, users must provide a means of identification. For example, the credential must not be a password or an email address. User authentication is in three categories: The system will authenticate the user according to who they are, what they know, and what they have.

What Is Broken Authentication?

Applications are prone to vulnerabilities that can cause a security breach. Broken authentication is one such vulnerability.

According to OWASP (Open Web Application Security Project), broken authentication is the second on the list of critical vulnerabilities.

Broken authentication consists of vulnerabilities that cybercriminals can exploit to impersonate legitimate users. Sometimes, these vulnerabilities can be a result of developer error or from APIs (application programming interfaces) in the application. For example, if the application uses an API with a security breach, it could inherit them. Also, if an application uses a library that’s vulnerable to authentication, it can cause a security breach.

Broken Authentication Types

There are different types of broken authentication vulnerabilities. In this section, we’ll explore the different ways authentication can be porous and cause a vulnerability.

A person holds their hands in front of them, crossing their index fingers to form an X gesture—a visual cue for blocking threats like API Attack Surface Discovery; the face is out of focus in the background.

Predictable Login Credentials

Sometimes, users choose credentials that are easily predictable. For instance, passwords like “Admin” or “Password1” can be easily predictable for cybercriminals. A downside to this is that attackers can easily get hold of the user’s account.

For example, criminals can apply brute force attacks until they can get access to the account of the user. A brute force attack isn’t the only way attackers can get into a user’s account. If the user permits a weak credential recovery process, the attacker can intercept the credential.

Sensitive Data Exposure

While software development firms try as much as possible to protect user data, sensitive data is vulnerable to exposure in many ways. For example, user login information can get exposed before they get to the database. Also, during password recovery when users forget their credentials, they could get exposed.

Sometimes, encryption doesn’t protect user data from exposure. This is because attackers can decrypt data that has been poorly encrypted. For instance, research shows a vulnerability in version 1.0 that can allow attackers to decrypt data passing between a web server and the user.

Session Hijacking

Session hijacking is a term that describes when an attacker successfully takes over a legitimate user’s account. With this move, the system thinks the attacker is the legitimate user and they get access to all user information.

Session hijacking happens when attackers compromise session tokens. These session tokens are unique strings of data that only the server and browser know about. This is for network communication, where the server trusts a session token from a browser and allows the user access. In session hijacking, the attacker can take over the user’s session after the legitimate user has logged in. Session hijacking is different from session fixation. The former hijacks a user session after the user logs in, while the latter launches an attack before the user logs in.

Rainbow Attacks

Rainbow attacks are a series of attacks that target an application’s database. When attackers target the database, they can get user credentials and let themselves into the user’s account. A rainbow table is a table of reversed hashes that attackers can use to collect password hashes and decode them.

Vertical brushstrokes of yellow, orange, red, green, blue, and purple blend together on the left side—evoking the layered approach of Dynamic Application Security Testing (DAST)—before fading into a white background on the right.

Session ID Vulnerability

Session ID vulnerabilities exploit the fact that some systems allow attackers to get a valid session ID and then manipulate users to authenticate themselves with the session ID.

How to Avoid Broken Authentication in Rust

We’ve explored the different broken authentication types in Rust applications. In this section, we’ll discuss how to avoid them.

Encrypt Password and Add Salt to Hashes

Credential encryption can go a long way in protecting user data from exposure. For instance, if an attacker gets hold of a user’s credentials, they’ll have to decrypt it to a human-readable string. In Rust, developers can use libraries like rust-fnv to hash user credentials. Here’s an example of how to use this Rust library in a hashtable or HashSet:

// Hashtable
use fnv::FnvHashMap;

let mut map = FnvHashMap::default();
map.insert(1, "one");
map.insert(2, "two");

map = FnvHashMap::with_capacity_and_hasher(10, Default::default());
map.insert(1, "one");
map.insert(2, "two");

// Hashset
use fnv::FnvHashSet;

let mut set = FnvHashSet::default();
set.insert(1);
set.insert(2);

set = FnvHashSet::with_capacity_and_hasher(10, Default::default());
set.insert(1);
set.insert(2);

What this does is use the FnvHashMap and FnvHashSetwhich to store a hash of credentials in a HashMap or HashSet. Sometimes, firms only want to hash the user’s password. For this, they can use Rust’s bcrypt library. An advantage of using this library is the addition of salt to hashes. Here’s how to use the bcrypt library:

extern crate bcrypt;
use bcrypt::{DEFAULT_COST, hash, verify};
let hashed = hash("hunter2", DEFAULT_COST)?;
let valid = verify("hunter2", &hashed)?;

Use Passwordless Authentication and Session Invalidation

To avoid credential exposure, many firms are using passwordless authentication. In Rust, users can incorporate this with the Auth0 passwordless feature. This feature allows you to authenticate a user by sending a magic link or code to them. This magic link/code can be sent to the user’s email address or phone number.

However, what happens when attackers launch a series of attacks to hijack the user’s session? This is where session invalidation comes in.

Session invalidation clears authentication objects and marks them as invalid.

For example, when an attacker tries to use the account, they’ll be logged out because the session is invalid. To do this, developers can incorporate either of the methods below:

HttpSession.invalidate()
session.inValidate()

Session Time-Outs

Developers can stop session hijacking, session fixation, and other attacks that can result from vulnerable session IDs by incorporating session time-outs. A session time-out is the time window when the user is inactive. When a user logs in to their account and stays inactive for a long time, attackers can steal user credentials or even hijack their session. What session time-outs do is lay out a time where the user will be logged out if they remain inactive.

In Rust, most libraries have the time-out traits for their sessions. For instance, in Rust’s yubihsm crate, developers can use the time-out struct in the session module. This allows them to create a new time-out by setting the duration of the time-out.

Blog Banner - Find and Fix Application Security Vulnerabilities with Automated Testing

Conclusion

Rust is an amazing language when it comes to security. For example, the compiler gives out errors like type errors when the developer makes a wrong choice. However, what happens when there’s no compile-time error but users are making an error that’ll cause a security vulnerability? This is where monitoring tools like StackHawk come into play. For instance, they can capture unsafe code that might lead to broken authentication. With StackHawk, you can also test APIs and third-party libraries in your application for security.

This post was written by Ukpai Ugochi. Ukpai is a full-stack JavaScript developer (MEVN), and she contributes to FOSS in her free time. She loves to share knowledge about her transition from marine engineering to software development to encourage people who love software development and don’t know where to begin.

Spring Excessive Data Exposure: Examples and Prevention

Vue XML External Entities (XXE) Guide: Examples and Prevention

In this article, we’ll address the subject of Vue XML external entities injection. Our goal is to offer you a solid foundation to understand and mitigate XML external entity injection vulnerabilities in Vue and NodeJS. Additionally, we want to help you prepare to implement solutions in your projects.

It’s important to note that we’ll be providing mitigation strategies for NodeJS since the bulk of vulnerabilities lie in the back end of applications.

We’ll first explain what XML is. Then, we’ll give you some basic examples of XML external entity injection vulnerabilities and exploits. Finally, we’ll provide you with strategies and mechanisms to prevent this exploit from affecting your application.

It goes without saying, but this article might not be for you if you don’t have any experience with Vue. If you just want to know what XML external entity injections are, we recommend you go to our in-depth article about it here. Additionally, if you just want to learn about the basics of Vue, you might want to spend some time here .

Explaining XML

XML (extensible markup language) is a markup language for storing, transmitting, and reconstructing data. This language defines rules for encoding documents in both human-readable and machine-readable formats.

But wait—why does a markup language represent a threat to your systems?

The truth is that we make use of this language everywhere to process data in a convenient and human-readable way. Additionally, most XML processing tools in use allow for the specification of what is known as an external entity.

This entity, commonly a URI, is retrieved and processed during the parsing of the XML file. This prompts the parser to request and include the content inside the XML document. And, as you might’ve guessed, this is a window into trouble.

XML external entity injections, also known as XXE injections, are attacks that target XML parsing vulnerabilities. And, given that most systems that use XML parsing functionalities that face the user are potentially vulnerable, they can allow a bad actor to access files and resources on the server.

Given that a determined bad actor could use this entity as an avenue to retrieve any resource in the server, this vulnerability could be devastating for our security. All that’s needed is a sufficient understanding of server structures and information about the technology stack in use.

Examples of XML External Entity Injection Vulnerabilities

The biggest threat offered by XXE injection is its simplicity.

Most developers won’t be able to spot the dangerous code. Many won’t even see danger at all, even when it’s right in front of them.

So, to prevent that, let’s see some common examples.

This XML document contains just one username element.

<?xml version="1.0" encoding="ISO-8859-1"?>
<username>Michael</username>
</xml>

Nothing scary here, right? Well, we haven’t added any external entity yet.

OK, how do we add an external entity?

Simple. External entities are simple XML tags that use a system identifier within a DOCTYPE header.

This header works by adding more properties to the XML file structure itself. This would be, for example, a URL referencing another XML file containing additional data—nothing complex.

But what if we take advantage of this feature to retrieve something we shouldn’t? For example, the following code containing an external XML entity fetches the content of /privates.txt and displays it.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///privates.txt" >]>
<username>&xxe;</username>
</xml>

Yikes.

It’s painfully clear that this is a potentially catastrophic vulnerability since these entities can access local or remote content within our server.

This is particularly awful if you make the mistake of keeping sensitive files on your server. Essentially, this would eventually provide a path to a hostile takeover of your whole platform.

Incidentally, XML external entity injection attacks can also access local resources that may return data in a loop, impacting application availability and leading to a kind of denial of service attack.

Now, if you’re paying attention, this is when you should be freaking out and start advocating for disabling XML file processing altogether.

But don’t be so hasty. There are still steps that we can take to mitigate this vulnerability.

Mitigating XML External Entity Injection Vulnerabilities

Now that you’ve calmed yourself a little bit, let’s explore how to prevent your systems from falling victim to these attacks so you can keep your job.

First and foremost, mitigating XXE injection attacks is actually quite simple—sorry for the fearmongering.

Assuming that you need the functionality for loading user-provided XML files, as long as you’re not deliberately attempting to open a back door for exploits, most libraries do a decent job protecting your application.

The general approach to prevent this exploit is not to use libraries that support entity replacement like LibXML. And, if you have to, disable the feature altogether.

Working on the Code

Now, this mainly concerns the back end of your application. In our case, this is NodeJS, but if you’re parsing XML in the front end for any specific purpose, avoid using libraries that support entity replacement.

As we’ve mentioned in our NodeJS article about the subject, “Sadly, NodeJS does not have a built-in XML parsing engine, so, likely, you might already be using this library in your project. But no fret; entity replacement is disabled by default.”

Nevertheless, we recommend that you explicitly disable this feature in your project.

You can do this by simply changing all initializations of the library like so.

const lib = libxmljs.parseXml(xml, {noent: true});

Luckily, the latest versions of LibXML make it tough to allow entity replacement on purpose. Nevertheless, we want you to know that regardless of your approach, you may still be vulnerable to a DoS attack when using LibXML in this way.

Now, if you absolutely have to have this feature, you can still minimize the potential for exploits by safe-listing the external entities you allow.

app.post('/load_xml', upload.single('xml'), async function (req, res) { 
	if (!req.file) { 
		res.sendStatus(500); return; 
	} 
	
	try { 
		const xml = req.file.buffer; const doc = libxmljs.parseXml(xml, {noent: true}); 
		
		if (doc.text().includes("<!ENTITY")) { 
			throw new Error("INVALID XML FILE"); 
		} 
		
		res.send(doc.text()); 
	} catch (err) { 
		res.send(err.toString()); res.sendStatus(500); 
	} 
});

By simply checking the XML document before parsing it with our library for any strings containing any “ENTITY” not in our list, we can provide a minimum level of security to our application.

Surefire Solution

The last thing I want to leave you with is that the best approach to security is not to have a door open in the first place.

Do not parse XML unless it’s an application requirement. Despite the convenience that it might offer, there are numerous ways to provide equivalent functionalities without opening yourself to these vulnerabilities.

Blog Banner - Ready to Test Your App

What’s Next?

It should go without saying that protecting our platforms against the exploits of bad actors requires an expansive knowledge of the technology and infrastructure in use.

Nevertheless, if you’re in charge of a highly productive team with many responsibilities and pressure on your hands, it’s essential to do your best to offer them the tools and mechanisms to perform their best. That’s not an easy task.

Luckily, we’ve developed the ideal solution for you.

Our dynamic application security testing solution is a fantastic and powerful solution that empowers teams focused on delivering the best solutions on the web while protecting your users.

You can check it out here .

This post was written by Juan Reyes. Juan is an engineer by profession and a dreamer by heart who crossed the seas to reach Japan following the promise of opportunity and challenge. While trying to find himself and build a meaningful life in the east, Juan borrows wisdom from his experiences as an entrepreneur, artist, hustler, father figure, husband, and friend to start writing about passion, meaning, self-development, leadership, relationships, and mental health. His many years of struggle and self-discovery have inspired him and drive to embark on a journey for wisdom.

Spring Excessive Data Exposure: Examples and Prevention

Spring Broken Object Level Authorization Guide: Examples and Prevention

Spring Broken Object Level Authorization Guide: Examples and Prevention - Picture 1

If a malicious user gains access to functionality that only system administrators should have access to, there can be dire consequences. This post is about a specific type of vulnerability called broken object level authorization, or BOLA. This happens when an attacker gains access to API methods that should be restricted. In addition to talking about what this is, I’ll discuss ways to mitigate this attack in general, and specifically in Java Spring Boot .

Broken Object Level Authorization Defined

Back-end APIs are basically a set of functions that return answers to requests. For instance, if we run an e-commerce shop, API will handle many functions. Some examples include getting the product description, getting the product inventory, setting the product price, adding the product to the shopping cart, checking out, and sending an invoice, among other things. Some of those actions should be accessible to every user who reaches the store, whether it’s an application or a website. For example, all users should be able to get product details, get product category details, and view the shipping policy page.

On the other hand, other actions should be strictly performed by specific users only. For instance, shop administrators should be the only ones who can update product inventory or set a product price. Only specific store shoppers should be able to add a specific product to the cart and check out with their order.

If the store developers don’t enforce proper permissions on those actions, serious consequences can occur.

For example, a malicious actor will be able to add products to a cart in the name of an existing client. Or they can change the shipping address and pay for them with the existing client’s payment method. Moreover, if the malicious user successfully accesses functionality that only the store’s administrator should be able to manage, the consequences might be much worse. We call this vulnerability broken object level authorization.

Technical Specifics of a Broken Object Level Authorization Vulnerability

As described above, broken object level authorization is basically a vulnerability that allows an attacker access to restricted data or functionality. Now let’s see how it happens in detail. Usually, APIs use URLs of the following structure to access specific resources of items: http://domain.com/api/version/resource/sub-resource/id. In addition, the ID of the resource can appear in the header of the request or in the body instead of the URL. In any case, to access a certain resource, each user generally needs to undergo two steps: authentication and authorization.

Authentication

Authentication basically means logging in. The system receives a combination of a username and password or an API access token and then validates those credentials against the data that it stores. If users enter the correct credentials, they can log in and do API requests.

Authorization

However, authentication is not the full story here. It’s just the first step. Being authenticated just means that the API “knows who you are.” It doesn’t mean that you can actually do requests to API endpoints. This stage is authorization. Each user can have different privileges grouped into a “role,” and each endpoint can have granular permissions. For instance, an endpoint that accesses a product page will allow all users to view the data, but only the store admin can edit anything. Basically, there should be a check for each API call if the user who has issued it has access to the endpoint and has permission to do the specific action.

Implementing Authorization

A developer can implement authorization in different ways. For instance, we can send the API_token with each request. The API code will check the API_token against the action the user wants to perform and the token’s permissions list. Alternatively, we can store the permissions in an encrypted way on the client side. Then it can be sent over to the server with each request.

Breaking Into the API

The specifics of how an attacker can break into an API are application specific .

The general idea, as stated above, is to gain privileges to restricted data or actions. Hijacking the API_TOKEN can be easily done if the API token is sent as part of the URL request: http://domain.com/api/version/resource/sub-resource/id?api_token=randomApiToken1422345. Alternatively, an attacker can do it by copying an encrypted JSON web token from a client machine. However, in most cases, this is just human error when API developers don’t properly check the permissions on their end.

Spring Boot

The Spring framework is a superb Java framework for creating web applications and enterprise applications. In 2005, Pivotal developed the Spring framework, and it’s still very popular today. Ever since Pivotal developed the Spring framework, they have added various modules to the core Spring container. Spring Boot is one of the most commonly used ones, and it is the convention over configuration (CoC) part of the Spring framework. Spring Boot lets you code with very minimal configuration.

Mitigating Broken Object Level Authorization Vulnerability

I’ll first discuss how to mitigate this vulnerability in general and then dive into Spring Boot specifics. To mitigate this vulnerability, API developers should first and foremost put authentication and authorization code in place. Without those, any API endpoint is compromised. In addition, proper test cases should cover those mechanisms via unit tests, component tests, and integration tests. Tests should cover at least the most popular and business-critical endpoints. In addition, the tests should cover different use cases. For instance, let’s say that a user has entered the wrong credentials. The expected behavior is that no API endpoint can be accessed. The user tries to access an endpoint that they don’t have access to. The expected behavior is that access will be denied.

Spring Broken Object Level Authorization Guide: Examples and Prevention - Picture 2

Additional Actions

Verify that each user has specific permissions. If you are deploying a more robust user management system that includes user roles, then make sure that a role hierarchy is in place. For example, an administrator can do all guest actions but not vice versa. Likewise, to prevent request forgeries, don’t use an API token as a query param, as in this example: http://domain.com/api/version/resource/sub-resource/id?api_token=randomApiToken1422345. Require API users to refresh their credentials periodically. Don’t store permission information in an unencrypted browser cookie on the client’s side.

Mitigating Broken Object Level Authorization Vulnerability in Spring Boot

Luckily, Spring Boot has Spring Security. This is a robust and built-in way to handle authentication and authorization, thus preventing this vulnerability. Since Spring Security is very robust and has lots of configuration options, we can’t cover all of it here. However, it is sufficient to point out that it provides you with BOLA mitigation out of the box. We can use this snippet:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

This enables Spring Security in our application automatically. This configuration protects our endpoints by default. And we need to manually set permissions for each endpoint to make it accessible to users. This is a good starting point for developing any new API in Spring Boot. Having said that, users have to take into account that Spring Security can have a steep learning curve. It can also be overkill for their needs. If you are building a small API, then developing authentication and authorization from scratch can be the right way to go.

Blog Banner - Find and Fix Application Security Vulnerabilities with Automated Testing

Conclusion

BOLA is a serious vulnerability. An attacker can get access to restricted information or functionality. OWASP considers it to be the #1 API vulnerability. Broken object level authorization usually occurs due to human error in API implementation. However, despite its serious impact, its mitigation is straightforward (at least strategy wise) through proper authentication and authorization. Spring comes with a module that handles those out of the box, which, in turn, can make mitigating this vulnerability easier for Spring Boot users.

This post was written by Alexander Fridman. Alexander is a veteran in the software industry with over 11 years of experience. He worked his way up the corporate ladder and has held the positions of Senior Software Developer, Team Leader, Software Architect, and CTO. Alexander is experienced in frontend development and DevOps, but he specializes in backend development.