Güvenlik Best Practices
Production ortamı için Atlantic ID entegrasyonunda güvenlik kontrolü.
Pre-Production Checklist
✅ PKCE
- [ ] Public client'larda PKCE zorunlu
- [ ]
S256method kullanılıyor (plain değil) - [ ] Her request için yeni verifier
- [ ] Verifier güvenli saklanıyor
✅ State & Nonce
- [ ] State parametresi kullanılıyor (CSRF)
- [ ] State server-side/session'da saklanıyor
- [ ] Nonce kullanılıyor (ID token replay)
- [ ] Kriptografik random generator
✅ HTTPS
- [ ] Production'da sadece HTTPS
- [ ] Valid SSL certificate
- [ ] Redirect URI'ler HTTPS (localhost hariç)
- [ ] TLS 1.2+ kullanılıyor
✅ Token Storage
- [ ] Backend'de güvenli session storage
- [ ] Frontend'de httpOnly cookie
- [ ] LocalStorage KULLANILMIYOR
- [ ] Token'lar asla URL'de değil
✅ Token Validation
- [ ] ID token backend'de doğrulanıyor
- [ ] İmza kontrol ediliyor (JWKS)
- [ ] iss, aud, exp validate ediliyor
- [ ] Client-side decode asla güvenilmiyor
✅ Client Secret (Confidential)
- [ ] Secret environment variable'da
- [ ] Git'e commit edilmemiş
- [ ] Frontend'de yok
- [ ] Production/dev farklı secret'lar
✅ Redirect URIs
- [ ] Tüm URI'ler console'da kayıtlı
- [ ] Wildcard yok (
https://*.example.com❌) - [ ] Exact match (trailing slash dikkat)
- [ ] Open redirect vulnerability yok
✅ Scope Minimization
- [ ] Sadece gerekli scope'lar isteniyor
- [ ]
offline_accessgerçekten gerekli mi? - [ ] Kullanıcıya açık bilgilendirme
Common Vulnerabilities
1. Authorization Code Interception
Risk: Code URL'de yakalanabilir
Korunma:
- ✅ PKCE kullan
- ✅ HTTPS zorunlu
- ✅ Short-lived codes (5 dk)
2. CSRF Attack
Risk: Saldırgan kendi code'unu kurbanın session'ına bağlayabilir
Korunma:
- ✅ State parametresi
- ✅ State server-side validate et
- ✅ SameSite cookie attribute
3. Open Redirect
Risk: redirect_uri manipulation
Korunma:
- ✅ Exact match kontrolü
- ✅ Whitelist approach
- ✅ No wildcard URIs
4. Token Leakage
Risk: Token'lar log'lara, referrer'a düşebilir
Korunma:
- ✅ Never in URL/query params
- ✅ Never in localStorage
- ✅ httpOnly, secure cookies
- ✅ Short-lived access tokens
5. XSS Attacks
Risk: JavaScript ile token çalınması
Korunma:
- ✅ httpOnly cookies
- ✅ Content Security Policy
- ✅ Input sanitization
- ✅ Modern framework kullan (React, Vue)
6. Replay Attacks
Risk: Eski token'ların yeniden kullanılması
Korunma:
- ✅ Nonce (ID token'da)
- ✅ Short token lifetime
- ✅ Token rotation (refresh)
Token Security
Access Token
Storage:
// ✅ Good: httpOnly cookie
res.cookie('access_token', token, {
httpOnly: true,
secure: true, // HTTPS only
sameSite: 'lax',
maxAge: 900000 // 15 min
});
// ❌ Bad: localStorage
localStorage.setItem('access_token', token);
Usage:
// ✅ Good: Backend sends in header
fetch('/api/data', {
credentials: 'include' // Sends cookie
});
// ❌ Bad: Frontend manually sends
fetch('/api/data', {
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
});
Refresh Token
Rules:
- Server-side only (asla frontend'e verme)
- Database'de hash'lenmiş sakla
- Rotation kullan (her kullanımda yenile)
- Revocation mekanizması
Example:
// ✅ Good
app.post('/api/refresh', async (req, res) => {
const refreshToken = req.session.refreshToken;
// Validate & exchange
const tokens = await atlanticId.refresh(refreshToken);
// Save new refresh token
req.session.refreshToken = tokens.refresh_token;
// Send new access token
res.cookie('access_token', tokens.access_token, {
httpOnly: true,
secure: true,
maxAge: 900000
});
});
Client Secret Protection
Environment Variables
// ✅ Good
const CLIENT_SECRET = process.env.ATLANTIC_ID_SECRET;
// ❌ Bad
const CLIENT_SECRET = 'sec_abc123def456';
.env File
# .env
ATLANTIC_ID_CLIENT_ID=cli_abc123
ATLANTIC_ID_CLIENT_SECRET=sec_def456
ATLANTIC_ID_REDIRECT_URI=https://myapp.com/callback
.gitignore:
.env
.env.local
.env.production
Secret Rotation
- Developer Console'da yeni secret oluştur
- Her iki secret da geçici olarak çalışır
- Tüm instancelarda yeni secret'a geç
- Eski secret'ı devre dışı bırak
Session Management
Session Security
// Express.js
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: true, // HTTPS only
httpOnly: true,
sameSite: 'lax',
maxAge: 86400000 // 24 hours
},
store: new RedisStore({ /* ... */ })
}));
Session Fixation Prevention
// After successful login
req.session.regenerate((err) => {
req.session.userId = user.id;
});
CORS Configuration
// ✅ Good: Whitelist
app.use(cors({
origin: [
'https://myapp.com',
'https://www.myapp.com'
],
credentials: true
}));
// ❌ Bad: Allow all
app.use(cors({
origin: '*',
credentials: true // Bu çalışmaz zaten
}));
Rate Limiting
Application Level
const rateLimit = require('express-rate-limit');
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 min
max: 5, // 5 attempts
message: 'Too many login attempts'
});
app.post('/auth/callback', authLimiter, handleCallback);
Atlantic ID Level
Atlantic ID otomatik rate limiting uygular:
- 100 req/min auth endpoints
- 50 req/min token endpoint
- 429 response → exponential backoff
Logging & Monitoring
What to Log
✅ Log:
- Login attempts (success/fail)
- Token refresh events
- Logout events
- Failed verifications
- Rate limit hits
❌ Never Log:
- Access tokens
- Refresh tokens
- ID tokens
- Client secrets
- Authorization codes
- PKCE verifiers
Example
logger.info('User login', {
userId: user.sub,
clientId: 'cli_abc123',
timestamp: Date.now(),
// NO TOKENS!
});
Production Deployment
Pre-Launch
- [ ] Security audit yapıldı
- [ ] Penetration test yapıldı
- [ ] SSL certificate geçerli
- [ ] Secrets rotate edildi (dev→prod)
- [ ] Rate limiting test edildi
- [ ] Error handling test edildi
- [ ] Monitoring kuruldu
- [ ] Backup/recovery planı var
Post-Launch
- Monitor logs daily
- Review access patterns
- Track failed auth attempts
- Update dependencies
- Rotate secrets quarterly
Security Headers
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
connectSrc: ["'self'", "https://id.codeatlantis.com"]
}
},
hsts: {
maxAge: 31536000,
includeSubDomains: true
}
}));
Incident Response
Token Compromised
-
Immediate:
- Revoke all tokens for affected user
- Force re-authentication
- Log incident
-
Investigation:
- Check access logs
- Identify breach source
- Assess damage
-
Remediation:
- Rotate client secrets
- Update security measures
- Notify affected users (if required)
Code
// Revoke all user tokens
await atlanticId.revokeAllUserTokens(userId);
// Force logout
req.session.destroy();
// Log
logger.error('Token compromise detected', {
userId,
clientId,
timestamp: Date.now()
});
Compliance
KVKK / GDPR
- [ ] Kullanıcı onayı alınıyor
- [ ] Data minimization (scope)
- [ ] User data deletion API
- [ ] Privacy policy link
- [ ] Terms of service
PCI DSS (Eğer ödeme varsa)
- [ ] Token'lar encrypted
- [ ] Access logs tutluyor
- [ ] Regular security audits
- [ ] Incident response plan
Useful Tools
Testing
- OWASP ZAP - Security scanner
- Burp Suite - Web vulnerability scanner
- jwt.io - JWT debugger
Monitoring
- Sentry - Error tracking
- DataDog - APM & monitoring
- CloudFlare - DDoS protection
Sorunuz mu var? developers@codeatlantis.com