ISO 27001 Certification Guide: Fix API SSRF Risks

A developer guide to prevent OWASP API7:2023 Server-Side Request Forgery, satisfying ISO 27001 controls A.8.25 & A.12.1.2, and automating audit evidence.

ISO 27001 Certification Guide: Fix API SSRF Risks

ISO 27001 Certification Guide: Fix API SSRF Risks

APIs that fetch resources from external URLs are common, powering features like webhooks, file imports, and document converters. But if not handled carefully, they can open a door for attackers to map, attack, and exfiltrate data from your internal network. This vulnerability is known as Server-Side Request Forgery (SSRF), or OWASP API7:2023.

For teams preparing for an ISO 27001 audit, demonstrating control over SSRF is non-negotiable. It directly challenges the effectiveness of your secure development lifecycle (A.8.25) and protection against malware (A.12.1.2). This guide provides a developer-focused roadmap to find, fix, and prevent SSRF, helping you generate the evidence needed to satisfy auditors.

What is API SSRF (API7:2023)?

Server-Side Request Forgery occurs when an attacker can trick a server-side application into making an HTTP request to an arbitrary domain of their choosing. Instead of targeting a legitimate external service, the attacker points the API to a destination it was never intended to access, such as internal services, loopback interfaces, or cloud provider metadata endpoints.

Imagine an API endpoint designed to check the status of a remote website:

GET /api/v1/status?url=https://example.com

A vulnerable server might naively take the `url` parameter and send a request. An attacker can abuse this by supplying an internal address:

  • GET /api/v1/status?url=http://localhost:8080/admin - Accessing an internal admin panel.

  • GET /api/v1/status?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ - Stealing AWS credentials from the EC2 metadata service.

  • GET /api/v1/status?url=http://10.0.1.5:6379 - Port scanning an internal Redis server.

Because the requests originate from the trusted server, they bypass firewall rules and can access sensitive internal resources, effectively turning your API into a pivot point for network compromise.

Mapping SSRF to ISO 27001:2022 Controls

During an ISO 27001 audit, an SSRF finding can cause a major non-conformity. Here’s how it maps to key controls:

A.8.25: Secure development lifecycle

This control requires that information security is designed and implemented within the development lifecycle. Preventing SSRF is a perfect example. A mature process includes security requirements gathering (e.g., "outbound requests must only target approved domains"), secure coding practices, and automated testing to validate these requirements. Failing to stop SSRF suggests a critical gap in your SDLC's security integration.

A.12.1.2: Protection against malware

While often associated with anti-virus software, this control is about preventing, detecting, and recovering from malware. SSRF is a primary vector for reconnaissance and payload delivery. An attacker can use it to scan for vulnerable internal services and then exploit them to gain a foothold, move laterally, or exfiltrate data. Proactively blocking SSRF is a powerful form of malware protection.

Other Related Controls

SSRF weaknesses also reflect poorly on A.8.3 (Secure coding) and A.8.8 (Management of technical vulnerabilities). It’s a classic, well-documented vulnerability that secure coding principles are designed to eliminate.

Auditor's Perspective: "You're telling me a public-facing API can make arbitrary requests to our internal network? That shows a fundamental misunderstanding of network segmentation and secure input handling. How can I trust your other security claims if the basics are missing?"

The Shift-Left Solution: Preventing SSRF in Code

Waiting for a pentest to find SSRF is too late. The most effective place to stop it is within the code and the CI/CD pipeline. The core principle is simple: never trust user-supplied URLs. The implementation requires discipline.

Example: A Vulnerable Node.js Endpoint

Here’s a typical vulnerable code snippet using Express and Axios to fetch content from a URL.


const express = require('express');
const axios = require('axios');
const app = express();

// VULNERABLE ENDPOINT
app.get('/fetch-image', async (req, res) => {
  const { imageUrl } = req.query;

  if (!imageUrl) {
    return res.status(400).send({ error: 'imageUrl is required' });
  }

  try {
    // The vulnerability is here: No validation on `imageUrl`
    const response = await axios.get(imageUrl, { responseType: 'stream' });
    response.data.pipe(res);
  } catch (error) {
    res.status(500).send({ error: 'Failed to fetch image.', details: error.message });
  }
});

app.listen(3000, () => console.log('Server running on port 3000'));
        

An attacker could call /fetch-image?imageUrl=http://169.254.169.254/latest/user-data and potentially compromise the server.

The Secure Implementation: Allow-Lists and Validation

The only robust defense against SSRF is an allow-list. Block-listing IPs like 127.0.0.1 or domains like localhost is a fragile cat-and-mouse game that can be bypassed with DNS trickery, alternate IP encodings, and redirects. For deep-dives on various security measures, check out our comprehensive API security comparison guides.

Here’s how to refactor the code for security:

  1. Define an Allow-List: Explicitly list the domains your API is permitted to contact.

  2. Parse and Validate the URL: Use a standard library to break the URL into its components (protocol, hostname, port).

  3. Enforce the Allow-List: Check if the parsed hostname belongs to your allow-list.

  4. Resolve the Hostname: Resolve the domain to an IP address to ensure it doesn't point to an internal-range IP address.

  5. Disable Redirects: An attacker might use a redirect from an allowed domain to a forbidden one. Disable this in your HTTP client.

Example: A Secure Node.js Endpoint


const express = require('express');
const axios = require('axios');
const { URL } = require('url');
const dns = require('dns').promises;

const app = express();

const ALLOWED_DOMAINS = new Set(['images.unsplash.com', 'pexels.com']);

// SECURE ENDPOINT
app.get('/fetch-image-secure', async (req, res) => {
  const { imageUrl } = req.query;

  if (!imageUrl) {
    return res.status(400).send({ error: 'imageUrl is required' });
  }

  try {
    const parsedUrl = new URL(imageUrl);

    // 1. Validate Protocol
    if (!['http:', 'https:'].includes(parsedUrl.protocol)) {
        return res.status(400).send({ error: 'Invalid protocol.' });
    }

    // 2. Enforce Hostname Allow-List
    if (!ALLOWED_DOMAINS.has(parsedUrl.hostname)) {
      return res.status(403).send({ error: 'Domain not allowed.' });
    }

    // 3. Resolve IP to prevent DNS rebinding and internal IP attacks
    const { address } = await dns.lookup(parsedUrl.hostname);
    const ip = require('ip');
    if (ip.isPrivate(address)) {
        return res.status(403).send({ error: 'Destination IP is internal.' });
    }

    // 4. Make the request, disabling redirects
    const response = await axios.get(parsedUrl.toString(), { 
        responseType: 'stream',
        maxRedirects: 0 // CRITICAL: Disable redirects
    });

    response.data.pipe(res);

  } catch (error) {
    res.status(500).send({ error: 'Failed to fetch image securely.', details: error.message });
  }
});

app.listen(3000, () => console.log('Server running on port 3000'));
        

This revised code is far more resilient. It trusts nothing and validates everything, making it defensible during an audit. This form of strict data validation is a core principle, similar to what's needed to prevent API mass assignment.

Automating SSRF Detection and Evidence Generation

While secure code is the goal, proving it to auditors requires automation. An API posture management strategy provides the continuous validation and documentation needed.

  • Static Analysis (SAST) in CI/CD: Integrate a SAST tool into your pull request pipeline. Configure it with rules to flag code that makes HTTP requests using unsanitized user input. This provides a preventative control and fails builds before vulnerable code merges.

  • Dynamic Analysis (DAST) in Staging: Use a DAST scanner that is specifically designed to test for SSRF. These tools will automatically probe your APIs with malicious payloads (like localhost or known cloud metadata URLs) and report on vulnerabilities. The APIPosture platform specializes in mapping such findings directly back to compliance requirements.

  • OpenAPI Contract Enforcement: While not a complete solution for SSRF, your OpenAPI specification can enforce basic format validation on URL parameters (e.g., format: 'url'). A contract validation tool can ensure requests match this format at the gateway or in CI tests.

ISO 27001 Audit Evidence Checklist for SSRF

When the auditor asks about your controls for vulnerabilities like SSRF, be ready to present the following automated evidence:

  • Secure Coding Policy: A document that explicitly requires allow-list validation for all API endpoints that initiate outbound requests based on user input.

  • Pull Request Templates: A PR template with a checklist item: "Does this code make outbound requests? If so, is an allow-list enforced?"

  • CI/CD Pipeline Logs: Reports from your SAST/DAST tools showing that SSRF scans were executed for the commit and passed.

  • Vulnerability Management Reports: Dashboards from your security tools showing zero open, high-severity SSRF vulnerabilities in production applications.

  • Code Samples: A link to your secure wrapper or library for handling outbound requests, demonstrating a standardized, approved method that all developers use.

For more hands-on guidance, explore our detailed remediation guides covering a wide range of API vulnerabilities.

Conclusion: From Vulnerability to Compliance

Server-Side Request Forgery is more than just a code-level bug; it's a direct threat to your organization's information security posture and a red flag for any ISO 27001 auditor. By treating it as a critical risk, you can move beyond reactive patching and build a proactive defense.

The key is to embrace a shift-left mindset: define strict allow-lists, write secure and validated code, and automate detection within your CI/CD pipeline. This approach not only neutralizes the threat of SSRF but also produces a clear, auditable trail of evidence, proving that your security controls are effective, consistent, and an integral part of how you build software.

Share this article:
>_ Keep Reading

Explore more security insights

Choose which optional cookies to allow. You can change this any time.