top of page
Eyal Katz

The Developer's Guide to OWASP API Security


OWASP Logo

We live in an API-driven world. But, just as APIs connect businesses and users globally, they also offer a gateway between malicious actors and valuable data.

 

74% of organizations report at least three API-related data breaches in the last two years, and 59% of executives say they have to slow out the rollout of new applications because of API security concerns.

 

Clearly, the current level of awareness and API security is not enough. Enter: the OWASP API Security Top 10.

 

What is the OWASP?

OWASP (Open Web Application Security Project) is an international non-profit organization dedicated to improving software security. Founded in 2001, OWASP aims to make software security visible so that individuals and organizations worldwide can make informed decisions about software security risks.

 

What is API Security?

APIs serve as the channels for communication between different software applications, systems, or services. As APIs expose application logic and sensitive data, they are attractive targets for attackers, making API security all the more critical.

 

API security refers to the practices, techniques, and tools designed to protect APIs from attacks like broken authentication and SSRF. It includes strategies like:

  • Authentication and authorization

  • Input validation

  • Encryption

  • Rate limiting and throttling

  • API gateway

  • Regular security testing

  • Monitoring and logging

  • API discovery

 

What is the OWASP API Security Top 10

OWASP API Logo

OWASP’s most recognized project is the OWASP Top 10, a regularly updated report that outlines the most critical web application security risks, providing organizations with a starting point for application security. Another significant project is the OWASP API Security Top 10, which outlines the most common API-specific security risks. It provides examples of the potential impact of these risks and offers guidance on mitigating them. The OWASP has even released free tools like ZAP to support API vulnerability scanning.


5 Reasons Why You Should Care About the OWASP API Security Top 10

  1. Establish a Robust API Security Strategy: This tool helps organizations establish a robust API security strategy and provides a framework for identifying and mitigating APIs' most critical security risks.

  2. Safeguard Sensitive Data: APIs often expose application logic and sensitive data. The OWASP API Security Top 10 guides how to protect this data, helping to prevent attacks and data breaches.

  3. Compliance with Regulations: Many regulations and standards require businesses to take appropriate steps to secure their data. By proactively following the OWASP API Security Top 10, organizations can demonstrate that they are in control and taking the necessary measures to secure their APIs.

  4. Build Trust Among Users and Stakeholders: Secure APIs are a sign of a responsible organization and a reassurance of data safety. The Top 10 list helps your organization instill confidence and build trust among users and stakeholders.

  5. Stay Updated with Evolving Threats: The list is regularly and diligently updated to reflect the evolving threat detection landscape, ensuring you are always well-informed of the latest threats and can take appropriate measures to protect APIs.

 

OWASP Top 10 in API Security for 2023

1. Broken Object Level Authorization (BOLA)

BOLA occurs when APIs reveal object IDs, allowing attackers to access or modify data without authorization. It poses a significant risk of data breaches and the exposure of sensitive information.

 

Remediation Tips:

  • Do not rely on IDs that the client sends. Use IDs stored in the session object instead.

  • Check authorization for each client request to access the database.


function checkObjectAccess(req, res, next) {
  const userId = req.session.userId; // User ID from session
  const objectId = req.params.id; // Object ID from request
  ObjectModel.findById(objectId).then(object => {
    if (!object) {
      return res.status(404).send('Object not found');
    }
    if (object.ownerId !== userId && req.user.role !== 'admin') {
      return res.status(403).send('Access Denied');
    }
    next();
  }).catch(err => {
    res.status(500).send('Server error');
  });
}

 

  • Use random IDs that cannot be guessed (UUIDs). Here is how to generate random IDs with uuid.

 

const { v4: uuidv4 } = require('uuid');
app.post('/api/object', (req, res) => {
  const newObject = {
    id: uuidv4(), // Generate a random UUID for the new object
    // Set other object properties from request
  };
  ObjectModel.create(newObject).then(createdObject => {
    res.status(201).json(createdObject);
  }).catch(error => {
    res.status(500).send('Error creating object');
  });
});

 

2. Broken Authentication

Broken authentication occurs when security flaws in authentication processes allow attackers to bypass them, potentially leading to token theft, brute force attacks, and other incidents like session hijacking and clickjacking.

 

Remediation Tips:

  • Implement robust authentication mechanisms. For example, you can use JWTs for secure, stateless authentication.

 

const jwt = require('jsonwebtoken');
// Generate JWT Token
function generateToken(user) {
  return jwt.sign({ userId: user.id, role: user.role }, process.env.JWT_SECRET, { expiresIn: '1h' });
}
// Middleware to validate token
function verifyToken(req, res, next) {
  const token = req.headers['authorization'];
  if (!token) return res.status(401).send('Access Denied: No Token Provided!');
  try {
    const verified = jwt.verify(token, process.env.JWT_SECRET);
    req.user = verified;
    next();
  } catch (error) {
    res.status(400).send('Invalid Token');
  }
}

 

  • Use libraries that are actively maintained and receive security updates.

  • Automate dependency updates using tools like Dependabot for GitHub repositories.

  • Monitor for and block suspicious authentication attempts.

 

3. Broken Object Property Level Authorization

Broken object property level authorization happens when access controls fail to protect individual object properties, enabling unauthorized viewing or editing.

 

Remediation Tips:

  • Implement proper authorization validation at the object property level. For example, if you have a model with sensitive fields like password and role, unauthorized users should not be able to expose or modify it.

 

// Middleware to check if the user is allowed to access or modify certain properties
function checkPropertyAccess(req, res, next) {
  const userRequesting = req.user;
  const propertiesRequested = Object.keys(req.body); // Properties the user wants to access or modify
  const restrictedProperties = ['password', 'role'];
  // Check if the user is trying to access or modify restricted properties
  const isUnauthorized = propertiesRequested.some(property => restrictedProperties.includes(property) && userRequesting.role !== 'admin');
  if (isUnauthorized) {
    return res.status(403).send('You do not have permission to access or modify one or more of the requested properties.');
  }
  next(); // User has the necessary permissions
}
// Apply this middleware to routes that handle sensitive object properties
app.put('/api/user/:id', verifyToken, checkPropertyAccess, (req, res) => {
  // ...
});

 

  • Conduct regular security audits.

  • Use security-focused linters and static code analysis tools like ESLint for Node.js and Bandit for Python.

 

Broken Object Property Level Authorization

4. Unrestricted Resource Consumption

Unrestricted resource consumption threatens API availability and performance by overloading resources like CPU and memory, often through DOS attacks. For example, a successful DOS attack can overwhelm storage, increasing operational costs.

 

Remediation Tips:

  • Implement rate limiting to limit repeated requests to public APIs like password reset.

 

const rateLimit = require('express-rate-limit');
const apiLimiter = rateLimit({
  windowMs: 15 60  1000, // 15 minutes
  max: 100, // Limit each IP to 100 requests per window  (here, per 15 minutes)
  message: "Too many requests from this IP"
});
// Apply the rate limiting middleware to all API calls
app.use('/api/', apiLimiter);

 

  • Monitor for and block suspicious patterns of resource consumption. You can use tools like AWS CloudWatch and Prometheus for Kubernetes environments to set up alerts for unusual resource spikes.

 

5. Broken Function Level Authorization

Broken function level authorization occurs when inadequate access controls are defined to differentiate user permissions accurately, granting unauthorized access to sensitive functions.

 

Remediation Tips:

  • Create an identity governance framework to manage and control user identities, roles, and entitlements.

  • Implement clear and secure policies like role-based access control (RBAC) using middleware.

 

const express = require('express');
const app = express();
// Mock user roles for demonstration
const userRoles = {
  admin: ['create', 'read', 'update', 'delete'],
  editor: ['create', 'read', 'update'],
  viewer: ['read']
};
function checkAccess(req, res, next) {
  const userRole = req.user.role;
  const action = req.query.action;
  if (userRoles[userRole].includes(action)) {
    next(); // User has the role required to perform the action
  } else {
    res.status(403).send('Forbidden');
  }
}
// Use this middleware to protect routes
app.use(checkAccess);
  • Conduct periodic access control reviews.

  • Adopt the principle of least privilege.

  • Implement automated tests that check for unauthorized access attempts.

 

6. Unrestricted Access to Sensitive Business Flows

Unrestricted access to sensitive business flows allows the exploitation of business-critical APIs, such as ticket sales, leading to potential abuse and financial harm.

 

Remediation Tips:

  • Implement rate limiting on sensitive business flows.

  • Monitor for and block suspicious patterns of access to sensitive business flows.

 

7. Server Side Request Forgery (SSRF)

Server Side Request Forgery (SSRF) occurs when an API fetches a remote resource without validating the user-supplied URI. This allows an attacker to redirect requests to unintended destinations, bypassing firewalls or VPNs and leading to data security breaches or internal network exposure.

 

Remediation Tips:

  • Validate and sanitize all user-supplied URIs.

 

const url = require('url');
// List of allowed domains
const allowedDomains = ['example.com', 'api.example.com'];
function isValidUri(inputUri) {
  const parsedUri = url.parse(inputUri);
  return allowedDomains.includes(parsedUri.hostname);
}
// Usage
app.get('/fetch', (req, res) => {
  const userSuppliedUri = req.query.uri;
  if (!isValidUri(userSuppliedUri)) {
    return res.status(400).send('Invalid URI');
  }
  // Proceed with fetching the remote resource safely
});

 

  • Implement secure server configurations to prevent SSRF attacks. You can implement this by restricting outgoing requests from your server, using firewalls, or isolating services that need to make external requests.


Server Side Request Forgery (SSRF)

8. Security Misconfiguration

Security misconfigurations arise from complex or neglected settings within APIs, meant to make the APIs more customizable. These oversights can enable various attack vectors, from unauthorized data access to server takeover.

 

Remediation Tips:

  • Regularly review and update security configurations.

  • Enforce the least privilege principle.

  • Disable unnecessary features like remote database access.

  • Change all default passwords and settings.

  • Store API keys, database credentials, and other sensitive information in environment variables.

 

// Accessing an environment variable for a database password
const dbPassword = process.env.DB_PASSWORD;
// Configure your database connection using the environment variable
const dbConfig = {
  host: 'example.com',
  user: 'myuser',
  password: dbPassword,
  database: 'mydatabase'
};

 

  • Use HTTP security headers like Content-Security-Policy, X-Frame-Options, and X-Content-Type-Options.

 

app.use((req, res, next) => {
  res.setHeader('Content-Security-Policy', "default-src 'self'");
  res.setHeader('X-Frame-Options', 'DENY');
  res.setHeader('X-Content-Type-Options', 'nosniff');
  next();
});

 

9. Improper Inventory Management

Improper inventory management happens due to inadequate tracking and documentation of APIs, which often expose more endpoints than traditional applications. This deficiency can lead to outdated, unpatched systems, causing sensitive data leakages.

 

Remediation Tips:

  • Use tools like Swagger/OpenAPI for API documentation to generate live documentation that updates with your API.

  • Use an API gateway as a central control point to enforce security policies, including authentication, rate limiting, and access controls.

  • Communicate depreciation schedules to users. For example, you can include messages indicating the deprecation status and the deadline for migration in API headers.

  • Ensure critical security patches are backported.

 

10. Unsafe Consumption of APIs

Unsafe consumption of APIs is a new addition to the OWASP API Security Top 10 in 2023. Developers sometimes trust outside sources too much, not realizing they might be insecure. Attackers can take advantage of this trust to break into these connected services. A successful attack could expose private data, allow harmful data injections, or even cause service shutdowns.

 

Remediation Tips:

  • Interact with other APIs over an encrypted channel. For example, you can use Axios with Node.js.

 

const axios = require('axios');
async function fetchSecureData() {
  try {
    const response = await axios.get('https://external-api.com/data', {
      // Axios uses HTTPS by default for secure communication
    });
    console.log(response.data);
  } catch (error) {
    console.error('Error fetching data:', error);
  }
}
fetchSecureData();

 

  • Properly validate and sanitize data gathered from other APIs before processing or passing.

  • Limit the number of resources available to process third-party service responses.

  • Implement timeouts for interactions with third-party services.

 

open-appsec is an open-source project that builds on machine learning to provide pre-emptive web app & API threat protection against OWASP-Top-10 and zero-day attacks. It simplifies maintenance as there is no threat signature upkeep and exception handling, like common in many WAF solutions.


To learn more about how open-appsec works, see this White Paper and the in-depth Video Tutorial. You can also experiment with deployment in the free Playground.


Experiment with open-appsec for Linux, Kubernetes or Kong using a free virtual lab

bottom of page