API Security 2025
API'ler modern uygulamaların bel kemiği. Güvenlik açıkları kritik risk oluşturuyor. Kapsamlı API güvenlik rehberi.
OWASP API Security Top 10
- Broken Object Level Authorization - En yaygın
- Broken Authentication
- Broken Object Property Level Authorization
- Unrestricted Resource Consumption
- Broken Function Level Authorization
- Unrestricted Access to Sensitive Business Flows
- Server Side Request Forgery (SSRF)
- Security Misconfiguration
- Improper Inventory Management
- Unsafe Consumption of APIs
Authentication & Authorization
OAuth 2.0 Flow
// Authorization Code Flow
app.get('/auth', (req, res) => {
const authUrl = `https://oauth.provider.com/authorize?
client_id=${CLIENT_ID}&
redirect_uri=${REDIRECT_URI}&
response_type=code&
scope=read write&
state=${generateState()}`;
res.redirect(authUrl);
});
app.get('/callback', async (req, res) => {
const { code, state } = req.query;
// Verify state (CSRF protection)
if (!verifyState(state)) {
return res.status(401).send('Invalid state');
}
// Exchange code for token
const tokens = await exchangeCodeForToken(code);
// Store tokens securely
storeTokens(tokens);
res.redirect('/dashboard');
});
JWT (JSON Web Tokens)
const jwt = require('jsonwebtoken');
// Generate JWT
function generateToken(user) {
return jwt.sign(
{
sub: user.id,
email: user.email,
role: user.role
},
process.env.JWT_SECRET,
{
expiresIn: '1h',
issuer: 'api.example.com',
audience: 'example.com'
}
);
}
// Verify JWT
function verifyToken(token) {
try {
return jwt.verify(token, process.env.JWT_SECRET, {
issuer: 'api.example.com',
audience: 'example.com'
});
} catch (error) {
throw new Error('Invalid token');
}
}
// Middleware
function authenticateJWT(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
try {
const decoded = verifyToken(token);
req.user = decoded;
next();
} catch (error) {
return res.status(403).json({ error: 'Invalid token' });
}
}
Rate Limiting
const rateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');
const redis = require('redis');
const client = redis.createClient();
// Global rate limit
const globalLimiter = rateLimit({
store: new RedisStore({ client }),
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // 100 requests per window
message: 'Too many requests, please try again later'
});
// Endpoint-specific rate limit
const strictLimiter = rateLimit({
store: new RedisStore({ client }),
windowMs: 60 * 1000, // 1 minute
max: 5, // 5 requests per minute
message: 'Rate limit exceeded'
});
// Apply
app.use('/api/', globalLimiter);
app.post('/api/login', strictLimiter, loginHandler);
Input Validation
const Joi = require('joi');
// Validation schema
const userSchema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(8).pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/).required(),
age: Joi.number().integer().min(18).max(120),
username: Joi.string().alphanum().min(3).max(30).required()
});
// Validate middleware
function validateUser(req, res, next) {
const { error, value } = userSchema.validate(req.body);
if (error) {
return res.status(400).json({
error: 'Validation failed',
details: error.details.map(d => d.message)
});
}
req.validatedData = value;
next();
}
app.post('/api/users', validateUser, createUser);
API Gateway Security
# Kong API Gateway configuration
services:
- name: user-service
url: http://user-service:8080
plugins:
# Authentication
- name: jwt
config:
secret_is_base64: false
key_claim_name: kid
# Rate limiting
- name: rate-limiting
config:
minute: 100
hour: 1000
policy: redis
# IP restriction
- name: ip-restriction
config:
whitelist:
- 10.0.0.0/8
- 172.16.0.0/12
# CORS
- name: cors
config:
origins:
- https://app.example.com
credentials: true
max_age: 3600
GraphQL Security
const { ApolloServer } = require('apollo-server');
const depthLimit = require('graphql-depth-limit');
const { createComplexityLimitRule } = require('graphql-validation-complexity');
const server = new ApolloServer({
typeDefs,
resolvers,
// Query depth limiting
validationRules: [
depthLimit(10), // Max query depth: 10
createComplexityLimitRule(1000) // Max complexity: 1000
],
// Disable introspection in production
introspection: process.env.NODE_ENV !== 'production',
playground: process.env.NODE_ENV !== 'production',
// Context with auth
context: ({ req }) => {
const token = req.headers.authorization;
const user = verifyToken(token);
return { user };
},
// Error handling
formatError: (error) => {
// Don't expose internal errors
if (error.message.startsWith('Database')) {
return new Error('Internal server error');
}
return error;
}
});
API Security Testing
# OWASP ZAP API scan
zap-cli quick-scan --spider -r https://api.example.com
# Postman security tests
pm.test("No sensitive data in response", function () {
pm.expect(pm.response.text()).to.not.include("password");
pm.expect(pm.response.text()).to.not.include("secret");
});
pm.test("Proper auth required", function () {
pm.sendRequest({
url: pm.environment.get("API_URL") + "/admin",
method: "GET"
}, function (err, res) {
pm.expect(res.code).to.equal(401);
});
});
Best Practices Checklist
✅ Authentication:
- [ ] OAuth2/OpenID Connect
- [ ] JWT with short expiration
- [ ] Refresh token rotation
- [ ] MFA for sensitive operations
✅ Authorization:
- [ ] Role-based access control (RBAC)
- [ ] Object-level authorization checks
- [ ] Principle of least privilege
✅ Data:
- [ ] Input validation (whitelist)
- [ ] Output encoding
- [ ] Encryption (TLS 1.3)
- [ ] Sensitive data filtering
✅ Rate Limiting:
- [ ] Per-IP limits
- [ ] Per-user limits
- [ ] Per-endpoint limits
- [ ] Distributed rate limiting (Redis)
✅ Monitoring:
- [ ] Logging all API calls
- [ ] Alert on anomalies
- [ ] API analytics
- [ ] Security event correlation
API security danışmanlığı: iletisim@cesayazilim.com 🔐