API Bezbednost — Vodic za zastitu

Objavljeno: 8. april 2026. · Vreme citanja: 16 min

94%
Aplikacija ima API ranjivost (Salt Security)
681%
Porast API napada 2021-2022 (Salt)
50M
Facebook tokena kompromitovano 2018.
$6.1M
Prosecna cena API breach-a (IBM)

1. Zasto je API bezbednost kriticna

API-ji (Application Programming Interfaces) su postali kicma modernih aplikacija. Mobilne aplikacije, single-page web aplikacije, IoT uredjaji, i mikroservisi — svi komuniciraju putem API-ja. To znaci da su API-ji postali primarna meta napadaca.

Za razliku od tradicionalnih web aplikacija gde je logika na serveru, API-ji izlazu poslovnu logiku direktno. Ako API endpoint dozvolava korisniku da pristupi tudjim podacima samo promenom ID-ja u URL-u, to je kriticna ranjivost.

Kljucna cinjenica: Prema Salt Security izvestaju za 2023, 94% organizacija je dozivelo API bezbednosni incident u poslednjih 12 meseci. API napadi su porasli za 681% u periodu 2021-2022.

2. OWASP API Security Top 10 (2023)

OWASP (Open Web Application Security Project) je 2023. godine objavio azuriranu listu 10 najkriticnijih API bezbednosnih rizika:

API1:2023 — Broken Object Level Authorization (BOLA)

Najcesci API rizik. Korisnik moze pristupiti objektima drugih korisnika menjajuci ID u zahtevu. Primer: GET /api/users/123/orders — sta se desava ako promenite 123 na 456?

# Ranjiv endpoint — nema provere vlasnistva
GET /api/invoices/1001  # Korisnik A vidi svoju fakturu
GET /api/invoices/1002  # Korisnik A vidi fakturu korisnika B!

# Ispravan pristup — uvek proveravajte vlasnistvo
app.get('/api/invoices/:id', auth, async (req, res) => {
  const invoice = await Invoice.findById(req.params.id);
  if (invoice.userId !== req.user.id) {
    return res.status(403).json({ error: 'Forbidden' });
  }
  res.json(invoice);
});

API2:2023 — Broken Authentication

Slabi mehanizmi autentifikacije: nedostatak rate limiting-a na login, slabi tokeni, nezasticeni API kljucevi u kodu, ili nedostatak token expiration-a.

API3:2023 — Broken Object Property Level Authorization

Korisnik moze da cita ili modifikuje svojstva objekta koja ne bi trebalo. Primer: korisnik salje PUT zahtev i menja polje "role": "admin" u svom profilu (mass assignment).

API4:2023 — Unrestricted Resource Consumption

API nema ogranicenja na resurse: bez rate limiting-a, bez limita na velicinu payloada, bez ogranicenja na kompleksnost upita. Ovo vodi ka DoS napadima.

API5:2023 — Broken Function Level Authorization

Obican korisnik moze pristupiti admin endpoint-ima. Primer: POST /api/admin/users/delete je dostupan i obicnim korisnicima.

API6:2023 — Unrestricted Access to Sensitive Business Flows

Automatizovano zloupotrebljavanje poslovnih tokova: masovna kupovina limitiranih proizvoda, automatsko kreiranje naloga, scraping podataka.

API7:2023 — Server Side Request Forgery (SSRF)

API prihvata URL od korisnika i vrsi zahtev ka tom URL-u bez validacije. Napadac moze pristupiti internim servisima (metadata endpoint, interne baze).

API8:2023 — Security Misconfiguration

Nebezbedna podrazumevana konfiguracija: otvoren CORS, verbose error poruke, nepotrebni HTTP metodi, stare TLS verzije.

API9:2023 — Improper Inventory Management

Stare verzije API-ja ostaju aktivne i nezasticene. Shadow API-ji koje tim ne zna da postoje. Nedokumentovani endpoint-i.

API10:2023 — Unsafe Consumption of APIs

Aplikacija veruje odgovorima od third-party API-ja bez validacije. Ako provajder bude kompromitovan, vas API takodje postaje ranjiv.

3. Autentifikacija: API Keys vs OAuth 2.0 vs JWT

MetodaPrednostiManeKada koristiti
API KeysJednostavno, brzo za implementacijuNema user context, tesko za rotaciju, cesto leakujuServer-to-server, javni API-ji sa ogranicenjem
OAuth 2.0Standardizovano, delegirana autorizacija, scopesKompleksno za implementaciju, mnogi flow-oviThird-party pristup, korisnicka autorizacija
JWTStateless, sadrzi claims, efikasnoNe moze se revocirati bez blackliste, payload vidljivMikroservisi, SPA autentifikacija

4. JWT bezbednost

JWT (JSON Web Token, definisan u RFC 7519) se sastoji od tri dela: Header, Payload, i Signature, razdvojenih tackama.

# JWT struktura
eyJhbGciOiJSUzI1NiJ9.     # Header: {"alg":"RS256"}
eyJ1c2VyIjoiam9obiJ9.     # Payload: {"user":"john"}
SflKxwRJSMeKKF2QT4fw...   # Signature

# OPASNO: "none" algoritam napad
# Napadac menja header na {"alg":"none"} i uklanja potpis
eyJhbGciOiJub25lIn0.eyJ1c2VyIjoiYWRtaW4ifQ.
# Neki serveri prihvataju ovo kao validan token!

JWT bezbednosne preporuke

  • Uvek validirajte algoritam — eksplicitno navedite dozvoljene algoritme, nikada ne prihvatajte "alg": "none"
  • Koristite asimetricne algoritme — RS256 ili ES256 umesto HS256 kada vise servisa verifikuje tokene
  • Kratko vreme isteka — pristupni tokeni: 15-30 minuta, refresh tokeni: 7-30 dana
  • Proveravajte exp, iss, aud claims — ne samo potpis
  • Cuvajte tajnu kljuca — nikada u kodu, koristite environment varijable ili vault
// Node.js — bezbedna JWT verifikacija
const jwt = require('jsonwebtoken');

function verifyToken(token) {
  try {
    // Eksplicitno navedite dozvoljeni algoritam
    const decoded = jwt.verify(token, publicKey, {
      algorithms: ['RS256'],  // Samo RS256!
      issuer: 'https://auth.mojsajt.rs',
      audience: 'https://api.mojsajt.rs',
      clockTolerance: 30  // 30 sekundi tolerancije
    });
    return decoded;
  } catch (err) {
    throw new Error('Invalid token: ' + err.message);
  }
}

5. GraphQL specificni rizici

Introspection u produkciji

GraphQL introspection omogucava klijentu da upita kompletnu semu API-ja. U razvoju je korisno, ali u produkciji otkriva sve tipove, polja, relacije i mutacije napadacu.

# Introspection upit koji otkriva celu semu
{
  __schema {
    types {
      name
      fields {
        name
        type { name }
      }
    }
  }
}

# Iskljucite introspection u produkciji (Apollo Server)
const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: process.env.NODE_ENV !== 'production',
});

Depth limiting

Bez ogranicenja dubine, napadac moze poslati duboko ugnjezden upit koji preopterecuje server:

# Maliciozni upit sa preteranom dubinom
{
  user(id: 1) {
    friends {
      friends {
        friends {
          friends {
            friends { name }  # N nivoa dubine = eksponencijalna slozenost
          }
        }
      }
    }
  }
}

# Zastita: koristite graphql-depth-limit
const depthLimit = require('graphql-depth-limit');
const server = new ApolloServer({
  validationRules: [depthLimit(5)]
});

Batching napadi

GraphQL dozvoljava slanje vise upita u jednom zahtevu. Napadac moze poslati stotine login pokusaja u jednom HTTP zahtevu, zaobilazeci rate limiting koji se oslanja na broj HTTP zahteva.

6. Rate limiting implementacija

// Express.js rate limiting sa express-rate-limit
const rateLimit = require('express-rate-limit');

// Globalni limiter
const apiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,  // 15 minuta
  max: 100,                   // 100 zahteva po windowMs
  standardHeaders: true,
  legacyHeaders: false,
  message: { error: 'Too many requests, try again later' }
});

// Strozi limiter za login
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5,  // Samo 5 pokusaja logina na 15 min
  skipSuccessfulRequests: true
});

app.use('/api/', apiLimiter);
app.use('/api/auth/login', loginLimiter);

// Nginx rate limiting konfiguracija
// limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
// location /api/ {
//     limit_req zone=api burst=20 nodelay;
// }

7. Swagger/OpenAPI u produkciji

Swagger UI i OpenAPI specifikacija su odlicni za razvoj, ali u produkciji mogu otkriti kompletnu strukturu API-ja napadacu:

Opasnost: Javno dostupan /swagger, /api-docs, ili /openapi.json endpoint daje napadacu mapu svih endpoint-ova, parametara, i modela podataka. Uvek ga iskljucite ili zastitite autentifikacijom u produkciji.
// Express.js — uslovni Swagger pristup
if (process.env.NODE_ENV !== 'production') {
  const swaggerUi = require('swagger-ui-express');
  const swaggerDoc = require('./swagger.json');
  app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDoc));
}

// Ili zastitite autentifikacijom
app.use('/api-docs', basicAuth({
  users: { 'admin': process.env.SWAGGER_PASSWORD },
  challenge: true
}), swaggerUi.serve, swaggerUi.setup(swaggerDoc));

8. Realni primeri API breach-eva

Facebook API breach (septembar 2018)

Napadaci su eksploatisali ranjivost u Facebook-ovom "View As" feature-u koji je koristio API za generisanje pristupnih tokena. Ranjivost je omogucila kradju pristupnih tokena za 50 miliona korisnickih naloga. Facebook je bio prisiljen da resetuje tokene za 90 miliona korisnika.

Izvor: Facebook Security Update, septembar 2018; FTC Settlement, 2019

Peloton API (maj 2021)

Istrazivac bezbednosti Jan Masters je otkrio da je Peloton API dozvoljavao neautentifikovanim korisnicima da pristupe privatnim korisnickim podacima — ukljucujuci starost, pol, grad, tezinu, i istoriju treninga. API nije proveravao autorizaciju na endpoint-ima za korisnicke profile.

Izvor: TechCrunch, "Peloton's leaky API let anyone grab riders' private account data", maj 2021

T-Mobile API breach (avgust 2021)

Napadac je otkrio nezasticen API endpoint koji je izlagao podatke 40+ miliona korisnika ukljucujuci imena, datume rodjenja, SSN brojeve i vozacke dozvole. Napadac John Binns je tvrdio da je "njihova bezbednost uzasna".

Izvor: T-Mobile Data Breach Notice, avgust 2021

Zajednicki imenilac: U sva tri slucaja, problem je bio BOLA (Broken Object Level Authorization) — API nije proveravao da li korisnik ima pravo da pristupa trazenim podacima.

9. Cesto postavljana pitanja

P: Da li je API key dovoljan za bezbednost?
O: API key sam po sebi je samo identifikator, ne autentifikacija. Ne sadrzi informacije o korisniku, tesko se rotira, i cesto leakuje u javne Git repozitorijume. Za korisnicku autentifikaciju koristite OAuth 2.0 ili JWT.
P: Gde da cuvam JWT token na klijentu?
O: HttpOnly Secure cookie je najbezbednija opcija jer nije dostupan JavaScript-u (zastita od XSS). LocalStorage je ranjiv na XSS napade. Nikada ne cuvajte tokene u URL parametrima.
P: Kako da zastitim API od scraping-a?
O: Kombinujte rate limiting, CAPTCHA za sumnjive aktivnosti, fingerprinting korisnika, i honeypot endpoint-e. Nijedna mera sama nije dovoljna.

10. Reference

Skenirajte svoj sajt besplatno →

API Security — Protection Guide

Published: April 8, 2026 · Reading time: 16 min

94%
Apps have API vulnerability (Salt Security)
681%
API attack growth 2021-2022 (Salt)
50M
Facebook tokens compromised 2018
$6.1M
Average API breach cost (IBM)

1. Why API security is critical

APIs (Application Programming Interfaces) have become the backbone of modern applications. Mobile apps, single-page web applications, IoT devices, and microservices all communicate via APIs. This means APIs have become a primary target for attackers.

Unlike traditional web applications where logic lives on the server, APIs expose business logic directly. If an API endpoint allows a user to access another user's data simply by changing the ID in the URL, that is a critical vulnerability.

Key fact: According to Salt Security's 2023 report, 94% of organizations experienced an API security incident in the past 12 months. API attacks grew by 681% between 2021-2022.

2. OWASP API Security Top 10 (2023)

OWASP (Open Web Application Security Project) published the updated list of 10 most critical API security risks in 2023:

API1:2023 — Broken Object Level Authorization (BOLA)

The most common API risk. A user can access other users' objects by changing the ID in the request. Example: GET /api/users/123/orders — what happens if you change 123 to 456?

# Vulnerable endpoint — no ownership check
GET /api/invoices/1001  # User A sees their invoice
GET /api/invoices/1002  # User A sees User B's invoice!

# Correct approach — always check ownership
app.get('/api/invoices/:id', auth, async (req, res) => {
  const invoice = await Invoice.findById(req.params.id);
  if (invoice.userId !== req.user.id) {
    return res.status(403).json({ error: 'Forbidden' });
  }
  res.json(invoice);
});

API2:2023 — Broken Authentication

Weak authentication mechanisms: lack of rate limiting on login, weak tokens, unprotected API keys in code, or missing token expiration.

API3:2023 — Broken Object Property Level Authorization

A user can read or modify object properties they shouldn't. Example: a user sends a PUT request and changes the "role": "admin" field in their profile (mass assignment).

API4:2023 — Unrestricted Resource Consumption

API has no resource limits: no rate limiting, no payload size limits, no query complexity restrictions. This leads to DoS attacks.

API5:2023 — Broken Function Level Authorization

Regular users can access admin endpoints. Example: POST /api/admin/users/delete is accessible to regular users.

API6:2023 — Unrestricted Access to Sensitive Business Flows

Automated abuse of business flows: mass purchasing of limited products, automated account creation, data scraping.

API7:2023 — Server Side Request Forgery (SSRF)

API accepts a URL from the user and makes a request to that URL without validation. Attacker can access internal services (metadata endpoint, internal databases).

API8:2023 — Security Misconfiguration

Insecure default configuration: open CORS, verbose error messages, unnecessary HTTP methods, old TLS versions.

API9:2023 — Improper Inventory Management

Old API versions remain active and unprotected. Shadow APIs that the team doesn't know exist. Undocumented endpoints.

API10:2023 — Unsafe Consumption of APIs

Application trusts responses from third-party APIs without validation. If the provider is compromised, your API also becomes vulnerable.

3. Authentication: API Keys vs OAuth 2.0 vs JWT

MethodProsConsWhen to use
API KeysSimple, quick to implementNo user context, hard to rotate, often leakServer-to-server, public APIs with limits
OAuth 2.0Standardized, delegated authorization, scopesComplex to implement, many flowsThird-party access, user authorization
JWTStateless, contains claims, efficientCannot revoke without blacklist, payload visibleMicroservices, SPA authentication

4. JWT security

JWT (JSON Web Token, defined in RFC 7519) consists of three parts: Header, Payload, and Signature, separated by dots.

# JWT structure
eyJhbGciOiJSUzI1NiJ9.     # Header: {"alg":"RS256"}
eyJ1c2VyIjoiam9obiJ9.     # Payload: {"user":"john"}
SflKxwRJSMeKKF2QT4fw...   # Signature

# DANGEROUS: "none" algorithm attack
# Attacker changes header to {"alg":"none"} and removes signature
eyJhbGciOiJub25lIn0.eyJ1c2VyIjoiYWRtaW4ifQ.
# Some servers accept this as a valid token!

JWT security recommendations

  • Always validate the algorithm — explicitly specify allowed algorithms, never accept "alg": "none"
  • Use asymmetric algorithms — RS256 or ES256 instead of HS256 when multiple services verify tokens
  • Short expiration time — access tokens: 15-30 minutes, refresh tokens: 7-30 days
  • Check exp, iss, aud claims — not just the signature
  • Protect the secret key — never in code, use environment variables or vault
// Node.js — secure JWT verification
const jwt = require('jsonwebtoken');

function verifyToken(token) {
  try {
    // Explicitly specify the allowed algorithm
    const decoded = jwt.verify(token, publicKey, {
      algorithms: ['RS256'],  // Only RS256!
      issuer: 'https://auth.mysite.com',
      audience: 'https://api.mysite.com',
      clockTolerance: 30  // 30 seconds tolerance
    });
    return decoded;
  } catch (err) {
    throw new Error('Invalid token: ' + err.message);
  }
}

5. GraphQL specific risks

Introspection in production

GraphQL introspection allows a client to query the complete API schema. Useful in development, but in production it reveals all types, fields, relationships, and mutations to an attacker.

# Introspection query that reveals the entire schema
{
  __schema {
    types {
      name
      fields {
        name
        type { name }
      }
    }
  }
}

# Disable introspection in production (Apollo Server)
const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: process.env.NODE_ENV !== 'production',
});

Depth limiting

Without depth limits, an attacker can send a deeply nested query that overwhelms the server:

# Malicious query with excessive depth
{
  user(id: 1) {
    friends {
      friends {
        friends {
          friends {
            friends { name }  # N levels deep = exponential complexity
          }
        }
      }
    }
  }
}

# Protection: use graphql-depth-limit
const depthLimit = require('graphql-depth-limit');
const server = new ApolloServer({
  validationRules: [depthLimit(5)]
});

Batching attacks

GraphQL allows sending multiple queries in a single request. An attacker can send hundreds of login attempts in one HTTP request, bypassing rate limiting that relies on HTTP request count.

6. Rate limiting implementation

// Express.js rate limiting with express-rate-limit
const rateLimit = require('express-rate-limit');

// Global limiter
const apiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,  // 15 minutes
  max: 100,                   // 100 requests per windowMs
  standardHeaders: true,
  legacyHeaders: false,
  message: { error: 'Too many requests, try again later' }
});

// Stricter limiter for login
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5,  // Only 5 login attempts per 15 min
  skipSuccessfulRequests: true
});

app.use('/api/', apiLimiter);
app.use('/api/auth/login', loginLimiter);

// Nginx rate limiting configuration
// limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
// location /api/ {
//     limit_req zone=api burst=20 nodelay;
// }

7. Swagger/OpenAPI in production

Swagger UI and OpenAPI specification are great for development, but in production they can reveal the complete API structure to an attacker:

Danger: A publicly accessible /swagger, /api-docs, or /openapi.json endpoint gives an attacker a map of all endpoints, parameters, and data models. Always disable or protect it with authentication in production.
// Express.js — conditional Swagger access
if (process.env.NODE_ENV !== 'production') {
  const swaggerUi = require('swagger-ui-express');
  const swaggerDoc = require('./swagger.json');
  app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDoc));
}

// Or protect with authentication
app.use('/api-docs', basicAuth({
  users: { 'admin': process.env.SWAGGER_PASSWORD },
  challenge: true
}), swaggerUi.serve, swaggerUi.setup(swaggerDoc));

8. Real-world API breach examples

Facebook API breach (September 2018)

Attackers exploited a vulnerability in Facebook's "View As" feature which used an API to generate access tokens. The vulnerability enabled theft of access tokens for 50 million user accounts. Facebook was forced to reset tokens for 90 million users.

Source: Facebook Security Update, September 2018; FTC Settlement, 2019

Peloton API (May 2021)

Security researcher Jan Masters discovered that Peloton's API allowed unauthenticated users to access private user data — including age, gender, city, weight, and workout history. The API did not check authorization on user profile endpoints.

Source: TechCrunch, "Peloton's leaky API let anyone grab riders' private account data", May 2021

T-Mobile API breach (August 2021)

An attacker discovered an unprotected API endpoint exposing data of 40+ million customers including names, dates of birth, SSN numbers, and driver's licenses. Attacker John Binns claimed "their security is awful."

Source: T-Mobile Data Breach Notice, August 2021

Common thread: In all three cases, the problem was BOLA (Broken Object Level Authorization) — the API did not verify whether the user had the right to access the requested data.

9. Frequently asked questions

Q: Is an API key sufficient for security?
A: An API key by itself is just an identifier, not authentication. It contains no user information, is hard to rotate, and often leaks into public Git repositories. For user authentication, use OAuth 2.0 or JWT.
Q: Where should I store JWT tokens on the client?
A: An HttpOnly Secure cookie is the safest option because it is not accessible to JavaScript (XSS protection). LocalStorage is vulnerable to XSS attacks. Never store tokens in URL parameters.
Q: How do I protect my API from scraping?
A: Combine rate limiting, CAPTCHA for suspicious activity, user fingerprinting, and honeypot endpoints. No single measure is sufficient on its own.

10. References

Scan your site for free →