API Security Checklist for Indian Fintech
India's fintech revolution is built on APIs. UPI, BBPS, Account Aggregator, ONDC — every major financial innovation is API-first. But with great connectivity comes great responsibility. Indian fintech APIs process over ₹100 lakh crore annually, and they're under constant attack.
Having assessed APIs for multiple Indian fintech companies, I've compiled this comprehensive security checklist. It's organized by priority and maps to both OWASP API Top 10 and RBI's cybersecurity framework.
- ₹100+ lakh crore — annual value processed through Indian fintech APIs
- 94% of fintech apps tested had at least one critical API vulnerability (Bachao.AI internal data)
- BOLA (Broken Object Level Authorization) found in 68% of Indian fintech APIs tested
- 43% of Indian fintech APIs lack proper rate limiting
- 6 hours — CERT-In mandatory incident reporting time for financial sector
The Fintech API Threat Landscape
flowchart TD
A[Fintech API Threats] --> B[Authentication Attacks]
A --> C[Authorization Flaws]
A --> D[Data Exposure]
A --> E[Injection Attacks]
A --> F[Rate Limiting Bypass]
B --> B1[Brute Force OTP]
B --> B2[JWT Manipulation]
B --> B3[Session Fixation]
C --> C1[BOLA/IDOR]
C --> C2[Privilege Escalation]
C --> C3[Function Level Access]
D --> D1[Excessive Data in Response]
D --> D2[PII in Logs]
D --> D3[Debug Endpoints Exposed]
E --> E1[SQL Injection]
E --> E2[NoSQL Injection]
E --> E3[Command Injection]
F --> F1[OTP Flood]
F --> F2[Transaction Replay]
F --> F3[Account Enumeration]
The Checklist
Section 1: Authentication & Session Management
| # | Check | Priority | OWASP API | Status |
|---|
| 1.1 | OAuth 2.0 / OpenID Connect for user auth | Critical | API2 | ☐ |
| 1.2 | JWT tokens signed with RS256 (not HS256) | Critical | API2 | ☐ |
| 1.3 | Token expiry ≤ 15 minutes for access tokens | High | API2 | ☐ |
| 1.4 | Refresh token rotation on every use | High | API2 | ☐ |
| 1.5 | OTP rate limiting (max 5 attempts per 10 min) | Critical | API4 | ☐ |
| 1.6 | OTP expiry ≤ 5 minutes | High | API2 | ☐ |
| 1.7 | No OTP in API response body | Critical | API3 | ☐ |
| 1.8 | API key rotation mechanism in place | Medium | API2 | ☐ |
| 1.9 | Multi-factor auth for high-value transactions | High | API2 | ☐ |
| 1.10 | Session invalidation on password change | High | API2 | ☐ |
🛡️SECURITYThe #1 fintech API vulnerability in India: OTP in API response. I've seen this in at least 30% of Indian fintech apps. The server sends the OTP back in the HTTP response body during the verification flow, thinking the frontend needs it for "validation." An attacker just reads the response and bypasses OTP entirely.
bash# BAD: OTP returned in response
POST /api/auth/send-otp
Response: {"status": "sent", "otp": "482910"} # NEVER DO THIS
# GOOD: Only status returned
POST /api/auth/send-otp
Response: {"status": "sent", "expiresIn": 300}
Section 2: Authorization (BOLA/IDOR Prevention)
| # | Check | Priority | OWASP API | Status |
|---|
| 2.1 | Object-level authorization on every endpoint | Critical | API1 | ☐ |
| 2.2 | Use UUIDs instead of sequential IDs | High | API1 | ☐ |
| 2.3 | Server-side ownership validation | Critical | API1 | ☐ |
| 2.4 | Function-level access control (admin vs user) | Critical | API5 | ☐ |
| 2.5 | No horizontal privilege escalation possible | Critical | API1 | ☐ |
typescript// BAD: No authorization check
app.get('/api/transactions/:id', async (req, res) => {
const transaction = await db.findTransaction(req.params.id);
res.json(transaction); // Any user can see any transaction!
});
// GOOD: Authorization check
app.get('/api/transactions/:id', async (req, res) => {
const transaction = await db.findTransaction(req.params.id);
if (transaction.userId !== req.user.id) {
return res.status(403).json({ error: 'Forbidden' });
}
res.json(transaction);
});
⚠️WARNINGBOLA (Broken Object Level Authorization) is the #1 vulnerability in the OWASP API Top 10 for a reason. In fintech, this means User A can see User B's transactions, balance, KYC documents, or even initiate transfers. Always validate that the requesting user owns the resource.
| # | Check | Priority | OWASP API | Status |
|---|
| 3.1 | Schema validation on all inputs (Zod/Joi) | Critical | API8 | ☐ |
| 3.2 | Amount fields validated as positive numbers | Critical | API8 | ☐ |
| 3.3 | UPI ID format validation (regex) | High | API8 | ☐ |
| 3.4 | PAN/Aadhaar format validation | High | API8 | ☐ |
| 3.5 | File upload type and size validation | High | API8 | ☐ |
| 3.6 | SQL parameterized queries (no string concat) | Critical | API8 | ☐ |
| 3.7 | NoSQL injection prevention | High | API8 | ☐ |
| 3.8 | Request body size limits | Medium | API4 | ☐ |
typescript// Input validation example with Zod (recommended for Indian fintech)
import { z } from 'zod';
const transferSchema = z.object({
amount: z.number()
.positive('Amount must be positive')
.max(500000, 'Single transaction limit exceeded') // RBI UPI limit
.multipleOf(0.01, 'Invalid decimal places'),
upiId: z.string()
.regex(/^[a-zA-Z0-9._-]+@[a-zA-Z0-9]+$/, 'Invalid UPI ID format'),
note: z.string()
.max(50, 'Note too long')
.regex(/^[a-zA-Z0-9\s]+$/, 'Special characters not allowed'),
pin: z.string()
.length(6, 'PIN must be 6 digits')
.regex(/^\d{6}$/, 'PIN must be numeric'),
});
Section 4: Rate Limiting & Throttling
| # | Check | Priority | OWASP API | Status |
|---|
| 4.1 | Global rate limit per IP | Critical | API4 | ☐ |
| 4.2 | Per-user rate limit for authenticated endpoints | Critical | API4 | ☐ |
| 4.3 | Stricter limits on auth endpoints (login/OTP) | Critical | API4 | ☐ |
| 4.4 | Transaction amount-based throttling | High | API4 | ☐ |
| 4.5 | Rate limit headers in response | Medium | API4 | ☐ |
| 4.6 | Exponential backoff on auth failures | High | API4 | ☐ |
bash# Recommended rate limits for fintech APIs:
# Authentication endpoints
/api/auth/send-otp → 5 requests per 10 minutes per phone
/api/auth/verify-otp → 5 attempts per OTP per phone
/api/auth/login → 10 requests per minute per IP
# Transaction endpoints
/api/transfer → 30 per hour per user
/api/beneficiary/add → 5 per day per user
# Query endpoints
/api/balance → 60 per minute per user
/api/transactions → 30 per minute per user
💡TIPUse Redis-backed rate limiting, not in-memory counters. In a multi-instance deployment (which every fintech should have), in-memory counters don't share state across instances. An attacker can simply rotate between instances to bypass limits.
Section 5: Data Exposure Prevention
| # | Check | Priority | OWASP API | Status |
|---|
| 5.1 | No PII in URL parameters | Critical | API3 | ☐ |
| 5.2 | Mask Aadhaar (show last 4 digits only) | Critical | API3 | ☐ |
| 5.3 | Mask PAN (show first and last 2 chars) | Critical | API3 | ☐ |
| 5.4 | No sensitive data in logs | Critical | API3 | ☐ |
| 5.5 | API responses return only required fields | High | API3 | ☐ |
| 5.6 | Encrypt sensitive fields at rest (AES-256) | High | API3 | ☐ |
| 5.7 | TLS 1.2+ enforced on all endpoints | Critical | API7 | ☐ |
typescript// Data masking utility for Indian fintech
const mask = {
aadhaar: (num: string) => 'XXXX-XXXX-' + num.slice(-4),
pan: (pan: string) => pan.slice(0, 2) + 'XXXXXX' + pan.slice(-2),
phone: (phone: string) => 'XXXXX' + phone.slice(-5),
email: (email: string) => {
const [user, domain] = email.split('@');
return user[0] + '***@' + domain;
},
account: (acc: string) => 'XXXXXXXXXX' + acc.slice(-4),
upi: (upi: string) => upi.split('@')[0].slice(0, 2) + '***@' + upi.split('@')[1],
};
// Usage in API response
res.json({
name: user.name,
aadhaar: mask.aadhaar(user.aadhaar), // XXXX-XXXX-4589
pan: mask.pan(user.pan), // AB XXXXXX9Z
phone: mask.phone(user.phone), // XXXXX67890
});
Section 6: Logging & Monitoring (RBI/CERT-In Compliance)
| # | Check | Priority | Regulation | Status |
|---|
| 6.1 | Log all authentication attempts | Critical | RBI | ☐ |
| 6.2 | Log all transaction API calls | Critical | RBI | ☐ |
| 6.3 | Log all admin actions | Critical | RBI | ☐ |
| 6.4 | No sensitive data in logs (PII, tokens) | Critical | DPDP | ☐ |
| 6.5 | Log retention ≥ 180 days | High | CERT-In | ☐ |
| 6.6 | Tamper-proof log storage | High | RBI | ☐ |
| 6.7 | Real-time alerting on anomalies | High | RBI | ☐ |
| 6.8 | 6-hour incident reporting capability | Critical | CERT-In | ☐ |
sequenceDiagram
participant User
participant API
participant Logger
participant SIEM
participant Alert
User->>API: POST /api/transfer
API->>Logger: Log request (masked PII)
API->>API: Process transaction
API->>Logger: Log response + status
Logger->>SIEM: Forward logs
SIEM->>SIEM: Anomaly detection
alt Anomaly Detected
SIEM->>Alert: Trigger alert
Alert->>Alert: Notify security team
end
API-->>User: Response
Section 7: Infrastructure Security
| # | Check | Priority | Status |
|---|
| 7.1 | API gateway with WAF enabled | Critical | ☐ |
| 7.2 | DDoS protection (CloudFlare/AWS Shield) | Critical | ☐ |
| 7.3 | Separate API domain (api.yourdomain.com) | High | ☐ |
| 7.4 | API versioning (/v1/, /v2/) | Medium | ☐ |
| 7.5 | Health/debug endpoints not publicly accessible | Critical | ☐ |
| 7.6 | CORS configured for specific origins only | High | ☐ |
| 7.7 | API documentation not publicly accessible | Medium | ☐ |
ℹ️INFORBI's cybersecurity framework mandates that all regulated entities must conduct VAPT assessments at least once a year for critical systems. For fintech operating under PPI, NBFC, or payment aggregator licenses, API security testing is not optional — it's a regulatory requirement.
Know your vulnerabilities before attackers do
Run a free VAPT scan — takes 5 minutes, no signup required.
Book Your Free Scan
RBI Compliance Mapping
| RBI Requirement | API Security Measure |
|---|
| Strong authentication | OAuth 2.0 + MFA for high-value transactions |
| Transaction monitoring | Real-time API logging + anomaly detection |
| Data encryption | TLS 1.2+ in transit, AES-256 at rest |
| Access control | RBAC + object-level authorization |
| Incident reporting | 6-hour CERT-In notification pipeline |
| Audit trail | Immutable API request/response logs |
| Vendor risk management | Third-party API security assessment |
Key Takeaways:
- BOLA/IDOR is the #1 fintech API vulnerability — check every endpoint for authorization
- Never return OTP in the API response — this is shockingly common in Indian fintech
- Implement Redis-backed rate limiting — in-memory counters fail in multi-instance deployments
- Mask all PII in API responses — Aadhaar, PAN, phone numbers, account numbers
- Log everything but log safely — no PII in logs, 180-day retention for CERT-In
- RBI mandates annual VAPT for regulated entities — API testing is a regulatory requirement
- Use schema validation (Zod/Joi) on every input — never trust the client
Building a fintech product? Get a free API security assessment from Bachao.AI — we test against OWASP API Top 10 and RBI compliance requirements.