Best Practices for Securing API Endpoints
Recently, I have seen a lot of news about API security breaches and data exposure. I will not dissect the incident but let us take that as learning, and see what we can do to improve the security. Without further ado, let me jump into the core aspects.
Authentication and Authorization
Authentication ensures that the entity (user or system) making a request is who it claims to be. Authorization ensures that the authenticated entity has the necessary permissions to access the resource.
For example, In a banking API, a user must authenticate (e.g., by logging in with a username and password) before accessing account information.
OAuth 2.0: Used by services like Google, and GitHub for delegated access.
JWT (JSON Web Tokens): Used widely in stateless APIs to authenticate users. JWT contains claims about the user and is sent in headers for each request (e.g., as part of the
Authorization
header).Auth0: A service for managing OAuth, JWT, and other authentication methods.
HTTPS
HTTPS ensures that all communication between the client and the server is encrypted, protecting the data from man-in-the-middle (MITM) attacks and eavesdropping.
When a user accesses an API for online shopping (e.g., Amazon’s API), HTTPS ensures that sensitive information such as credit card details is encrypted.
SSL/TLS certificates: Provided by authorities like Let's Encrypt for securing communications. TLS (Transport Layer Security) is the successor of SSL.
Cloudflare: Offers SSL for websites and APIs to ensure HTTPS.
Rate Limiting and Throttling
Rate limiting restricts the number of requests a client can make in a given timeframe. This helps prevent DoS attacks and abuse of API resources.
X (formerly Twitter) API limits the number of requests that can be made to its API endpoints within a 15-minute time window. For example, the /users/show
endpoint has a rate limit of 900 requests per 15 minutes. This prevents one client from overwhelming the service.
NGINX and Apache: Can be configured to set rate limits for API endpoints.
AWS API Gateway: You can define request quotas and throttle limits for API endpoints.
Input Validation
Validating inputs ensures that only expected data is processed by the API, preventing attacks such as SQL injection, XML/JSON injection, and XSS (Cross-Site Scripting).
A user submitting a login form might inject SQL queries into the username field. Input validation ensures only valid usernames are processed, preventing malicious inputs from executing.
OWASP ESAPI (Enterprise Security API): A toolkit for input validation and encoding.
Validators and libraries: In languages like Joi for Node.js or Flask-WTF for Python to validate forms and inputs.
API Gateway
An API gateway acts as an entry point for APIs, handling tasks such as authentication, rate limiting, and routing, ensuring consistent security across all endpoints.
A microservices architecture might use an API gateway like Kong to manage security, logging, and rate limits for various microservices.
Kong: Open-source API gateway that provides plugins for security, rate limiting, and logging.
AWS API Gateway: Manages REST APIs with integrated security features.
CORS (Cross-Origin Resource Sharing)
CORS policies restrict which origins (domains) can make requests to your API, preventing unauthorized websites from accessing it.
A web-based client (e.g., a React app hosted on example.com
) might use a CORS policy to allow only requests from api.example.com
to avoid malicious sites making requests on behalf of users.
CORS configurations in web servers like NGINX or Express.js can be configured to specify which origins are allowed.
Helmet.js: Helps secure Node.js APIs by setting appropriate HTTP headers, including CORS policies.
Strong Encryption
Strong encryption protects sensitive data both at rest (in the database) and in transit (during communication). Ensure you’re using modern encryption algorithms like AES (Advanced Encryption Standard).
Storing user passwords in a database using strong encryption like bcrypt ensures that even if the database is breached, the passwords are not easily decrypted.
AES-256: Widely used for encrypting sensitive data in databases and communications.
bcrypt: A password hashing function used to encrypt passwords securely.
OpenSSL: A toolkit for implementing encryption in software.
Logging and Monitoring
Logging tracks API requests, and monitoring helps detect and respond to security incidents in real time. These practices help in identifying abnormal behaviours or security breaches.
If a user makes too many failed login attempts, logging and monitoring can detect and block the IP address to prevent brute-force attacks.
Loggly and Splunk: Tools for centralized log management and analysis.
Datadog: Used for monitoring APIs and tracking unusual behaviours such as spikes in traffic.
Content Security Policies (CSP)
CSPs restrict which resources a website can load (e.g., scripts, styles). This can protect against attacks like cross-site scripting (XSS) by preventing malicious scripts from being executed.
A web app that includes dynamic content might use a CSP to ensure that only trusted domains can serve JavaScript, preventing attackers from injecting malicious scripts.
Helmet.js: Can set CSP headers in Node.js applications.
Web Application Firewalls (WAFs) like Cloudflare offer CSP management.
Security Audits
Security audits help identify vulnerabilities and weaknesses in the API that may have been overlooked during development.
Large organizations like Google run regular vulnerability scans and penetration testing to ensure their APIs are not vulnerable to attacks.
OWASP ZAP and Burp Suite: Popular tools for security testing and penetration testing.
Snyk: Used to identify vulnerabilities in dependencies or APIs.
JWT Token Expiry and Refresh
JWT tokens should have a short lifespan to minimize the impact if a token is compromised. After expiration, a new token can be issued through a refresh token, ensuring security without requiring users to log in frequently.
A web app might issue a JWT with a 15-minute lifespan. After expiration, the app automatically fetches a new token using a refresh token.
Auth0 and Firebase: Popular services that implement JWT-based authentication with token expiry and refresh.
jsonwebtoken (Node.js) for implementing JWT tokens in your services.
Limit Data Exposure
Limit the amount of information exposed through API responses, especially in error messages, to avoid giving attackers insights into the system’s inner workings.
An API might return generic error messages (e.g., "Invalid credentials") instead of more detailed messages like "Invalid username" or "Incorrect password," which could help attackers identify valid usernames.
API Gateway and Web Application Firewalls (WAFs) can filter responses to ensure minimal data exposure.
Express.js middleware: Custom error handlers can ensure error messages don’t leak sensitive information.
Security Headers
Security headers like Content-Security-Policy
, X-Content-Type-Options
, and X-Frame-Options
protect against common attacks such as clickjacking, MIME-type sniffing, and XSS.
A browser is prevented from embedding an API page inside an iframe (protecting from clickjacking) if the X-Frame-Options: DENY
header is set.
Helmet.js: A middleware for Express.js that helps set various security headers.
Mozilla Observatory: A tool to check the security headers in your API’s HTTP responses.
By adopting these best practices, you’ll strengthen the security of your API endpoints against a wide range of threats. There are numerous other tools and libraries apart from what has been mentioned here to help automate and enforce many of these practices to ensure a secure environment.
Subscribe to my newsletter
Read articles from Sainath Ramanathan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Sainath Ramanathan
Sainath Ramanathan
I am an experienced technology professional with a strong background in software development. I have expertise in full-stack web development and have consistently driven innovation and modularity across various frameworks and architectures. I am passionate about designing and developing efficient, scalable, and user-friendly applications. My work includes developing generative AI solutions, no-code solutions, and AI-based web apps. I am enthusiastic about frontend and backend technologies, generative AI, and technology leadership. I have been recognized in both professional and technical communities for my contributions. I have worked with diverse organizations, from startups to large enterprises, and I am always eager to learn new things and take on new challenges.