← Back to list

API Security Explained: 7 Proven Techniques to Protect Your APIs

APIs are like doors to your system. Every endpoint you expose is an entry point; a door that lets clients in to access data, trigger…

bernard bebeni in Towards Dev · 2026-09-10 12:44 · 0 claps · 3.6 min read
#api-security #web-development #cybersecurity #backend-development #software-engineering
Open on Medium ↗
Wiki topics: FT · Fine-tuning & Adaptation 🌐 · Web Development 🔒 · Cybersecurity

API Security Explained: 7 Proven Techniques to Protect Your APIs

APIs are like doors to your system. Every endpoint you expose is an entry point; a door that lets clients in to access data, trigger actions, and interact with your services. But if you leave these doors unprotected, attackers can walk right in.

This article covers 7 proven techniques to secure your APIs against the most common and dangerous threats. Whether you’re building a startup MVP or running enterprise-grade infrastructure, these defenses form the foundation of any solid API security strategy.

The Big Picture: API Security at a Glance

The diagram above shows the typical path a request takes through your security layers. Each layer adds a level of protection, creating a defense-in-depth architecture. Let’s break down each one.

1. Rate Limiting

The Problem

Imagine someone knocking on your door 10,000 times per second. That’s essentially what a DDoS attack does to your API. Without rate limiting, a single attacker can overwhelm your servers, brute-force passwords, or scrape your entire database.

How It Works

Rate limiting controls how many requests a client can make within a specific timeframe. Think of it as a bouncer at a club ; once you’ve hit your limit, you have to wait before making more requests.

Types of Rate Limits

Rate limits can be applied at different granularities depending on your needs:

When a client exceeds the rate limit, return HTTP 429 Too Many Requests with a Retry-After header so well-behaved clients know when to try again.

Example

A typical setup might allow:

  • 100 requests per minute per user for general API calls
  • 5 requests per minute for login attempts (to prevent brute-force attacks)
  • 1,000 requests per minute for read-only endpoints

2. CORS (Cross-Origin Resource Sharing)

The Problem

Browsers enforce a security policy called the Same-Origin Policy (SOP). This means a web page at https://my-app.com cannot freely read data from https://api.other-site.com. This is a good thing; it prevents malicious websites from silently reading your data from other services.

But what if your own frontend at https://my-app.com legitimately needs to call your API at https://api.my-app.com? That's where CORS comes in.

How It Works

CORS eases the Same-Origin Policy in a controlled way. The server specifies which origins can access its resources by including specific HTTP headers in its responses.

CORS is a browser-level mechanism, not a backend security layer. It only protects browser-based requests. Tools like curl or Postman ignore CORS entirely. Never rely on CORS as your sole security defense. It supplements authentication and authorization; it doesn't replace them.

Never use Access-Control-Allow-Origin: * combined with Access-Control-Allow-Credentials: true. This allows any website on the internet to make authenticated requests to your API on behalf of your users.

3. SQL Injection

The Problem

SQL injection is one of the oldest and most devastating attack vectors. It occurs when untrusted user input is directly inserted into a database query, allowing the attacker to manipulate the query and potentially read, modify, or delete your entire database.

How the Attack Works

Consider a login form that takes a username and builds a SQL query like this:

SELECT * FROM users WHERE username = '{user_input}' AND password = '{password_input}'

A normal user types bernard, producing:

SELECT * FROM users WHERE username = 'bernard' AND password = 'secret123'

But an attacker types: ' OR '1'='1' --

SELECT * FROM users WHERE username = '' OR '1'='1' --' AND password = ''

Since '1'='1' is always true, this returns all users; effectively bypassing authentication entirely.

The Fix: Parameterized Queries

Always use parameterized queries (prepared statements). This ensures the database treats user input strictly as data, never as executable code.

-- DANGEROUS: String concatenation
query = "SELECT * FROM users WHERE name = '" + user_input + "'"

-- SAFE: Parameterized query
query = "SELECT * FROM users WHERE name = ?"
execute(query, [user_input])

메타데이터
post_id
021e6e10d2a9
slug
api-security-explained-7-proven-techniques-to-protect-your-apis-021e6e10d2a9
url
https://towardsdev.com/api-security-explained-7-proven-techniques-to-protect-your-apis-021e6e10d2a9
canonical_url
https://towardsdev.com/api-security-explained-7-proven-techniques-to-protect-your-apis-021e6e10d2a9
author_url
https://medium.com/@bernardbebeni
status
ok
fetched_at
2026-09-12 14:57:28