Skip to main content

Security Overview

This guide covers security best practices for integrating with the TxnCheck API, protecting your API keys, and handling sensitive data.

Security Architecture

Key Security Principles

Defense in Depth

Multiple layers of security controls to protect against various attack vectors

Least Privilege

Grant minimum necessary permissions for API keys and service accounts

Zero Trust

Verify every request, even from internal systems

Audit Everything

Log all API interactions for compliance and incident response

Authentication Security

API Key Protection

Your API key grants access to paid services and sensitive verification data. Treat it like a password.
Do:
  • Store API keys in a secrets manager (AWS Secrets Manager, HashiCorp Vault, etc.)
  • Use environment variables, never hardcode keys
  • Rotate keys periodically (every 90 days recommended)
  • Use separate keys for development, staging, and production
Don’t:
  • Commit API keys to version control
  • Share keys via email or chat
  • Log API keys in application logs
  • Expose keys in client-side code
// ✅ Good: Load from environment
const client = new TxnCheckClient({
  apiKey: process.env.FRAUD_BUSTER_API_KEY!,
});

// ❌ Bad: Hardcoded key
const client = new TxnCheckClient({
  apiKey: 'fb_live_abc123xyz',
});
Enable HMAC-SHA256 request signing for additional security:
const client = new TxnCheckClient({
  apiKey: process.env.FRAUD_BUSTER_API_KEY!,
  secretKey: process.env.FRAUD_BUSTER_SECRET_KEY!, // For signing
});
Request signing provides:
  • Integrity: Ensures request wasn’t modified in transit
  • Replay Protection: Timestamp prevents replay attacks
  • Non-repudiation: Proves request originated from your system

Transport Security

HTTPS Requirements

All API communication must use HTTPS with TLS 1.2 or higher:
// The SDK enforces HTTPS by default
const client = new TxnCheckClient({
  apiKey: process.env.FRAUD_BUSTER_API_KEY!,
  baseUrl: 'https://api.txncheck.in/api/v1', // HTTPS required
});

Certificate Validation

Always validate SSL certificates:
// ✅ Good: Default behavior - validates certificates
const response = await fetch(url);

// ❌ Bad: Disabling certificate validation
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // Never do this!

Input Validation

Always validate input before sending to the API:
// Validate mobile number format
function validateMobile(mobile: string): boolean {
  return /^\+91\d{10}$/.test(mobile);
}

// Validate VPA format
function validateVPA(vpa: string): boolean {
  return /^[a-zA-Z0-9._-]+@[a-zA-Z0-9]+$/.test(vpa);
}

// Use validation before API calls
if (!validateMobile(userInput.mobile)) {
  throw new ValidationError('Invalid mobile number format');
}

const result = await client.upiByMobile(userInput.mobile, { sync: true });

Rate Limiting

Implement client-side rate limiting to avoid hitting API limits:
import Bottleneck from 'bottleneck';

const limiter = new Bottleneck({
  reservoir: 100, // Initial tokens
  reservoirRefreshAmount: 100, // Refill amount
  reservoirRefreshInterval: 60 * 1000, // Refill every minute
  maxConcurrent: 5, // Max concurrent requests
});

async function rateLimitedRequest(mobile: string) {
  return limiter.schedule(() => client.upiByMobile(mobile, { sync: true }));
}

Webhook Security

Signature Verification

Always verify webhook signatures to ensure authenticity:
import crypto from 'crypto';

function verifyWebhookSignature(
  payload: string,
  signature: string,
  timestamp: string,
  secretKey: string
): boolean {
  // Check timestamp to prevent replay attacks
  const webhookTime = parseInt(timestamp, 10);
  const currentTime = Date.now();
  const maxAge = 5 * 60 * 1000; // 5 minutes
  
  if (Math.abs(currentTime - webhookTime) > maxAge) {
    return false;
  }

  // Verify signature
  const message = `${timestamp}.${payload}`;
  const expected = crypto
    .createHmac('sha256', secretKey)
    .update(message)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Webhook Endpoint Security

Secure your webhook endpoint:
app.post('/webhook/fraud-buster', 
  // Rate limit webhooks
  rateLimit({ windowMs: 60000, max: 100 }),
  
  // Verify signature middleware
  webhookSignatureMiddleware(process.env.WEBHOOK_SECRET!),
  
  // Process webhook
  async (req, res) => {
    // Handle webhook...
    res.json({ status: 'ok' });
  }
);

Error Handling Security

Don’t Expose Internal Errors

// ✅ Good: Generic error message to client
app.use((err, req, res, next) => {
  console.error('Internal error:', err); // Log full error
  res.status(500).json({
    error: 'An error occurred processing your request',
  });
});

// ❌ Bad: Exposing internal details
app.use((err, req, res, next) => {
  res.status(500).json({
    error: err.message,
    stack: err.stack, // Never expose stack traces!
  });
});

Secure Logging

Log enough for debugging without exposing sensitive data:
// ✅ Good: Mask sensitive data in logs
function logAPICall(mobile: string, result: any) {
  console.log({
    action: 'verification',
    mobile: maskMobile(mobile), // +91****543210
    status: result.status,
    requestId: result.requestId,
    timestamp: new Date().toISOString(),
  });
}

function maskMobile(mobile: string): string {
  return mobile.slice(0, 3) + '****' + mobile.slice(-6);
}

// ❌ Bad: Logging full mobile numbers
console.log(`Verified mobile: ${mobile}`);

Security Checklist

Before going to production, verify:
  • API keys stored in secrets manager
  • No keys in source code or version control
  • Separate keys for dev/staging/production
  • Key rotation process documented
  • All API calls use HTTPS
  • Certificate validation enabled
  • No sensitive data in URLs (use POST body)
  • Mobile numbers validated before API calls
  • VPA formats validated
  • Input sanitization in place
  • Signature verification implemented
  • Timestamp validation (replay protection)
  • Rate limiting on webhook endpoint
  • HTTPS-only webhook URL
  • Sensitive data masked in logs
  • API errors logged for debugging
  • Alerting on unusual patterns
  • Audit trail for compliance

Incident Response

If you suspect your API key has been compromised:
  1. Immediately rotate the API key in your dashboard
  2. Review recent API usage for unauthorized calls
  3. Check your systems for the source of the leak
  4. Update all deployed applications with new keys
  5. Contact TxnCheck support if needed