Storing, Accessing, and displaying JSON data in local storage | Penetration Testing
In my latest post, I shared how I escalated a Critical misconfiguration in Firebase — Bug bounty, If you haven’t read it yet, go ahead and take a look!
I would love to connect on LinkedIn with you, if you haven’t, send me a request!
Introduction
In this article, I will talk about JSON from a developer perspective. I will talk about how to store, access, and display JSON data in Local Storage.
To begin with, let’s define JSON and Local Storage.
JSON (JavaScript Object Notation) is an open standard data interchange format used to communicate between applications. JSON is similar to XML but easier to read than XML due to its highly lightweight nature (small file size). JSON was derived from JavaScript — the programming language of the Web and the world’s most popular.
Local storage provides a mechanism for storing data persistently within the user’s browser. Unlike session storage, local storage retains data even after the browser is closed and reopened, making it suitable for applications that require long-term data storage.
Understanding these two concepts is a good foundation for cybersecurity students because they open the door to a handful of vulnerabilities:
JSON Vulnerabilities:
- JSON Injection: This vulnerability occurs when user-controllable data is directly embedded into JSON data structures without proper sanitization. Attackers can exploit this to manipulate JSON data or inject malicious code, leading to various security risks such as data manipulation, cross-site scripting (XSS), or remote code execution (RCE).
- JSONP (JSON with Padding) Hijacking: JSONP is a technique used for bypassing the same-origin policy to enable cross-domain communication. However, if not implemented securely, it can be vulnerable to JSONP hijacking, where an attacker can intercept and manipulate JSON responses, leading to data theft or unauthorized access to sensitive information.
- Denial of Service (DoS) through large JSON payloads: Attackers can exploit vulnerabilities in JSON parsers or poorly implemented JSON processing routines by sending excessively large JSON payloads, causing resource exhaustion or crashing the application, leading to denial of service.
Local Storage Vulnerabilities:
- Cross-Site Scripting (XSS): If user input stored in local storage is retrieved and displayed on web pages without proper sanitization, it can lead to XSS vulnerabilities. Attackers can inject malicious scripts into the local storage, which when retrieved and executed on other users’ browsers, can lead to session hijacking, data theft, or other malicious actions.
- Insecure Direct Object References (IDOR): Storing sensitive data in local storage without proper access controls can lead to IDOR vulnerabilities. Attackers may manipulate the data stored in local storage to access unauthorized resources or escalate privileges.
- Data Leakage: Storing sensitive information such as authentication tokens or user credentials in local storage without encryption or proper security measures can lead to data leakage vulnerabilities. Attackers with access to the local storage may extract this information and misuse it for unauthorized access or identity theft.
- Lack of Secure Communication: Local storage is susceptible to man-in-the-middle (MITM) attacks if data stored in it is transmitted over insecure channels. Attackers can intercept communication between the client and server, tamper with the data stored in local storage, or inject malicious content, compromising the integrity and confidentiality of the data.
However, in this blog post, I will not elaborate on how to exploit those vulnerabilities, rather I will explain how to play with JSON data, how to store, access, and display it in Local Storage. Please let me know in the comments if you are interested in learning about any of those vulnerabilities.
Storing JSON Data in Local Storage:
Let’s consider an example where we want to store user preferences using JSON data in local storage. Suppose we have the following JSON object representing the user profile with attributes such as name, age, and user role:
{
"profile": {
"name": "John Doe",
"age": 30,
"userRole": "admin"
}
}
You can use this JSON structure to store user profiles in local storage and access them within your web application. Here’s how you can store and access this data using JavaScript:
// Storing user profile in local storage
const userProfile = {
name: "John Doe",
age: 30,
userRole: "admin"
};
localStorage.setItem("userProfile", JSON.stringify(userProfile));
// Accessing user profile from local storage
const storedProfile = JSON.parse(localStorage.getItem("userProfile"));
console.log(storedProfile.name); // Output: John Doe
console.log(storedProfile.age); // Output: 30
console.log(storedProfile.userRole); // Output: admin
Accessing JSON Data from Local Storage:
Once the JSON data is stored in local storage, we can retrieve it and use it within our application. Here’s how we can access the stored user preferences:
const storedPreferences = JSON.parse(localStorage.getItem("userPreferences"));
console.log(storedPreferences.theme); // Output: dark
console.log(storedPreferences.fontSize); // Output: 16px
console.log(storedPreferences.language); // Output: en
Displaying JSON Data:
Now, let’s demonstrate how to display the stored JSON data in a web page. We’ll create a simple HTML structure to showcase the user preferences:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User Preferences</title>
</head>
<body>
<h1>User Preferences</h1>
<ul>
<li>Theme: <span id="theme"></span></li>
<li>Font Size: <span id="fontSize"></span></li>
<li>Language: <span id="language"></span></li>
</ul>
<script>
const storedPreferences = JSON.parse(localStorage.getItem("userPreferences"));
document.getElementById("theme").textContent = storedPreferences.theme;
document.getElementById("fontSize").textContent = storedPreferences.fontSize;
document.getElementById("language").textContent = storedPreferences.language;
</script>
</body>
</html>
Securing JSON Data Storage:
When storing sensitive information such as user profiles or application configurations using JSON data in local storage, it’s crucial to implement security best practices. One common pitfall is inadvertently exposing sensitive data to potential attackers. To mitigate this risk, developers should:
- Encrypt sensitive data: Before storing JSON objects containing sensitive information, such as passwords or personal details, ensure that the data is encrypted. Encryption adds an additional layer of protection, making it significantly more challenging for unauthorized parties to access the data even if they gain access to the storage.
- Implement access controls: Restrict access to stored JSON data by implementing access controls. Only authenticated users with the appropriate permissions should be allowed to access or modify the stored data. Role-based access control (RBAC) mechanisms can help enforce granular access permissions based on user roles and privileges.
- Sanitize input data: Prevent injection attacks by thoroughly validating and sanitizing input data before storing it in JSON format. Input validation helps mitigate risks associated with SQL injection, cross-site scripting (XSS), and other injection-based attacks, ensuring the integrity of the stored data.
Now, let’s see how these steps can be implemented through coding examples.
Encrypt Sensitive Data:
Before:
// JSON object containing sensitive data
const userData = {
username: "example_user",
password: "secretpassword",
email: "example@example.com"
};
// Storing JSON object in local storage without encryption
localStorage.setItem("userData", JSON.stringify(userData));
After:
// Encryption function (example: using AES encryption)
function encryptData(data) {
// Example encryption implementation
// Replace with actual encryption method
return AES.encrypt(data, 'encryptionKey').toString();
}
// JSON object containing sensitive data
const userData = {
username: "example_user",
password: encryptData("secretpassword"),
email: encryptData("example@example.com")
};
// Storing encrypted JSON object in local storage
localStorage.setItem("userData", JSON.stringify(userData));
Implement Access Controls:
Before:
// Retrieving stored JSON object from local storage
const storedUserData = JSON.parse(localStorage.getItem("userData"));
// Accessing sensitive data without proper access controls
console.log(storedUserData.username); // Output: example_user
console.log(storedUserData.password); // Output: secretpassword
console.log(storedUserData.email); // Output: example@example.com
After:
// Check if the user is authenticated before accessing sensitive data
if (user.isAuthenticated) {
// Retrieve stored JSON object from local storage
const storedUserData = JSON.parse(localStorage.getItem("userData"));
// Access sensitive data only if the user is authenticated
console.log(storedUserData.username); // Output: example_user
console.log(storedUserData.password); // Output: Encrypted value
console.log(storedUserData.email); // Output: Encrypted value
} else {
console.log("User is not authenticated.");
}
Sanitize Input Data:
Before:
// JSON object received from user input
const userInput = {
username: "<script>alert('XSS attack!');</script>",
password: "secretpassword",
email: "example@example.com"
};
// Storing JSON object in local storage without sanitization
localStorage.setItem("userInput", JSON.stringify(userInput));
After:
// Sanitize input data before storing it in JSON format
function sanitizeInput(input) {
// Example: Use htmlentities to escape HTML characters
return htmlentities(input);
}
// JSON object received from user input
const sanitizedUserInput = {
username: sanitizeInput(userInput.username),
password: userInput.password,
email: userInput.email
};
// Storing sanitized JSON object in local storage
localStorage.setItem("userInput", JSON.stringify(sanitizedUserInput));
API Penetration Testing and JSON Objects:
Last October I did an online course from APISec University and got certified:
Understanding JSON structures, client-storage and server-storage are essential to succeed in this course. I would like to briefly tell you about how JSON and API’s are related. The course from APISec taught me valuable lessons!
APIs (Application Programming Interfaces) and JSON (JavaScript Object Notation) files work together seamlessly to facilitate data exchange and communication between different systems in web application development.
API’s are literally the backbone of modern web applications. Conducting API penetration testing, with a focus on JSON objects, is essential for identifying and mitigating security risks.
This is how an API looks like on a website:
Here’s how JSON objects play a crucial role in API penetration testing:
- Input validation: During API penetration testing, JSON objects are commonly used to simulate different types of input data sent to API endpoints. By crafting malicious JSON payloads, penetration testers can assess the robustness of input validation mechanisms and identify potential injection vulnerabilities.
- Parameter manipulation: JSON objects allow penetration testers to manipulate parameters and payloads sent to API endpoints, enabling them to uncover weaknesses such as insecure direct object references (IDOR) or inadequate access controls. By altering JSON parameters, testers can assess the API’s resilience to parameter tampering attacks.
- Response analysis: JSON responses returned by API endpoints are scrutinized during penetration testing to identify potential information disclosure vulnerabilities. Testers analyze the structure and content of JSON responses to detect sensitive data exposure, inadequate error handling, or other security flaws that could be exploited by attackers.
In a different post, I will give practical examples of each of these vulnerabilities. Burp Suite is my favorite tool to test and search for JSON vulnerabilities.
Favorite source:
I would encourage you to read write ups of reported vulnerabilities at HackerOne or BugCrowd.
Let’s connect on LinkedIn! Let me know in the comments if you have any questions, I check them regurlarly and answer them as well!