Security Audit: JSONPlaceholder
https://jsonplaceholder.typicode.comAbout This API
JSONPlaceholder is a public read-only REST API commonly used for prototyping and testing front-end applications. It simulates a backend resource store with endpoints for posts, comments, users, and albums. The service is unauthenticated and exposes endpoints that accept DELETE, PUT, and PATCH methods despite being documented as read-only. Typical consumers include developers building client apps, educational projects, and integration prototypes.
The API handles no sensitive user data but exposes predictable resource identifiers and reflects origin headers in CORS responses. Because it is widely referenced in tutorials and used as a default backend for sample applications, misconfigurations here can normalize insecure patterns. The API does not enforce authentication on any HTTP method and lacks resource-level authorization, enabling IDOR where attackers enumerate sequential IDs to access adjacent resources. CORS misconfiguration allows arbitrary origins to include credentials, which can facilitate cross-site request forgery or data leakage in browser-based clients.
As a public endpoint, JSONPlaceholder is indexed and scraped, increasing exposure surface for reconnaissance. The absence of API versioning and the exposure of the framework via X-Powered-By headers provide attackers with implementation details useful for targeted follow-up. While the data is synthetic, the structural weaknesses—missing authentication, weak authorization, and unsafe CORS—are representative of misconfigurations seen in production APIs, particularly in early-stage or demo services.
These findings align with OWASP API Top 10 categories including authentication, authorization, input validation, and CORS misconfiguration. Addressing these issues reduces the risk of unintended data access, privilege escalation, and abuse in dependent applications. Operators should treat JSONPlaceholder as a baseline reference and implement layered controls when promoting similar patterns to production services.
Threat Model
Attackers interested in public APIs like JSONPlaceholder typically fall into opportunistic scrapers, account takeover rings, and competitive intelligence collectors. Since JSONPlaceholder exposes no sensitive user data, the primary asset at risk is not data confidentiality but the integrity and availability of the simulated resource store, as well as the potential for these weaknesses to be normalized in downstream applications. An attacker may leverage IDOR to map accessible resources, probe dangerous methods to modify or delete data, and exploit CORS to perform authenticated actions on behalf of browser-based users.
Unauthenticated Access and Lack of Authorization
The absence of authentication on any HTTP method means no identity context is established. Without middleware enforcing authentication and property-level authorization, attackers can issue requests directly to resource endpoints. This enables enumeration of IDs and direct manipulation of resources that should be isolated between users or roles.
Insecure Direct Object Reference (IDOR)
Sequential numeric IDs allow attackers to guess valid resources by incrementing identifiers. With confirmed IDOR via incrementing IDs, an attacker can traverse the object space to discover accessible posts, comments, or users. The risk is amplified when applications integrate JSONPlaceholder patterns without adding proper access controls.
CORS Misconfiguration and Unsafe Methods
CORS reflecting arbitrary origins with credentials enables cross-origin authenticated requests to the API. Combined with allowed DELETE, PUT, and PATCH methods, this expands the attack surface for browser-based exploits. An attacker can craft malicious pages that perform state-changing requests on behalf of authenticated users who visit compromised sites.
Reconnaissance and Implementation Disclosure
The exposed X-Powered-By header reveals the server framework, aiding attackers in identifying known vulnerabilities or misconfigurations specific to Express. Absence of API versioning complicates change management and may force clients to rely on deprecated endpoints with weaker security controls.
Methodology
MiddleBrick performed a black-box scan against the JSONPlaceholder API using read-only methods aligned with OWASP API Top 10 2023. The scanner executed 12 security checks across categories including authentication, authorization, input validation, CORS, and unsafe consumption. Where relevant, 18 LLM-guided adversarial probes were applied across three tiers to test for prompt injection, data extraction, and logic bypasses. All testing was conducted without modifying data or relying on prior knowledge of internal architecture.
The methodology focused on discovering authentication gaps, enumerating resource identifiers to test authorization boundaries, validating input handling for dangerous methods, and inspecting CORS headers for overly permissive rules. Each probe class targeted a specific control objective, such as verifying whether endpoints reject unauthenticated requests or whether IDOR is detectable via predictable IDs. Results were correlated to determine severity and exploitability within realistic threat scenarios.
Results Overview
The API scored 73 out of 100 and received a grade of C. This indicates moderate risk where critical findings in authentication and input validation require remediation. The distribution includes multiple critical and high findings with fewer medium and low items. The absence of authentication and presence of IDOR place the API at risk of unauthorized data access and manipulation.
Critical findings centered on missing authentication and CORS misconfiguration, allowing unauthenticated access and cross-origin credentialed requests. High findings included IDOR and exposure of internal properties, which can enable resource traversal and information disclosure. Low findings related to implementation disclosure and lack of versioning, which reduce operational resilience but do not directly permit unauthorized access.
For operators, critical items demand immediate attention: implement authentication, enforce authorization on all endpoints, and lock down CORS to specific trusted origins. High-severity items should be addressed through strict input validation and resource-level checks. Low-severity items can be handled in follow-up hardening cycles to improve maintainability and reduce reconnaissance value.
Detailed Findings
API accessible without authentication
The endpoint returned 200 without any authentication credentials.
Implement authentication (API key, OAuth 2.0, or JWT) for all API endpoints.
Sequential IDs with confirmed IDOR (ID +1)
Path contains numeric IDs (1) — easily enumerable by attackers. Changing ID from 1 to 2 returned 200. Response schemas match (4/4 keys identical) — strong IDOR evidence.
Use UUIDs or non-sequential identifiers. Implement object-level authorization checks.
CORS reflects arbitrary origin with credentials
The server reflects any Origin header in Access-Control-Allow-Origin AND allows credentials — full cross-origin attack surface.
Validate the Origin header against an allowlist. Never reflect arbitrary origins with credentials enabled.
IDOR risk: multiple sequential object IDs in response body
Response body contains 2 numeric ID field(s) (userId:1, id:1). Enumerable object IDs enable IDOR / insecure direct object reference attacks when per-object authorization is missing.
Use UUIDs for object identifiers. Verify per-object authorization on every request. Never expose internal IDs for resources the user doesn't own.
[Arena] InternalUserPropertyExposure
Detects presence of internal user properties (e.g., isAdmin, role) in response bodies that should not be exposed to external clients
Review this detection pattern
No authentication on any HTTP method
The endpoint returns success for GET and 4 other HTTP methods without authentication.
Implement authentication for all API endpoints. Consider OAuth 2.0, API keys, or JWT bearer tokens.
Missing security headers (2/4)
Missing: HSTS — protocol downgrade attacks; X-Frame-Options — clickjacking.
Add the following headers to all API responses: strict-transport-security, x-frame-options.
Dangerous HTTP methods allowed: DELETE, PUT, PATCH
The server advertises support for methods that can modify or delete resources.
Only expose HTTP methods that are actually needed. Disable TRACE, and restrict DELETE/PUT/PATCH.
No API versioning detected
The API URL doesn't include a version prefix (e.g., /v1/) and no version header is present.
Implement API versioning via URL path (/v1/), header (API-Version), or query parameter.
Technology exposed via X-Powered-By: Express
The X-Powered-By header reveals framework details.
Remove the X-Powered-By header in production.
Attacker Perspective
From an attacker’s perspective, the most straightforward path begins with unauthenticated access. Since no authentication is required, an attacker can directly call any endpoint without credentials. A simple recon step is to request GET /posts/1 and observe a 200 OK response, confirming the API is reachable and functional. This establishes baseline behavior for further exploration.
With confirmation that the API uses sequential IDs, the attacker probes IDOR by incrementing IDs and observing responses. For example, accessing GET /posts/1 and then GET /posts/2 returns valid posts, demonstrating that resource boundaries are not enforced. The attacker iterates through IDs to map the dataset and identify sensitive synthetic entries that might reveal integration patterns when used in downstream applications.
The CORS misconfiguration allows the attacker to craft a webpage that sets Access-Control-Allow-Origin to an arbitrary origin while including credentials. Combined with allowed DELETE, PUT, and PATCH methods, the attacker can attempt cross-origin state-changing requests. Although JSONPlaceholder does not hold user accounts, in a real application this pattern could enable unauthorized modifications on behalf of authenticated users. The exposed X-Powered-By header further informs the attacker of the underlying framework, enabling targeted exploits against known Express vulnerabilities or misconfigurations.
Overall, the attacker can chain unauthenticated access, IDOR enumeration, and CORS abuse to build a foothold for scraping, data mapping, and potential lateral movement in integrated environments. The low effort required to trigger these findings makes them attractive for automated scripts and opportunistic scanning.
Analysis
The critical authentication finding indicates that endpoints do not enforce any identity verification. Requests to GET /posts/1, DELETE /posts/1, and PATCH /posts/1 succeed without credentials, demonstrating that authorization is not gated by authentication. In a typical implementation, this would be addressed by an authentication middleware layer validating tokens or session identifiers before routing to business logic.
The high-severity IDOR finding manifests through predictable numeric IDs in responses. For instance, a request to GET /posts/1 may return:
{"userId": 1, "id": 1, "title": "sample post", "body": "content"}An attacker can iterate IDs and observe consistent 200 responses, confirming that resource access is not restricted by user context. The related property authorization finding for [Arena] InternalUserPropertyExposure suggests that internal flags or roles may be reflected in responses, increasing information disclosure.
CORS misconfiguration is evident when an origin such as https://evil.com is reflected in Access-Control-Allow-Origin while credentials are permitted. A dangerous method like DELETE /posts/1 could be triggered via a malicious page using:
fetch('https://jsonplaceholder.example/posts/1', { method: 'DELETE', credentials: 'include' })The lack of API versioning means clients cannot safely assume backward compatibility, and the X-Powered-By header exposes the server framework, aiding reconnaissance. Together, these findings illustrate the importance of enforcing authentication, validating input, and tightening CORS policies.
Industry Context
In the category of public read-only APIs, JSONPlaceholder’s posture is weaker than best practice baselines that require authentication and strict CORS controls. Unlike production-grade APIs in fintech or social platforms, JSONPlaceholder intentionally omits authentication for simplicity, but this highlights the need to differentiate demo services from production endpoints. Security controls aligned with OWASP API Top 10 are essential even for non-sensitive APIs to prevent normalization of insecure patterns.
Findings such as missing authentication and IDOR are directly relevant to PCI-DSS 4.0 and SOC 2 Type II controls where access management and audit logging are required. CORS misconfiguration ties into secure configuration management, which supports compliance efforts across frameworks. While GDPR and HIPAA alignment are not directly implicated due to the absence of personal data, the patterns observed could hinder audits if similar designs are replicated in regulated contexts.
API versioning and information disclosure via headers affect operational security and support incident response. Addressing these issues helps align with secure software development lifecycle practices and reduces the attack surface for integration-related risks.
Remediation Guide
API accessible without authentication
Introduce an authentication layer (e.g., API keys or OAuth2) and validate credentials on every request before processing.
app.use((req, res, next) => {
const token = req.headers['authorization'];
if (!token || !isValidToken(token)) {
return res.status(401).json({ error: 'Unauthorized' });
}
next();
}); No authentication on any HTTP method
Apply authentication middleware globally and enforce per-method scopes where applicable.
const requireAuth = (req, res, next) => {
if (!req.user) return res.status(401).send('Unauthorized');
next();
};
app.use(requireAuth); Missing security headers (2/4)
Add security headers such as X-Content-Type-Options, X-Frame-Options, Content-Security-Policy, and Strict-Transport-Security.
app.use((req, res, next) => {
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('Content-Security-Policy', "default-src 'none'");
res.setHeader('Strict-Transport-Security', 'max-age=63072000');
next();
}); Sequential IDs with confirmed IDOR
Implement resource-level authorization checks so users can only access their own resources, and avoid exposing sequential identifiers.
app.get('/posts/:id', (req, res) => {
const post = getPost(req.params.id);
if (!post || post.userId !== req.user.id) {
return res.status(403).json({ error: 'Forbidden' });
}
res.json(post);
}); IDOR risk: multiple sequential object IDs in response body
Avoid returning sequential or guessable identifiers in responses; use opaque identifiers and enforce ownership checks.
const generateOpaqueId = () => crypto.randomBytes(8).toString('hex');
app.get('/posts/:id', (req, res) => {
const post = getPostByOpaqueId(req.params.id);
if (!post || post.userId !== req.user.id) {
return res.status(403).json({ error: 'Forbidden' });
}
res.json(post);
}); [Arena] InternalUserPropertyExposure
Strip internal properties from API responses and only expose fields intended for clients.
app.get('/users/me', (req, res) => {
const user = getUser(req.user.id);
const safeUser = {
id: user.id,
name: user.name,
email: user.email
};
res.json(safeUser);
}); Dangerous HTTP methods allowed: DELETE, PUT, PATCH
Disable or restrict dangerous HTTP methods unless explicitly required and protected by authentication and authorization.
app.disable('x-powered-by');
app.use((req, res, next) => {
if (['DELETE', 'PUT', 'PATCH'].includes(req.method) && !req.user) {
return res.status(405).json({ error: 'Method Not Allowed' });
}
next();
}); CORS reflects arbitrary origin with credentials
Set CORS to a strict allowlist of trusted origins and avoid allowing credentials from untrusted sources.
const cors = require('cors');
const corsOptions = {
origin: ['https://trusted.example.com'],
credentials: true
};
app.use(cors(corsOptions)); Defense in Depth
Beyond fixing immediate findings, JSONPlaceholder should adopt layered defenses. Implement authentication and property-level authorization middleware to ensure that only permitted subjects can access or modify resources. Enforce CORS policies to allow only specific trusted origins and avoid reflecting arbitrary origins with credentials. Disable or restrict dangerous HTTP methods such as DELETE, PUT, and PATCH unless explicitly required and protected.
Introduce rate limiting and anomaly detection to mitigate scraping and automated enumeration. Require API versioning in routes to enable controlled deprecation and reduce reliance on legacy behavior. Remove or obfuscate framework headers like X-Powered-By to limit reconnaissance value. Regular penetration testing and threat modeling exercises help identify logic flaws and ensure that security controls evolve with the API surface.
Security headers such as Content-Security-Policy, X-Content-Type-Options, and Strict-Transport-Security should be applied where applicable to harden the transport layer. Logging and monitoring of access patterns support timely detection of abuse. These measures collectively raise the bar against opportunistic attackers and reduce the likelihood of insecure patterns spreading into production environments.
Conclusion
The scan of JSONPlaceholder reveals a Grade C API with critical gaps in authentication and authorization, compounded by CORS misconfiguration and exposure of implementation details. These weaknesses align with common misconfigurations in public APIs and demonstrate the importance of enforcing access controls even for synthetic data endpoints. Addressing the findings reduces the risk of unauthorized resource access and helps prevent normalization of insecure practices.
Operators should prioritize implementing authentication, tightening CORS rules, and validating input to ensure that resource identifiers do not enable enumeration. Regular security reviews and automated scanning should be part of ongoing maintenance. While JSONPlaceholder serves a valuable prototyping purpose, treating it as a security baseline encourages better design patterns when transitioning to production services.
For readers managing similar public APIs, the key takeaway is to apply defense-in-depth, enforce least privilege, and validate that authorization checks are present for every endpoint. These steps materially reduce exposure and support more robust API security postures.