This guide provides recommendations for securing HTTP-based APIs. It is aimed at technical personnel responsible for designing or building applications that provide HTTP APIs. Please note that you should perform threat modeling specific to your design to fully secure HTTP-based APIs.
What is an HTTP-Based API?
An HTTP-based API enables communication between different software systems (often including third-party services) and can be used to access services and databases, manipulate data, and even handle user authentication and authorization. They are key components in modern internet application architectures.
An API (Application Programming Interface) is typically defined as a set of specifications (such as the format of HTTP requests sent to API endpoints) and the definition of response message structures, usually in JSON format. APIs can be used to receive some data, upload some data, or control operations or systems.
Threats Facing APIs
Attackers can exploit weaknesses and vulnerabilities in APIs in various ways. For example, they can:
- Access sensitive data using insecure API endpoints
- Upload malicious code via the API and use it to attack the system
- Gain API access and then perform unauthorized actions on the system (e.g., making unauthorized payments in a banking system)
- Manipulate data stored in the system via the API
- Launch denial-of-service attacks by repeatedly polling API endpoints
Since HTTP-based APIs are shared externally from your organization to provide data or functionality, you should perform service-specific threat modeling to understand the associated risks and threats.
1. Secure Development Practices
Your API being compromised can affect operations, damage the organization’s reputation, and even lead to fines from regulators. It is crucial to determine the context before designing systems, as this will ensure that any security controls are commensurate with the threats you face. For example, an API for a public weather forecasting application and an API for managing a production line have entirely different threat and risk profiles, which will translate into different security controls.
Threat Model Your Design
Start by threat modeling the high-level design so that you can understand any potential threats early in the design process. NCSC’s guidance on threat modeling and the OWASP Top Ten API threats can assist you.
Use Documented APIs
Comprehensive API documentation can provide asset management for your API design. This can be used to determine:
- Endpoints that should be exposed as part of the application
- Endpoints that should not be exposed (e.g., development or management endpoints)
- Legacy endpoints
Good documentation will help ensure that the correct security controls are applied to the parts of the API design that need them. Try to use common API specifications (such as OpenAPI) to document and describe your API. Using widely understood API specifications allows for the use of common tools to visualize and understand your API design.
As part of this documentation, ensure you effectively manage API versions to avoid inadvertently using deprecated or insecure versions, and ensure clients are always using the latest secure version. Through version control, you can also deprecate and eventually retire insecure or outdated API versions, encouraging users to migrate to newer, more secure versions.
Secure Development and Testing
NCSC uses the term “design security” to describe a development approach that encourages organizations to “embed” cybersecurity into all stages of the product lifecycle rather than considering it afterward. Regardless of how well protected an API is, a secure development environment and code delivery are still required. Once in production, any API should undergo appropriate security testing, including negative testing and fuzz testing applicable to the threat model (not just positive testing).
Use Standards
When building applications that use HTTP-based APIs, try to use well-known appropriate standards. This can reduce the likelihood of security vulnerabilities in the design. Some examples include:
- Using JSON for data exchange
- Using OpenAPI to describe API design
- Using TLS and other standard encryption technologies to transmit data
Many other standards can be considered in your API design, and you should prioritize tried and tested methods rather than building your own.
Asset Registration and Governance
Asset registries and effective governance can help organizations maintain visibility, control, and protection over their APIs. An asset registry is a comprehensive list detailing all API endpoints, services, and related resources within the organization’s infrastructure. This registry not only helps identify potential vulnerabilities but also enables efficient monitoring and management of assets throughout their lifecycle.
Effective governance ensures that policies, procedures, and controls are established to protect these assets and comply with industry standards and regulatory requirements.
2. API Authentication and Authorization
Implementing strong authentication and authorization is crucial for protecting APIs, ensuring that only legitimate users or services can access endpoints and perform actions.Authentication verifies the identity of the entity making the API request, while authorization controls what actions authenticated entities can perform.
In many cases, authentication and authorization are closely linked, with certain mechanisms serving both functions simultaneously. For example, tokens issued by identity providers can authenticate users and contain claims that define what actions the user is authorized to perform.
Choosing the right authentication and authorization methods requires careful planning and consideration of the specific needs of the application.
User Access
Applications often need to interact with APIs on behalf of users, but traditional user authentication methods are not suitable for this purpose. A more secure approach is to authenticate users through an identity provider. This process generates temporary credentials (such as tokens or cookies) that the application can use to interact securely with the API.
For more information, refer to NCSC’s guidance on selecting authentication methods for online services for businesses and multi-factor authentication.
API Authentication
Good practices for secure API authentication include:
Secure Generation and Exchange
Credentials should be generated in a secure environment, preferably not exported from the location where they are generated. This is especially true for public key-based credentials. If credentials need to be exported (typically when using symmetric keys), secure transport must be used, and the process should be automated with minimal human involvement.
Avoid hardcoding credentials directly into source code stored in version control, especially when the repository is publicly accessible or widely shared. Once in version control, secrets can be difficult to completely remove. Attackers often scan public repositories for such credentials.
Secure Credential Storage
Ensure your API credentials are securely stored. Consider using a secret manager (with secure storage backends like HSM or cloud KMS), or store credentials in tamper-proof hardware-backed storage locations (such as USB tokens or TPM). Poorly secured secrets increase the likelihood of attackers stealing your credentials, especially when you store secrets in multiple locations, making auditing difficult (this issue is known as “secret sprawl”).
For short-lived credentials (or for authenticating low-value applications), you can use software-backed storage. You should balance the effective lifetime of the credentials, their value, and the storage method used.
Credential Expiration
The expiration of credentials should be set to an appropriate time for the use case and threat. Credentials should be automatically rotated or renewed after expiration, and the rotation process should be automated with minimal human involvement. If credentials cannot be stored in a secure storage method, or if they lack replay resistance, the risk should be mitigated by shortening the effective lifetime of the credentials.
Avoid using long-lived access keys, as they can grant indefinite access if compromised, potentially exposing data and services. Attackers gaining access to these keys can abuse your API resources until the keys are rotated or revoked. Using short-lived keys reduces the time window during which attackers can use the keys before they become inactive (useless to attackers).
Replay-Proof Credentials
Use credentials with replay protection. This can be achieved by using public key-based credentials, such as certificates or signed JSON Web Tokens (JWTs). The use of credentials should be part of any monitoring strategy, with any abuse triggering alerts.
Avoid Weak Authentication Methods
Do not use weak authentication methods, such as basic authentication or API keys. Basic authentication transmits usernames and passwords in Base64 encoding with each request, while API keys are placed in HTTP headers and act as shared bearer tokens. Both methods are easily attacked, often due to poor secret management. They also frequently provide broad access and do not expire or limit permissions. You should adopt stronger authentication methods (such as signed JWTs or certificates) that should be implemented and managed according to NCSC guidance.
API Authorization
Once users are authenticated, it is important to control what actions they can perform and what data they can access in the API. Authorization controls access to resources based on the identity and permissions of the requesting entity. Unless you are hosting a completely open public API, implementing an authorization framework is essential.
Three fundamental principles guide effective authorization governance:
- Enforce Least Privilege: Grant users or processes the minimum access necessary to perform their tasks, thereby limiting potential security vulnerabilities or malicious activities.
- Default Deny: Restrict access by default, allowing only explicitly authorized entities to enter.
- Validate Permissions for Each Request: Continuously validate access permissions for each operation within the system.
Granting tokens excessive permissions increases the risk of data breaches or service abuse. This is often due to using generic keys or overly broad tokens that have full access to various endpoints.
OpenID Connect and OAuth 2.0
OAuth 2.0 and OpenID Connect (OIDC) are two complementary industry-standard frameworks for securing API access and user identity management. You can implement our authentication and authorization guidelines using a range of standards.
- OAuth 2.0 is an authorization framework that allows third-party applications to access resources on behalf of users without exposing their credentials. It uses tokens to facilitate secure delegated access but does not provide authentication itself.
- OpenID Connect extends OAuth 2.0 by introducing an identity layer that allows applications to verify user identities and retrieve identity-related claims via JWT. It achieves this by merging ID tokens that contain verified information about authenticated users. This extension helps implement single sign-on (SSO), allowing users to securely access multiple applications without re-entering credentials.
Recent advancements in OAuth have introduced improved credential protection security mechanisms, such as certificate-bound tokens and proof of possession (DPoP). Although these security enhancements are relatively new, they are widely supported and strongly recommended as part of the OAuth 2.0 Best Current Practice (BCP) guidelines to mitigate risks such as token theft and replay attacks.
3. Data Protection in Transit
API data should be protected in transit using TLS (Transport Layer Security). Refer to NCSC’s guidance on recommended profiles for securely configuring TLS. APIs using outdated TLS protocols or weak cipher suites expose data in transit to attackers, potentially allowing interception and decryption. This makes APIs vulnerable to man-in-the-middle (AiTM) attacks, which can leak sensitive information such as credentials and personal data.
If the API is hosted for a small community (or is a private API), consider using mutual authentication protocols, such as Mutual TLS (mTLS). This provides two-way authentication, ensuring that both the client and server verify each other’s identities before establishing a secure connection. If you do use mTLS, you may need to build a private PKI for the client authentication part of mTLS.
4. Input Validation
- Syntactic and Semantic Validation
Input validation is the process of checking and validating data received by the API before processing it. This validation ensures that the input meets specified criteria (such as data types, formats, lengths, and ranges) and does not contain potentially malicious or unintended content. For more information, refer to the “Make Invasion Difficult” section in NCSC’s security design principles.
Effective input validation is crucial for preventing various security vulnerabilities, including injection attacks, data tampering, and denial-of-service (DoS) attacks, which can jeopardize the confidentiality, integrity, and availability of API resources.
You should validate input as early as possible, preferably at the point of receiving data from external sources, and ensure validation occurs at every layer of the system. Unintentional inconsistencies between layers are a well-known cause of vulnerabilities. At the user interface layer, it helps catch basic errors early. The application logic layer enforces business rules, ensuring that only valid data can proceed, while the data access layer prevents injection attacks and enforces database constraints. Consistent validation across all layers reduces risk and creates a more secure defense-in-depth architecture.
If using an API gateway, it should perform initial validation but should not be the only validation point. Implement a multi-layered approach where the gateway handles basic checks while backend services perform detailed, context-specific validation. To simplify this process and ensure consistency, consider implementing a central input validation library or process so that you do not have to re-implement validation logic for each function.
Syntactic and Semantic Validation
Input validation should occur at both the syntactic and semantic levels:
- Syntactic validation ensures that the syntax and structure of input data are correct, typically focusing on predefined patterns, formats, and constraints. Validation checks whether the input conforms to expected standards and patterns, such as the correct format for email addresses, phone numbers, dates, or currency symbols.
- Semantic validation verifies the correctness of data within the relevant business context (e.g., confirming that a start date is earlier than an end date or falls within an expected range).
By enforcing both syntactic and semantic validation, developers can reject any input that does not conform to specified syntax rules and is accurate within the expected context, thereby reducing the risk of processing errors, data corruption, and security vulnerabilities while improving data accuracy.
Good Practices for Syntactic Validation
JSON Parsers
Strict JSON parsers ensure that data is syntactically correct, validating that it conforms to the correct JSON format. If the input data contains structural errors (such as incorrect parentheses or misplaced commas), the parser will raise an error or exception.
Centralized Validation Libraries
Use well-tested input validation libraries or frameworks. These libraries typically provide features such as type checking, range validation, and sanitization, reducing reliance on complex and hard-to-maintain regular expression patterns.
Allow Lists
Allow list validation explicitly defines authorized inputs and ensures that only accepted values are accepted. For example, for structured data from fixed options (such as dropdown lists), exact matches of data formats should be adopted.
Good Practices for Semantic Validation
Schema Validation
JSON schemas can be used to define the data structures exchanged via the API and validate incoming payloads against these schemas. Schema validation should also be used to ensure that attackers do not send unexpected additional clauses (key-value pairs).
Data Type Validators
Many programming languages provide built-in type-checking mechanisms. For example, in statically typed languages like Java or TypeScript, the compiler can enforce the correctness of data types. In dynamically typed languages like Python or JavaScript, libraries or custom functions can be used to perform type checking.
Minimum and Maximum Range
Ensure that numeric parameters and dates fall within specified minimum and maximum ranges, and that strings conform to defined length standards.
Escaping and Encoding
Escaping and encoding user input is an important security measure that ensures special characters are correctly handled to prevent vulnerabilities (such as SQL injection or cross-site scripting) by converting user input into a format that has no functional significance in the application.
5. Mitigating DoS Attacks
A common attack against APIs is exhausting the resources available to the API, which can lead to DoS or increased costs for hosting the API. Consider limiting or throttling the use of the API. “Throttling” refers to imposing quotas on the frequency/rate of API calls. This is typically measured in the number of requests that can be made per second and should allow legitimate consumers to handle spikes in usage. When APIs lack rate limiting and throttling, they are vulnerable to excessive requests, leading to server overload and resulting in denial-of-service (DoS) attacks or resource exhaustion.
Allowing usage spikes is a good practice, as API users may sometimes need to make more legitimate requests. You should also log the number of attempts users make to access the API to analyze whether there is legitimate traffic surges or if you are experiencing a potential DoS attack. For more information on understanding and mitigating DoS attacks, refer to NCSC’s Denial of Service (DoS) Guidelines.
6. Logging and Monitoring
On this page
- Logging
- Monitoring
Logging and monitoring, while closely related and often used together, serve different purposes. Logging is retrospective, providing a comprehensive audit trail that can be used for troubleshooting, forensic analysis, compliance audits, and incident response. It focuses on storing information for later review and analysis. On the other hand, monitoring involves continuous, real-time observation and analysis of system behavior, performance metrics, and security indicators.
Allowing usage spikes is a good practice, as API users may sometimes need to make more legitimate requests. You should also log the number of attempts users make to access the API to analyze whether there is legitimate traffic surges or if you are experiencing a potential DoS attack. For more information on understanding and mitigating DoS attacks, refer to NCSC’s What data needs to be collected for security purposes and when to collect it.
Logging
Logging is a systematic record of events, operations, and transactions within the system. These logs chronologically record user activities, system changes, and data access, providing a comprehensive view of the operational status of the API. In API security, logging is an important component for maintaining visibility into operations and interactions within the API ecosystem.
Record Security Events
Ensure logs capture important security-related events, including authentication and authorization activities, such as login attempts, permission changes, failed requests, errors, and sensitive operations like password changes, account modifications, and privilege escalations.
Implement Centralized Logging
If possible, implement a centralized logging system to aggregate and analyze logs, ensuring that data from multiple services and microservices is consolidated in one place.
Record Access, Error, and Transaction Logs
Track access logs, error logs, and transaction data to monitor API activity and ensure security. Record details of each API call, including timestamps, source IPs, user identities, and accessed endpoints. This helps identify unauthorized access, track user interactions, and detect unusual transaction patterns that may indicate potential security threats or fraudulent activities.
Protect Sensitive Data in Logs
Never log sensitive data such as passwords, API keys, access tokens, and personally identifiable information (PII). Instead, use data masking or obfuscation to protect confidential information and ensure that logs are encrypted both at rest and in transit.
Monitoring
Monitoring systems track key metrics such as API response times, uptime, resource utilization, and security events. They detect anomalies, generate alerts, and notify administrators or security teams when predefined thresholds are exceeded or suspicious activities are detected.
Monitoring is a proactive measure designed to discover and address issues as they arise, ensuring the ongoing health and security of the API infrastructure. Monitoring plays a critical role in maintaining the integrity and availability of APIs and detecting and mitigating security threats.
Enable Real-Time Monitoring and Alerts
Use SIEM (Security Information and Event Management) tools to monitor logs, detect threats, and enable anomaly detection. Set up alerts for suspicious activities, such as multiple failed login attempts (indicating potential brute-force attacks) or spikes in API traffic (which may indicate DoS attacks), sudden stops in logging (which may indicate tampering or ongoing attacks), or abnormal/large data transfers (which may indicate data breaches). Ensuring ongoing log integrity and monitoring data movement helps detect and mitigate security threats before they escalate.
Endpoint Performance Tracking
Implement endpoint performance tracking, focusing on monitoring the availability and performance of API endpoints. It tracks response times, error rates, and availability to ensure they are functioning as expected and detects any issues that may affect API availability or reliability.
7. Limiting Attack Surface
API endpoints should not be overly exposed or allow known malicious IP addresses to connect to the API. Limit the attack surface so that attackers cannot even access certain sensitive parts of the API, reducing the likelihood of your application being attacked.
Limit Exposure of Endpoints
API endpoints are the URLs that clients use to connect to the API. The API endpoints exposed to customers should be effectively managed. Unless access is strictly limited to trusted networks (or devices that attackers cannot control), attackers may have some level of access (potentially extracting API endpoints and keys through methods such as reverse engineering applications).
Remove Unused Endpoints
When APIs are updated, endpoints can sometimes be left exposed, especially when the API is being (or has been) deprecated. In such cases, this may mean that all monitoring and security features are inactive, especially if the API is no longer in use. This can also mean that potentially vulnerable API endpoints are exposed and accessible. When API endpoints are deprecated, IT teams need to ensure that the endpoints are no longer accessible and that access is blocked. The asset registry mentioned in Section 1 will help with this.
Restrict Access to Privileged Endpoints
Endpoints considered sensitive (such as those used for managing the API) should also have restricted network access and should not be publicly accessible. This makes it more difficult for attackers or malicious users to access sensitive APIs and attempt to exploit them. You should proactively scan your environment to ensure you know what is publicly exposed. This will allow you to proactively discover any overly exposed legacy, development, or management APIs.
Block Known Malicious IP Addresses
Block known malicious IP addresses and categories of IP addresses that should not connect to your API. Blocking IP addresses in this way is often a feature provided by many web application firewalls (WAFs). If possible, you should try to use managed rule sets to block IP addresses, as this will significantly reduce your management overhead. You will need to tune the rule sets, so you may need to monitor the rules before executing them to avoid inadvertently blocking legitimate traffic.
API Exposure in Closed Communities
If you are hosting a private API or an API used in a closed community (such as a CNI department or government department group), consider further limiting the exposure of the API. This can take the form of mTLS, IP address allow lists, or using VPNs. The method you choose to reduce exposure will depend on the size, threats, and requirements of the closed community.
API Responses
If an API returns excessive or unnecessary data, it may leak sensitive information such as internal identifiers, user personal identifiers (PII), or debugging details. Such exposure can help attackers gather intelligence for targeted attacks or lead to unintentional leaks of user privacy.
API Gateway Security
When deploying APIs at scale, use an API gateway, as this will provide a consistent security approach. If you are hosting APIs in the public cloud, you should consider using cloud-native infrastructure rather than migrating on-premises solutions to the cloud.
The API gateway acts as an intermediary between clients and backend services, providing a centralized entry point for managing and securing API traffic. The centralized nature of the API gateway simplifies the implementation of security features when building APIs at scale. The API gateway can provide a means for consistent implementation of security features, as these features are provided in the gateway rather than in the backend application code.
Some security features you can find in an API gateway include:
- Schema validation (as described in Section 4)
- Client authentication and authorization; API gateways typically support frameworks such as OpenID Connect and OAuth 2.0
- Providing a central point for monitoring and logging API endpoints
- Integration with tools such as WAF and IDS, which can serve as a defense-in-depth and limit API exposure