Insecure Direct Object Reference (IDOR)
A vulnerability where applications expose internal object references without proper authorization checks, allowing unauthorized access to data.
Insecure Direct Object Reference (IDOR) is a type of access control vulnerability that occurs when an application exposes internal implementation objects—like database IDs, file paths, or user references—and fails to verify whether the requesting user is authorized to access them. In Web3 contexts, IDOR vulnerabilities commonly appear in dApp backends, NFT metadata APIs, and user management systems, potentially exposing sensitive user data or enabling unauthorized actions.
How IDOR Works
A vulnerable endpoint might look like:
1GET /api/user/12345/profile
If the application doesn't verify that the authenticated user is actually user 12345, an attacker can enumerate through IDs:
1GET /api/user/12346/profile → Another user's data2GET /api/user/12347/profile → Another user's data3...
IDOR in Web3 Applications
NFT Metadata APIs
1// Vulnerable endpoint2app.get('/api/nft/:tokenId/metadata', (req, res) => {3 const metadata = getMetadata(req.params.tokenId);4 res.json(metadata); // No ownership check!5});67// Could expose unrevealed NFT metadata before mint
User Wallet APIs
1// Vulnerable: Exposes any user's data by ID2app.get('/api/users/:userId/wallets', (req, res) => {3 const wallets = getUserWallets(req.params.userId);4 res.json(wallets); // No authorization!5});67// Attack: Enumerate user IDs to discover wallet addresses
Transaction History
1// Vulnerable: Internal transaction IDs exposed2app.get('/api/transactions/:txId', (req, res) => {3 const tx = getTransaction(req.params.txId);4 res.json(tx); // Attacker can view others' transactions5});
Common IDOR Patterns
Sequential IDs
1/api/orders/10012/api/orders/10023/api/orders/1003 → Easy to enumerate
Predictable References
1/api/documents/report_2024_Q1.pdf2/api/documents/report_2024_Q2.pdf → Pattern is obvious
Exposed Internal Keys
1/api/files?key=aws-s3-bucket/users/private/document.pdf
Prevention Techniques
Authorization Checks
Always verify the requester has permission:
1app.get('/api/user/:userId/profile', authenticate, (req, res) => {2 // Check requester is the user or has admin role3 if (req.user.id !== req.params.userId && !req.user.isAdmin) {4 return res.status(403).json({ error: 'Forbidden' });5 }67 const profile = getUserProfile(req.params.userId);8 res.json(profile);9});
Indirect References
Map public tokens to internal IDs:
1// Instead of exposing user ID 123452// Generate a random reference token3const publicRef = generateSecureToken(); // "a7f3b2c1d4e5"4referenceMap.set(publicRef, userId);56// Endpoint uses non-enumerable reference7app.get('/api/user/:publicRef/profile', (req, res) => {8 const userId = referenceMap.get(req.params.publicRef);9 if (!userId) return res.status(404).json({ error: 'Not found' });10 // Continue with authorization check...11});
UUIDs Instead of Sequential IDs
1// Instead of: /api/orders/10012// Use: /api/orders/550e8400-e29b-41d4-a716-44665544000034const orderId = crypto.randomUUID();
UUIDs are not enumerable, but still require authorization checks.
Scoped Queries
Always filter by authenticated user:
1// VULNERABLE: Fetches any order by ID2const order = await Order.findById(orderId);34// SECURE: Filters by authenticated user5const order = await Order.findOne({6 _id: orderId,7 userId: req.user.id // Scope to current user8});
IDOR in Smart Contracts
While smart contracts are transparent by design, IDOR-like issues can occur:
1// All data is public on-chain, but...2// This function lets anyone modify any user's data!3function updateUserData(address user, bytes memory data) external {4 userData[user] = data; // No msg.sender check!5}67// Correct:8function updateMyData(bytes memory data) external {9 userData[msg.sender] = data; // User can only modify their own10}
Testing for IDOR
Manual Testing
- Authenticate as User A
- Access resource belonging to User A (note the ID)
- Change ID to another user's resource
- Check if access is granted
Automated Testing
1# Simple IDOR scanner2for user_id in range(1, 10000):3 response = requests.get(4 f'/api/user/{user_id}/profile',5 headers={'Authorization': f'Bearer {attacker_token}'}6 )7 if response.status_code == 200:8 print(f'IDOR found: User {user_id} data accessible')
Audit Checklist
When auditing for IDOR:
- All endpoints with resource IDs have authorization checks
- Authorization checks verify ownership/permission, not just authentication
- Sequential/predictable IDs replaced with UUIDs or indirect references
- Database queries scoped to authenticated user
- API responses don't leak other users' data
- Admin endpoints properly protected
- File access uses indirect references
Impact in Web3
IDOR vulnerabilities in Web3 applications can:
- Expose wallet addresses and transaction patterns
- Reveal unreleased NFT metadata
- Enable unauthorized API actions
- Leak KYC/identity information
- Allow access to private user settings
While blockchain data is public, off-chain APIs often contain sensitive information that requires proper access control.
Articles Using This Term
Learn more about Insecure Direct Object Reference (IDOR) in these articles:
Related Terms
Access Control
Security mechanisms that restrict which addresses can call specific functions in a smart contract, preventing unauthorized actions.
Cross-Site Scripting (XSS)
A web vulnerability where attackers inject malicious scripts into web applications, enabling theft of user data or unauthorized actions.
Cross-Site Request Forgery (CSRF)
An attack that tricks authenticated users into executing unwanted actions on a web application where they're logged in.
Frontend Security
Security practices protecting web application client-side code from attacks like XSS, CSRF, and malicious script injection.
Need expert guidance on Insecure Direct Object Reference (IDOR)?
Our team at Zealynx has deep expertise in blockchain security and DeFi protocols. Whether you need an audit or consultation, we're here to help.
Get a Quote

