During my early years in bug bounty programs and security research, I observed firsthand how crypto projects—even those with robust blockchain protocols—often crumble due to overlooked Web2 vulnerabilities.
In my 2020 blog post, Common Security Issues with Crypto Websites and APIs, I highlighted prevalent issues such as injection attacks, broken authentication, and insufficient authorization. At the time, many dismissed these risks, believing the decentralized nature of blockchain would render traditional web vulnerabilities obsolete.
Today, as the Web3 ecosystem matures and evolves, many of those same vulnerabilities persist—but they have shifted. Rather than existing in smart contracts themselves, they now thrive in off-chain components: relayers, signers, indexing services, and backend APIs. These systems, while often treated as secondary class citizens or trusted by default, serve as the critical connective tissue between users and blockchains. When compromised, they can undermine the integrity of the entire protocol.
In this post, I will focus on two particularly impactful vulnerabilities: Server-Side Request Forgery (SSRF) and Insecure Direct Object Reference (IDOR). Both are long-standing issues in Web2, and both are increasingly relevant in Web3 infrastructure.
The Off-Chain Reality of Web3
Web3 projects often emphasize decentralization, censorship resistance, and trust minimization. While these principles are core to blockchain protocols, they do not automatically extend to the full stack.
In practice, most Web3 applications rely on centralized infrastructure for key functionalities: transaction broadcasting, gas fee estimation, NFT metadata retrieval, user authentication, and analytics. These systems introduce the same attack surfaces that plagued Web2 for decades.
According to Immunefi’s Top 10 Most Common Vulnerabilities in Web3 report, more than 60% of all exploits in 2023 targeted off-chain systems. This statistic alone should serve as a wake-up call for teams who rely on third-party services, cloud infrastructure, or internally developed APIs without applying rigorous security controls.
SSRF in Web3 Applications
Understanding SSRF
Server-Side Request Forgery (SSRF) is an attack in which an attacker tricks a server into making unauthorized requests—often to internal services or cloud APIs. While this is not new in traditional web applications, SSRF in Web3 carries heightened consequences due to the high-value nature of blockchain infrastructure.

In the context of decentralized applications, SSRF often targets:
- Relayers: Services responsible for submitting signed transactions to the blockchain.
- Cloud Metadata APIs: Exposed endpoints that return infrastructure credentials.
- Data Fetching Services: Systems that retrieve metadata, price feeds, or external assets.
A Realistic Exploit Scenario
Consider a relayer responsible for fetching NFT metadata based on user-supplied URLs. If this relayer accepts URLs without validation, an attacker could point the metadata field to a cloud metadata endpoint:
http://169.254.169.254/latest/meta-data/iam/security-credentials/
This URL, specific to AWS EC2 instances, returns credentials that allow full access to cloud infrastructure. By tricking the relayer into accessing this endpoint, the attacker can extract IAM keys, assume privileged roles, and use those credentials to modify node configurations, sign unauthorized transactions, or extract private data.
This is not a hypothetical threat. The Capital One breach in 2019—one of the largest financial data breaches in history—was executed using a similar SSRF vector.
Why Web3 Projects Are Exposed
There are several reasons SSRF is so prevalent in Web3:
- Assumptions of Immutability: Developers often assume that because smart contracts are immutable, the systems surrounding them must be safe by association. This leads to relaxed validation and oversight in backend components.
- Dynamic Data Requirements: Relayers and metadata fetchers often retrieve real-time data from user-supplied endpoints. This is common in NFT platforms, oracle implementations, and data aggregators.
- Poor URL Validation: Many systems accept URLs without verifying the destination, protocol, or IP range.
Recommended Mitigations
To reduce the risk of SSRF:
- Implement URL Allowlisting: Accept only known, trusted domains.
- Use Network Segmentation: Prevent public-facing services from reaching internal resources.
- Harden Cloud Environments: Enforce the use of IMDSv2 (AWS/Azure) to require session-based access to metadata.
Code Example: Unsafe and Hardened
Vulnerable code:
app.post("/fetch-metadata", async (req, res) => {
const url = req.body.url;
const response = await axios.get(url); // SSRF risk
res.send(response.data);
});
Improved code with validation:
const allowedDomains = ["api.coingecko.com", "trusted-source.org"];
const userURL = new URL(req.body.url);
if (!allowedDomains.includes(userURL.hostname)) {
throw Error("Invalid URL");
}
Understanding IDOR
Insecure Direct Object Reference (IDOR) occurs when applications expose internal identifiers (e.g., user IDs or transaction IDs) in URLs or API parameters without verifying that the requesting user has permission to access the referenced data.
This vulnerability is particularly common in backend APIs that interface with wallets, transaction histories, or internal data stores.
Where IDOR Manifests in Web3
Common locations where IDOR is found:
- Wallet APIs: Users accessing transaction history via predictable endpoints.
- NFT Platforms: Previewing unrevealed content using object IDs.
- DeFi Dashboards: Viewing position data for other users by modifying user IDs.
Exploitation Example
Consider a crypto wallet service with the following endpoint:
GET /transactions/{userId}
If user IDs are assigned incrementally and there is no ownership validation, an attacker can simply increment the ID to access another user’s transaction history.
Vulnerable backend code (Flask):
@app.route('/transactions/')
def get_transactions(user_id):
transactions = db.query("SELECT * FROM txs WHERE user_id = ?", user_id)
return jsonify(transactions) # No ownership validation
The attacker can iterate through user IDs (e.g., 1001, 1002) and collect transaction hashes, wallet balances, and contract interactions. This data can then be used for phishing, surveillance, or targeting high-value accounts.

Why Web3 Is at Risk
- Sequential Identifiers: Many projects still rely on auto-incrementing database IDs.
- Lack of Authorization Checks: Some teams assume blockchain validation is sufficient.
- Overlooked API Security: Smart contracts receive audit attention, but backend APIs often do not.
Recommended Mitigations
- Use Indirect Identifiers: Replace numeric IDs with UUIDs or hash-based references.
// Bad: /transactions/1001 // Good: /transactions/ffc61035-b579-44e0-b7fc-199bb005cdde
- Enforce Ownership Verification:
app.get("/transactions/:uuid", (req, res) => {
const transaction = db.get(req.params.uuid);
if (transaction.owner !== req.user.wallet) {
throw Error("Unauthorized");
}
});
- Rate Limiting: Throttle requests that appear to be probing sequential IDs.
A Broader Lesson for Web3 Developers
From my early experiences in bug bounty platforms to my current work with Web3 infrastructure, one consistent lesson has remained true: security is only as strong as its weakest link.
While we celebrate the innovations in zero-knowledge proofs, L2 scaling, and decentralized finance, we must not lose sight of the foundational principles of application security. The most sophisticated protocol can still be undone by a single exposed endpoint or misconfigured server.
Practical Steps for Project Teams
- Audit Off-Chain Infrastructure: Treat APIs, relayers, and backend services with the same diligence as smart contracts.
- Adopt Zero-Trust Architectures: Assume all inputs and requests are malicious until proven otherwise.
- Train Development Teams: Ensure that engineers are familiar with OWASP Top 10 vulnerabilities and mitigation techniques.
As I emphasized in my 2020 post, the future of crypto depends not just on building novel protocols, but on learning from the mistakes of the past. Web3 will only thrive if we prioritize secure development across the entire stack—not just on-chain.
If you want to test it out in a simulated environment, take a look at: https://security.manishlabs.xyz/
