Advanced api security - vidyasekaran/current_learning GitHub Wiki
The book explains in depth how to secure APIs, from traditional HTTP Basic Authentication to OAuth 2.0 and the standards built around it, such as OpenID Connect, User Managed Access (UMA), and many more. JSON plays a major role in API communication. Most of the APIs developed today support only JSON, not XML. This book also focuses on JSON security. JSON Web Encryption (JWE) and JSON Web Signature (JWS) are two increasingly popular standards for securing JSON messages. The latter part of this book covers JWE and JWS in detail.
The world is more connected than ever. You can log in to Yahoo! with Facebook credentials, share photos from Instagram in Facebook, share a location from Foursquare in Twitter, and publish tweets to your Facebook wall. The list of connections is limitless. All this is made possible only because of public APIs, which have proliferated in the last couple of years. In 2013, 90% of Expedia’s business was coming through its API. Salesforce generates almost 50% of its annual $3 billion in revenue through APIs. APIs have become the coolest way of exposing business functionalities to the outside world.
API vs. Managed API
The Twitter API can be used to tweet, get timeline updates, list followers, update profiles, and do many other things. None of these operations can be performed anonymously—you need to authenticate first. Let’s take a concrete example (you need to have cURL installed to try this, or you can use the Chrome Advanced REST client browser plug-in):
curl https://api.twitter.com/1.1/statuses/home_timeline.json
This API is supposed to list all the tweets published by the authenticated user and his or her followers. If you just invoke it, it returns an error code, specifying that the request isn’t authenticated: {"errors":[{"message":"Bad Authentication data","code":215}]}
All the Twitter APIs are secured for legitimate access with OAuth 1.0 (which is discussed in detail in Chapter 6). Even with proper access credentials, you can’t invoke the API as you wish. Twitter enforces a **rate limit ** on each API call: within a given time window, you can only invoke a Twitter API a fixed number of times. This precaution is required for all public-facing APIs to minimize any possible denial of service (DoS) attacks (flooding). In addition to securing and rate-limiting its APIs, Twitter also closely monitors them. Twitter API Health (https://dev.twitter.com/status) shows the current status of each API. Security, rate limiting (throttling), and monitoring are key aspects of a managed business API. It also must have the ability to scale up and down for high availability based on traffic.
Rate limiting is used to control the amount of incoming and outgoing traffic to or from a network. For example, let's say you are using a particular service's API that is configured to allow 100 requests/minute. If the number of requests you make exceeds that limit, then an error will be triggered.
Life-cycle management is another key differentiator between a naked API and a managed API. A managed API has a life cycle from its creation to its retirement. A typical API life cycle might flow through Created, Published, Deprecated, and Retired stages, as illustrated in Figure 1-3. To complete each life-cycle stage, there can be a checklist to be verified. For example, to promote an API from Created to Published, you need to make sure the API is secured properly, the documentation is ready, throttling rules are enforced, and so on. A naked business API, which only worries about business functionalities, can be turned into a managed API by building these quality-of-service aspects around it.
https://helpx.adobe.com/coldfusion/api-manager/throttling-and-rate-limiting.html
Api throttling rules: Throttling is a process that is used to control the usage of APIs by consumers during a given period. You can define throttling at the application level and API level. Throttling limit is considered as cumulative at API level. For example, you can limit the number of total API requests as 10000/day.
Summary
This chapter discussed the evolution of APIs and how managed APIs are different from naked APIs. Most cloud service providers today expose public managed APIs. The later part of the chapter focused on building two examples around Twitter and Salesforce APIs. In the next chapter, we will take a closer look at the basic principles everyone should know when doing a security design.
Security isn’t an afterthought. It has to be an integral part of any development project and also for APIs. It starts with requirements gathering and proceeds through the Design, Development, Testing, Deployment, and Monitoring phases.
Security brings a plethora of challenges into system design. It’s hard to build a 100% secured system, at least in theory. The only thing you can do is to make the attacker’s job harder.
User Comfort - A password has to have more than 20 characters, with mandatory uppercase and lowercase letters, numbers, and special characters. Who on Earth is going to remember their password? Either you’ll write it on a piece of paper and keep it in your wallet, or you’ll add it as a note in your mobile device. Either way, you lose the ultimate objective of the strong password policy
Performance - Performance is another key criterion. What is the cost of the overhead you add to your business operations to protect them from intruders? Say you have an API secured with a key, and each API call must be digitally signed. If the key is compromised, an attacker can use it to access the API. How do you minimize the impact? You can make the key valid only for a very short period; so, whatever the attacker can do with the stolen key is limited to its lifetime. What kind of impact will this have on legitimate day-to-day business operations? Each API call should first check the validity period of the key and, if it has expired, make another call to the authorization server to generate a new key. If you make the lifetime too short, then for each API call, there will be another call to the authorization server to generate a new key. That kills performance—but drastically reduces the impact of an intruder getting access to the API key.
Weakest Link - A proper security design should include all the communication links in the system. Your system is no stronger than its weakest link. In 2010, it was discovered that since 2006, a gang of robbers equipped with a powerful vacuum cleaner had stolen more than 600,000 euros from the Monoprix supermarket chain in France. The most interesting thing was the way they did it. They found out the weakest link in the system and attacked it. To transfer money directly into the store’s cash coffers, cashiers slid tubes filled with money through pneumatic suction pipes. The robbers realized that it was sufficient to drill a hole in the pipe near the trunk and then connect a vacuum cleaner to capture the money. They didn’t have to deal with the coffer shield.
Defense in Depth - A layered approach is preferred for any system being tightened for security. This is also known as defense in depth. Most international airports, which are at a high risk of terrorist attacks, follow a layered approach in their security design. On November 1, 2013, a man dressed in black walked into the Los Angeles International Airport, pulled a semi-automatic rifle out of his bag, and shot his way through a security checkpoint, killing a TSA screener and wounding at least two other officers. This was the first layer of defense. In case someone got through it, there has to be another to prevent the gunman from entering a flight and taking control. If there had been a security layer before the TSA, maybe just to scan everyone who entered the airport, it would have detected the weapon and probably saved the life of the TSA officer. The number of layers and the strength of each layer depend on which assets you want to protect and the threat level associated with them. Why would someone hire a security officer and also use a burglar alarm system to secure an empty garage?
Insider Attacks- Insider attacks are less powerful and less complicated, but highly effective. From the confidential US diplomatic cables leaked by WikiLeaks to Edward Snowden’s disclosure about the National Security Agency’s secret operations, are all insider attacks. Both Snowden and Bradley Manning were insiders who had legitimate access to the information they disclosed. Most organizations spend the majority of their security budget to protect their systems from external intruders; but approximately 60% to 80% of network misuse incidents originate from inside the network, according to the Computer Security Institute (CSI) in San Francisco.
Security by Obscurity : Kerckhoffs, Principle emphasizes that a system should be secured by its design, not because the design is unknown to an adversary.** Microsoft’s NTLM design was kept secret for some time**, but at the point (to support interoperability between Unix and Windows) Samba engineers reverse-engineered it, they discovered security vulnerabilities caused by the protocol design itself. In a proper security design, it’s highly recommended not to use any custom-developed algorithms or protocols. Standards are like design patterns: they’ve been discussed, designed, and tested in an open forum. Every time you have to deviate from a standard, should think twice—or more.
Jerome Saltzer and Michael Schroeder produced one of the most widely cited research papers in the information security domain.2 The paper, “The Protection of Information in Computer Systems,” put forth eight design principles for securing information in computer systems, as described in the following sections.
Least Privilege - The principle of least privilege states that an entity should only have the required set of permissions to perform the actions for which they are authorized, and no more. Permissions can be added as needed and should be revoked when no longer in use. This limits the damage that can result from an accident or error.
Fail-Safe Defaults - This principle highlights the importance of making a system safe by default. A user’s default access level to any resource in the system should be “denied” unless they’ve been granted a “permit” explicitly. The Java Security Manager implementation follows this principle—once engaged, **none of the components in the system can perform **any privileged operations unless explicitly permitted.
Economy of Mechanism- This principle highlights the value of simplicity. The design should be as simple as possible. All the component interfaces and the interactions between them should be simple enough to understand.
Complete Mediation - With complete mediation, a system should validate access rights to all its resources to ensure that they’re allowed. Most systems do this once at the entry point to build a cached permission matrix. Each subsequent operation validates the resource permission against the permission matrix. If the access level to a** given resource is being revoked**, but that isn’t reflected in the permission matrix, it would violate this principle.
Open Design - This principle highlights the importance of building a system in an open manner—with no secret, confidential algorithms. This is the** opposite of security by obscurity**, discussed earlier in the section “Design Challenges.”
Separation of Privilege - The principle of separation of privilege states that granting permissions to an entity should not be purely based on a single condition. For example, say a reimbursement claim can be submitted by any employee but can only be approved by the manager. What if the manager wants to submit a reimbursement? According to this principle, the manager should not be granted the right to approve his or her own reimbursement claims.
Least Common Mechanism - The principle of least common mechanism concerns the risk of sharing state among different components. If one can corrupt the shared state, it can then corrupt all the other components that depend on it.
Psychological Acceptability - The principle of psychological acceptability states that** security mechanisms should not make the resource more** difficult to access than if the security mechanisms were not present. Microsoft introduced Information Cards in 2006 as a new paradigm for authentication to fight against phishing. But the user experience was bad, with a high setup cost, for people who were addicted to username/password-based authentication. It went down in history as another unsuccessful initiative from Microsoft
Confidentiality, integrity, and availability are three key factors used in benchmarking information systems security, as discussed next.
Confidentiality -
Confidentiality - Confidentiality means protecting data from unintended recipients, both at rest and in transit. You achieve confidentiality by protecting transport channels and storage with encryption. For APIs, where the transport channel is HTTP, you can use Transport Level Security (TLS), which is HTTPS. For storage, you can use disk-level encryption or application-level encryption. Channel encryption or transport-level encryption isn’t 100% secure. In contrast, there is message-level encryption, which happens at the application level and has no dependency on the transport channel. If you secure data with message-level encryption, then you can use HTTP as the transport channel. Transport-level encryption only provides point-to-point protection and truncates from where the connection ends. As soon as data leaves the transport channel, it’s no longer secured. At the same time, when you connect to an API gateway through a proxy, the data could be in cleartext while inside the proxy.
A TLS connection from the client to the gateway can be established in two ways: either with SSL bridging or with SSL tunneling. Almost all proxy servers support both modes. For a highly secured deployment, SSL tunneling is recommended. In SSL bridging (see Figure 2-1), the initial connection truncates from the proxy server, and a new connection to the gateway is established from there. That means the data is in cleartext in the proxy server. Any intruder who can plant malware in the proxy server can intercept traffic that passes through.** With SSL tunneling **(see Figure 2-2), the proxy server facilitates creating a direct channel between the client machine and the gateway. The data flow through this channel is invisible to the proxy server.
Message-level encryption, on the other hand, is independent from the underlying transport. It’s the application developers’ responsibility to encrypt and decrypt messages. Because this is application specific, it hurts interoperability and builds tight couplings between the sender and the receiver. Each has to know how to encrypt/decrypt data beforehand—which will not scale up in a distributed system. To overcome this challenge, there have been some concentrated efforts to build standards around message-level encryption. XML Encryption is one such effort, led by the W3C. It standardizes how to encrypt an XML payload. Similarly, the IETF JavaScript Object Signing and Encryption (JOSE) working group is in the process of building a set of standards for JSON payloads. JSON Web Encryption and JSON Web Signature are discussed in Chapter 13.
Transport-level security encrypts the entire message. Because it relies on the underlying channel for protection, application developers have no control over which part of the data to encrypt and which part not to. Partial encryption isn’t supported by transport-level security, but it is supported by message-level security. The Table 2-1 summarizes the key differences between transport-level security and message-level security.
Table 2-1. Transport-Level Security vs. Message-Level Security
Transport-Level Security Message-Level Security Relies on the underlying transport No dependency on the underlying transport Point-to-point End-to-end Partial encryption not supported Partial encryption supported High performance Relatively less performance
■ Note Secure Socket Layer (SSL) and Transport Layer Security (TLS) are often used interchangeably, but in pure technical terms they aren’t the same. TLS is the successor of SSL 3.0. TLS 1.0, which is defined under the IETF RFC 2246, is based on the SSL 3.0 protocol specification, which was published by Netscape. The differences between TLS 1.0 and SSL 3.0 aren’t dramatic, but they’re significant enough that TLS 1.0 and SSL 3.0 don’t interoperate.
Integrity - Integrity is a guarantee of data’s correctness and trustworthiness and the ability to detect any unauthorized modifications. It ensures that data is protected from unauthorized or unintentional alteration, modification, ordeletion**. The way to achieve integrity is twofold: preventive measures and detective measures. Both measures have to take care of data in transit as well as data at rest.
To prevent data from alteration while in transit, you should use a confidential channel that only intended parties can read.** TLS is the recommended approach for transport-level encryption**. TLS itself has a way of detecting datamodifications**. It sends a message-authentication code in each message from the initial handshake, which can beverified by the receiving party to make sure the data has not been modified while in transit**. For data at rest, you cancalculate the message digest periodically and keep it in a secured place. The audit logs, which can be altered by an intruder to hide suspicious activities, need to be protected for integrity.
■ Note : HTTP Digest Authentication with the quality of protection (qop) value set to auth-int can be used to protect messages for integrity. Chapter 3 discusses HTTP Digest Authentication in depth.
Availability -
Making a system available for legitimate users to access all the time is the ultimate goal of any system design. Security isn’t the only aspect to look into, but it plays a major role in keeping the system up and running. The goal of the security design should be to make the system highly available by protecting it from illegal access attempts. Doing so is extremely challenging. Attacks, especially on a public API, can vary from an attacker planting malware in the system to a highly organized distributed denial of service (DDoS) attack.
DDoS attacks are hard to eliminate fully, but with a careful design they can be minimized to reduce their impact. In most cases, DDoS attacks must be detected at the network perimeter level—so, the application code doesn’t need to worry too much. But vulnerabilities in the application code can be exploited to bring a system down. The research paper “A New Approach towards DoS Penetration Testing on Web Services” by Christian Mainka, Juraj Somorovsky, Jorg Schwenk, and Andreas Falkenberg (https://www.nds.rub.de/media/nds/veroeffentlichungen/2013/07/19/ ICWS_DoS.pdf) discusses eight types of DoS attacks that can be carried out against SOAP based APIs with XML payloads
Most of these attacks can be prevented at the application level. For CPU- or memory-intensive operations, you can keep threshold values. For example, to prevent a coercive parsing attack, the XML parser can enforce a limit on the number of elements. Similarly, if your application executes a thread for a longer time, you can set a threshold and kill it. Aborting any further processing of a message as soon as it’s found to be not legitimate is the best way to fight against DoS attacks. This also highlights the importance of having authentication/authorization checks closest to the entry point of the system.
There are also DoS attacks carried out against JSON vulnerabilities. CVE-2013-0269 explains a scenario in which a carefully crafted JSON message can be used to trigger the creation of arbitrary Ruby symbols or certain internal objects, to result in a DoS attack.
The CIA triad (confidentiality, integrity, and availability) is one of the core principles of information security. In achieving CIA, authentication, authorization, nonrepudiation, and auditing play a vital role
Authentication is the process of validating user-provided credentials to prove that users are who they claim to be. It can be single factor or multifactor. Something you know, something you are, and something you have are the well-known three factors of authentication. For multifactor authentication, a system should use a combination of at least two factors. Combining two techniques that fall under the same category isn’t considered multifactor authentication. For example, entering a username and a password and then a PIN number isn’t considered multifactor authentication.
■ Note Google two-step verification falls under multifactor authentication. First you need to provide a username and a password (something you know), and then a PIN number is sent to your mobile phone. Knowing the PIN number verifies that the registered mobile phone is under your possession: it’s something you have.
Something You Know Passwords, passphrases, and PIN numbers belong to the category of something you know
Something You Have- **Certificates and smart card-based authentication **fall into the category of something you have. This is a much stronger form of authentication than something you know. SSL mutual authentication is the most popular way of securing APIs with client certificates.
**Authorization **is the process of validating what actions an authenticated user can perform in the system. Authorization happens with the assumption that the user is already authenticated. Discretionary Access Control (DAC) and Mandatory Access Control (MAC) are two modes to control access.
Discretionary Access Control (DAC) vs. Mandatory Access Control (MAC)
With DAC, the user can be the owner of the data and, at their discretion, can transfer rights to another user. Most operating systems support DAC, including Unix, Linux, and Windows. When you create a file in Linux, you can decide who should be able to read, write to, and execute it. Nothing prevents you from sharing it with any user or a group of users. There is no centralized control—which can easily bring security flaws into the system. With MAC, only designated users are allowed to grant rights. Once rights are granted, users can’t transfer them. SELinux, Trusted Solaris, and TrustedBSD are some of the operating systems that support MAC.
An authorization table is a three-column table with subject, action, and resource. The subject can be an individual user or a group. With access-control lists, each resource is associated with a list, indicating, for each subject, the actions that the subject can exercise on the resource. With capabilities, each subject has an associated list called a capability list, indicating, for each resource, the actions that the user is allowed to exercise on the resource. A locker key can be considered a capability: the locker is the resource, and the user holds the key to the resource.
At the time the user tries to open the locker with the key, you only have to worry about the capabilities of the key—not the capabilities of its owner. An access-control list is resource driven, whereas capabilities are subject driven. These three types of representations are very coarse grained. One alternative is to use policy-based access control. With policy-based access control, you can have authorization policies with fine granularity. In addition, capabilities and access-control lists can be dynamically derived from policies. eXtensible Access Control Markup Language (XACML) is the de facto standard for policy-based access control.
These three types of representations are very coarse grained. One alternative is to use policy-based access control. With policy-based access control, you can have authorization policies with fine granularity. In addition, capabilities and access-control lists can be dynamically derived from policies. eXtensible Access Control Markup Language (XACML) is the de facto standard for policy-based access control.
XACML provides a reference architecture (see Figure 2-4), a request response protocol, and a policy language. Under the reference architecture, it talks about a Policy Administration Point (PAP), a Policy Decision Point (PDP), a Policy Enforcement Point (PEP), and a Policy Information Point (PIP). This is a highly distributed architecture in which none of the components are tightly coupled with each other. The PAP is the place where you author policies. The PDP is the place where policies are evaluated. While evaluating policies, if there is any missing information that can’t be derived from the XACML request, the PDP calls the PIP. The role of the PIP is to feed the PDP any missing information, which can be user attributes or any other required details. The policy is enforced through the PEP, which sits between the client and the service and intercepts all requests. From the client request, it extracts certain attributes such as the subject, the resource, and the action; then it builds a standard XACML request and calls the PDP. Then it gets a XACML response from the PDP. That is defined under the XACML request/response model. The XACML policy language defines a schema to create XACML policies for access control.
Note With the increasing popularity and adaptation of APIs, it becomes crucial for XACML to be easily understood in order to increase the likelihood it will be adopted. XML is often considered too verbose. Developers increasingly prefer a lighter representation using JSON, the JavaScript Object Notation. The profile “Request / Response Interface Based on JSON and HTTP for XACML 3.0” aims at defining a JSON format for the XACML request and response. See https://www.oasis-open.org/committees/document.php?document_id=47775.
Nonrepudiation - Whenever you do a business transaction via an API by proving your identity, later you should not be able to reject it
or repudiate it.
Note TLS ensures authentication (by verifying the certificates), confidentiality (by encrypting the data with a secret key), and integrity (by digesting the data), but not the nonrepudiation. In TLS, the Message Authentication Code (MAC) value of the data transmitted is calculated with a shared secret key, known to both the client and the server. Shared keys can’t be used to achieve nonrepudiation.
Digital signatures provide a strong binding between the user (who initiates the transaction) and the transaction the user performs. A key known only to the user should sign the complete transaction, and the server (or the service) should be able to verify the signature through a trusted broker that vouches for the legitimacy of the user’s key. This trusted broker can be a certificate authority (CA). Once the signature is verified, the server knows the identity of the user and can guarantee the integrity of the data. For nonrepudiation purposes, the data must be stored securely for any future verification.
Auditing - There are two aspects of auditing: keeping track of all legitimate access attempts, to facilitate nonrepudiation; and
keeping track of all illegal access attempts, to identify possible threats. There can be cases where you’re permitted to access a resource, but it should be with a valid purpose. For example, a mobile operator is allowed to access a user’s call history, but it should not do so without a request from the corresponding user. If someone frequently accesses a user’s call history, this can be detected by proper audit trails. Audit trails also play a vital role in fraud detection. An administrator must define fraud-detection patterns, and the audit logs should be evaluated in near real time. Complex event processing is a popular technique used for fraud detection.
Patterns provide solutions for common problems in a way similar to sharing industry best practices. Having a broader understanding of security patterns can help you design solutions. The solutions proposed in security patterns are widely recognized and well tested; hence you need not worry about reinventing the wheel.
Direct Authentication Pattern - An API can be open for anonymous access or protected for limited/restricted access. If it’s anonymous, you need not worry about authentication. Twitter API version 1.0 had a couple of open APIs. The https://api.twitter.com/1/ statuses/public_timeline.json API, which returned the public timeline of a given Twitter user, was an open API.
From version 1.1 onward, all Twitter APIs were made protected. If you make a public API open, be sure you enforce proper rate limits. Otherwise, this could be an invaluable source to carry out a DoS attack.
A public API can be secured for authentication with HTTP Basic/Digest Authentication. Chapter 3 digs into more about HTTP Basic/Digest Authentication. Until then, it’s a way of accessing a protected API by sending a username and a password in the HTTP Authorization header, along with the API invocation request. The limitation here is, you need to own and maintain the user base or the user store. In other words, if your API is available for public access, you also need to have a registration process to bring users into the system, and you own and maintain that user store. HTTP Basic Authentication won’t work in a federated scenario where you want to give access to the users not owned by you. This pattern of authentication is known as Direct Authentication.
Both public and private APIs can be secured with HTTP Basic/Digest Authentication. The difference is in the deployment, where you carry out the authentication check. In the case of a public API, you should carry out the authentication check inside the demilitarized zone (DMZ).
In Figure 2-5, there are three firewalls used to overcome the challenge of enabling access to the user store or the LDAP from the DMZ. It’s a best practice to not to put any databases or user stores into the DMZ. The figure introduces another secured zone called the yellow zone. The user store is inside the yellow zone, which is protected by two firewalls. One firewall is between the DMZ and the yellow zone, and it only allows inbound connections from the API gateway in the DMZ to the yellow zone. The other one is between the green zone and the yellow zone. This only allows inbound connections from the green zone to the yellow zone. With this approach, you share the same user store, having both internal corporate users and external users, with the two API gateways in the DMZ and the green zone. But you never let a connection propagate from the DMZ to the green zone except through ports 80 and 443 to access the application server. The actual API implementation is hosted in the application server.
Note A DMZ is a physical or logical separation between the internal network and the services exposed for a larger, untrusted environment—usually the Internet. In a typical setup, the DMZ has two firewalls: one between the DMZ and the public Internet and the other between the DMZ and the internal network (LAN).
Managing Credentials
In a system protected with HTTP Basic Authentication, you need to be concerned about the confidentiality of credentials. Credentials can be leaked at two stages: while in transit and at rest. To secure credentials in transit, you must use an encrypted channel. For API calls carrying user credentials, you can use HTTP over TLS (HTTPS). Securing the API call isn’t sufficient. A system is secured only to the level of the strength of its weakest link. You also need to think about how the API gateway connects to the user store. In the case of LDAP, you should use LDAP over TLS (LDAPS); and in the case of JDBC, you should use JDBC over TLS.
How do you store passwords? Ideally, passwords should only be known by the owners. They should not even be known by system administrators or people having full access to the system—at the database level. Passwords can be encrypted and stored in the user store. That prevents any attacker from getting access to the user store and seeing user credentials. But system administrators would be able to see passwords in cleartext, given that they have access to the key used to encrypt passwords. Using one-way hashing can prevent this. With hashing, you can pick whatever hashing algorithm you need and apply it to the password in cleartext. That results in a fixed-length hash, which isn’t reversible. In other words, given the hash and the hashing algorithm, you can’t derive the password. Also note that hashing doesn’t involve a key. How does this make your password safe? Anyone having access to the user store can see the hashes, but they can never derive passwords from them. Keep in mind—you can’t log in with a hashed password. But is this safe enough? A hacker who has access to the user store can still replace the hashed password with a hash calculated with a cleartext known to the attacker. Then the attacker can log in to the corresponding account with the cleartext known to him or her—because it’s verified against the hash value the attacker replaced in the database. Hashing alone is never safe. Whenever you store anything in cleartext as a hashed value, you need to store it as a salted hash. In cryptography, a salt comprises random bits that are used as one of the inputs to a key-derivation function. The other input is usually a password or a passphrase in cleartext. The application calculates the hash value of both the password in cleartext and the salt value and stores the salted hash in the database. The application also has to store the salt value. As a best practice, the salt value should be kept secret, separate from the password database. When a user enters their password for login, the application retrieves the salt value, calculates the hash over both the salt and the entered password, and matches the result with the hash value stored in the password database. If a hacker has access to the database and replaces the user’s password with a hash value of a cleartext password known to the attacker, the password verification will fail, because the hash isn’t calculated with the password alone. It's from both the password and the salt value. In this case, if the hacker wants to gain access to user accounts, they must break into the database, which stores salt values as well. The bottom line is, hashing alone is never secure, and salted hashing is much more secure—but all that makes it is harder to break.
Biometric Authentication
Biometric authentication implements the Direct Authentication pattern. Let’s take a fingerprint time-clock attendance recorder as an example (see Figure 2-6). This scans the user’s fingerprint and calls an API at the backend system to authenticate the user. Once the user is authenticated, the recorder has to update another backend system with the date and the time. This also can be done in a single step. The fingerprint scanner directly calls the API of the time-recording system with the fingerprint. The fingerprint goes as binary data on the wire. When it hits the API gateway, it extracts the fingerprint and calls the API of the biometric system to validate the fingerprint. If all goes well, the user’s time is recorded, and the user is granted access to the building.
To prevent any sort of spoofing between the fingerprint scanner and the biometric system, you need to make sure the channel between the scanner and the API gateway, as well as the channel between the API gateway and the biometric system, are on TLS. The API gateway should connect to a biometric database or to a biometric system to complete the authentication process. There are vendors who specifically focus on building biometric systems for authentication, and they do expose APIs that other systems can call.
Sealed Green Zone Pattern
In Figure 2-5, given the way the deployment is layered, the DMZ has an open connection to the green zone via ports 80/443. Some system administrators are extremely strict about connections between the DMZ and the green zone, whereas others don’t worry about opening ports 443 and 80 to the green zone. For extremely tight security, you should not open any inbound ports to the green zone. That leaves you with a challenge: how do you access any services running in the green zone from the DMZ? In Figure 2-7, no ports are open toward the green zone. That restricts anyone from making connections into the green zone. To facilitate communication between API gateway in the DMZ and the application server in the green zone, you use a message broker. The message broker has a queue, and whenever the API gateway gets a request, it authenticates the request first and publishes the message into the queue. The application server from the green zone subscribes to the same queue to receive messages. This is possible because it’s okay to open outbound connections from the green zone to the DMZ. A similar channel is used to send back the responses to the API gateway in the DMZ
Least Common Mechanism Pattern
In Figure 2-5, both the internal and external user accounts are in the same user store. It’s always recommended that you keep external user accounts in a different user store. Ideally, this should be a separate physical user store, as in Figure 2-7. Then you don’t need a connection between the green zone and the yellow zone, because you can keep the user store with internal users in the green zone. The principle of least common mechanism concerns the risk of sharing infrastructure among different components.
Brokered Authentication Pattern
Password-based authentication only facilitates the Direct Authentication pattern, where you need to have control over the user store under you. Certificate-based authentication supports both the Direct Authentication pattern as well as the Brokered Authentication pattern. In direct authentication, each user in your system has a certificate stored in the user store against their name. Once the validation process (or the handshake) in SSL mutual authentication is completed, the system checks whether it has a user with that given certificate. The system looks for each individual certificate during the authentication process. With the Brokered Authentication pattern, you don’t need to look for each individual certificate. You only go through the validation process in SSL mutual authentication and then check whether the CA that signed the client certificate is trusted. If the certificate is from a trusted CA, the system lets the user in. Figure 2-8 illustrates the Brokered Authentication pattern with certificates.
The deployment in Figure 2-9 illustrates how to enforce XACML-based authorization on APIs. Just as with authentication, for external inbound calls, you also need to enforce authorization checks in the DMZ. That makes sure only legitimate requests pass through to the green zone.
The request from the end user hits the API gateway first and completes the authentication process to identify the user who invokes the API. Then it creates a XACML request using the identified user as the subject, the context of the API as the resource, and the HTTP method as the action, and calls the XACML PDP. The XACML PDP evaluates the request against the policies loaded from the XACML Policy Store. After the evaluation, it returns the decision in a XACML response.
Listing 2-1. Sample XACML Request
foo GET http://api.gateway/barListing 2-2 shows a sample XACML response generated from the XACML PDP. The result is “Permit”. Listing 2-2. Sample XACML Response Permit
Listing 2-3 shows the sample XACML policy corresponding to the previous XACML request and response. The policy returns “Permit” for any user doing a GET on http://api.gateway/bar. All other actions will be denied.
Listing 2-3. Sample XACML Policy http://api.gateway/bar GET
When you’re building authorization policies, there are two main concepts you should take into consideration: the principle of least privilege and segregation of duties. When giving users access rights to resources in the system, you should give them only the bare minimum set of permissions to perform the expected actions, and no more. With segregation of duties, you need to make sure the ability to complete a critical task is divided between more than one person. For example, the person responsible for adding users to the system should be different from the person responsible for approving such actions. Being compliant with these two concepts will minimize security vulnerabilities that could creep into the system due to human errors.
■ Note Everything discussed so far has been related to direct access control. There is another derivation from this: delegated access control. OAuth is the de facto standard for delegated access control. Chapter 7 talks more about OAuth and how XACML can be integrated with it. Delegated access control is all about giving someone else access to a resource you own so that they can perform actions on your behalf.
Threat modeling is a methodical, systematic approach to identifying possible security threats and vulnerabilities in a system deployment. First you need to identify all the assets in the system. Assets are the resources you have to protect from intruders. These can be user records/credentials stored in an LDAP, data in a database, files in a file system, CPU power, memory, network bandwidth, and so on. Identifying assets also means identifying all their interfaces and the interaction patterns with other system components. For example, the data stored in a database can be exposed in multiple ways. Database administrators have physical access to the database servers. Application developers have JDBC-level access, and end users have access to an API.
Once you identify all the assets in the system to be protected and all the related interaction patterns, you need to list all possible threats and associated attacks. Threats can be identified by observing interactions, based on the CIA triad. In Figure 2-10, you see three communication links or interactions. From the application server to the database is a JDBC connection. A third party can eavesdrop on that connection to read or modify the data flowing through it. That’s a threat. How does the application server keep the JDBC connection username and password? If they’re kept in a configuration file, anyone having access to the application server’s file system can find them and then access the database over JDBC. That’s another threat. The JDBC connection is protected with a username and password, which can potentially be broken by carrying out a brute-force attack. Another threat.
Administrators have direct access to the database servers. How do they access the servers? If access is open for SSH via username/password, then a brute-force attack is likely a threat. If it’s based on SSH keys, where those keys are stored? Are they stored on the physical personal machines of administrators or uploaded to a key server? Losing SSH keys to an intruder is another threat. How about the ports? Have you opened any ports to the database servers, where some intruder can telnet and get control or carry out an attack on an open port to exhaust system resources? Can the physical machine running the database be accessed from outside the corporate network? Is it only available over VPN? All these questions lead you to identifying possible threats against the database server.
End users have access to the data via the API. This is a public API, which is exposed from the corporate firewall. A brute-force attack is always a threat if the API is secured with HTTP Basic/Digest Authentication. Having broken the authentication layer, anyone could get free access to the data. Another possible threat is an attacker getting access to the confidential data that flows through the transport channels. Executing a man-in-the-middle attack can do this. DoS is also a possible threat. An attacker can send carefully crafted, malicious, extremely large payloads to exhaust server resources.
STRIDE is a popular technique to identify threats associated with a system in a methodical manner. STRIDE stands for Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Escalation of privileges. Table 2-2 compares STRIDE with the security properties discussed at the start of the chapter.
Table 2-2. Security Properties vs. Threats
Authentication Spoofing Integrity Tampering Nonrepudiation Repudiation Confidentiality Information disclosure Availability Denial of service Authorization Escalation of privileges
Once you’ve identified all the possible threats and associated attacks, you can start planning attacks. This requires tooling support. You have to identify what tools would be used to carry out a brute-force attack, a DoS attack, and so on. Once the test matrix is planned against all possible threats, you can begin executing. At the end of the test, you can identify all possible vulnerabilities in your system. Then you need to think about countermeasures to mitigate them.
Threat modeling is an exercise that must be carried out against any serious enterprise deployment before moving to production. A proper threat-modeling exercise includes business analysts, solution architects, system architects, developers, and testers. Each one has a role to play. The challenge faced by the moderator is to capture all the bits and pieces, resolve any contradictions, and come up with all possible data-flow diagrams. A single missing data-flow diagram could easily put your company on the news the day after you move to production—which could result in a huge loss in customer confidence.
Summary
This chapter focused on building a solid foundation for the rest of the book by introducing core security principles. It covered security principles, design challenges, security patterns and best practices, security properties, and threat-modeling techniques.
In the next chapter, we are going to discuss** HTTP basic and digest authentication** as means of securing APIs for legitimate access.
HTTP Basic Authentication and Digest Authentication are popular for protecting resources on the web. Both are based on usernames and passwords. HTTP/1.0 includes the specification for the Basic Access Authentication scheme, which takes the username and password over the network in cleartext. Hence it isn’t considered to be a secured way of authenticating users, unless it’s used over an externally secured system such as Transport Level Security (TLS). RFC 2617 defines the specification for HTTP’s authentication framework (the original Basic Access Authentication scheme) and Digest Access Authentication, which is based on cryptographic hashes. Unlike Basic Authentication, Digest Authentication doesn’t take the user’s password over the wire in cleartext.
Transport Layer Security (TLS) mutual authentication, also known as client authentication or two-way Secure Socket Layer (SSL), is part of the TLS handshake process. In one-way TLS, only the server proves its identity to the client; this is mostly used in e-commerce to win consumer confidence by guaranteeing the legitimacy of the e-commerce vendor. In contrast, mutual authentication authenticates both parties—the client and the server
Identity delegation plays a key role in enterprise security. You could be the owner but not the direct consumer of the API. There may be a third party who wants to access it on your behalf. Sharing credentials with a third party who wants to access a resource you own on your behalf is an anti-pattern. Most web-based applications and APIs developed prior to 2006 utilized credential sharing to facilitate identity delegation. Post-2006, many vendors started developing their own proprietary ways to address this concern without credential sharing. Yahoo BBAuth, Google AuthSub, and Flickr Authentication are some of the implementations that became popular. Any identity-delegation model has three main roles: delegator, delegate, and service provider. The delegator owns the resource and is also known as the resource owner. The delegate wants to access a service on behalf of the delegator. The delegator delegates a limited set of privileges to the delegate to access the service. The service provider hosts the protected service and validates the legitimacy of the delegate. The service provider is also known as the resource server.
As discussed in the last section of Chapter 5, OAuth 1.0 was the first step toward the standardization of identity delegation. OAuth involves three parties in an identity delegation transaction. The delegator, also known as the user, assigns access to his or her resources to a third party. The delegate, also known as the consumer, accesses a resource on behalf of its user. The application that hosts the actual resource is known as the service provider. This terminology was introduced in the first release of the OAuth 1.0 specification under oauth.net. It changed a bit when the OAuth specification was brought into the IETF working group. In OAuth 1.0, RFC 5849, the user (delegator) is known as the resource owner, the consumer (delegate) is known as the client, and the service provider is known as the server.
OAuth 2.0 is a major breakthrough in identity delegation. It has its roots in OAuth 1.0, but OAuth WRAP primarily influenced it. The main difference between OAuth 1.0 and 2.0 is that OAuth 1.0 is a standard protocol for identity delegation, whereas 2.0 is a highly extensible framework. OAuth 2.0 is already the de facto standard for API security and is widely used across leading web sites including Facebook, Google, LinkedIn, Microsoft (MSN, Live), PayPal, Instagram, Foursquare, GitHub, Yammer, Meetup, and many more. There is one popular exception: Twitter still uses OAuth 1.0.
The OAuth 2.0 core specification doesn’t mandate any specific token type. It’s one of the extension points introduced in OAuth 2.0. Almost all public implementations use the OAuth 2.0 Bearer Token Profile. This came up with the OAuth 2.0 core specification, but as an independent profile, documented under RFC 6750. Eran Hammer, who was the lead editor of the OAuth 2.0 specification by that time, introduced the MAC Token Profile for OAuth 2.0. (Hammer also led the OAuth 1.0 specification.) Since its introduction to the OAuth 2.0 IETF working group in November 2011, the MAC Token Profile has made a slow progress. The slow progress was mostly due to the fact that the working group was interested in building a complete stack around bearer tokens before moving into another token type. In this chapter, we will take a deeper look into the OAuth 2.0 MAC token profile and its applications.
OAuth 2.0 is a framework for delegated authorization. It doesn’t address all specific enterprise API security use cases. The OAuth 2.0 profiles built on top of the core framework work to build a security ecosystem to make OAuth 2.0 ready for enterprise grade deployments. OAuth 2.0 introduced two extension points via grant types and token types. The profiles for OAuth 2.0 are built on top of this extensibility. This chapter talks about four key OAuth 2.0 profiles for token introspection, chained API invocation, dynamic client registration, and token revocation.
User Managed Access (UMA, pronounced “OOH-mah”) is an OAuth 2.0 profile. OAuth 2.0 decouples the resource server from the authorization server. UMA takes one step forward: it lets you control a distributed set of resource servers from a centralized authorization server. It also enables the resource owner to define a set of policies at the authorization server, which can be evaluated at the time a client is granted access to a protected resource. This eliminates the need for the resource owner’s presence to approve access requests from arbitrary clients or requesting parties. The authorization server can make the decision based on the policies defined by the resource owner.
Recent research performed by Quocirca confirms that many businesses now have more external users who interact with enterprise applications than internal ones. In Europe, 58% of businesses transact directly with users from other firms and/or consumers. In the UK alone, the figure is 65%. If you look at recent history, most enterprises today grow via acquisitions, mergers, and partnerships. In the United States alone, the volume of mergers and acquisitions totaled $865.1 billion in the first nine months of 2013, according to Dealogic. That’s a 39 percent increase over the same period of the previous year, and the highest nine-month total since 2008. What does this mean for API security? It indicates that you need to have the ability to deal with multiple heterogeneous security systems across borders
Enabling Federation
Federation, in the context of API security, is about propagating user identities across distinct identity-management systems or distinct enterprises. Let’s start with a simple use case where you have an API exposed to your partners. How would you authenticate users from different partners? These users belong to the external partners and are managed by them. HTTP Basic Authentication won’t work. You don’t have access to the external users’ credentials and, at the same time, you don’t dare expose an LDAP or a JDBC connection outside your firewall to external parties. Asking for usernames and passwords simply doesn’t work in a federation scenario. Would OAuth 2.0 work? To access an API secured with OAuth, the client must present an access token issued by the owner of the API. Users from external parties have to authenticate first with the OAuth authorization server and then obtain an access token. Neither the Authorization Code grant type nor the Implicit grant type mandates how to authenticate users at the authorization server. It’s up to the authorization server to decide. If the user is local to the authorization server, then it can use a username and password or any other direct authentication protocol. If the user is from an external entity, then you have to use some kind of brokered authentication.
OpenID Connect was ratified as a standard by its membership on February 26, 2014. OpenID Connect provides a lightweight framework for identity interactions in a RESTful manner. It was developed under the OpenID Foundation and has its roots in OpenID, but it was greatly affected by OAuth 2.0.
Chapter 2 touched on some of the key patterns surrounding API security. This chapter expands on that discussion with more concrete details. Here we present ten API security patterns to address the ten most common enterprise security problems. All of the patterns are derived from the concepts and theories discussed in previous chapters.
Direct Authentication with the Trusted Subsystem Pattern
Suppose a medium-scale enterprise has a limited number of RESTful APIs. Company employees are allowed to access these APIs via a single web application while they’re behind the company firewall. All user data is stored in a Microsoft Active Directory, and the web application is connected to it to authenticate users. The web application passes the logged-in user’s identifier to the back-end APIs, and it retrieves data related to the user. The problem is straightforward, and Figure 14-1 illustrates the solution. You need to use some kind of directauthentication pattern. User authentication happens at the front-end web application, and once the user is authenticated, the web application needs to access the back-end APIs. The catch here is that the web application passes the logged-in user’s identifier to the API. That implies that the APIs can be invoked in a user-aware manner by the web application.
You need to worry not about authenticating the end user to the back-end API, but about authenticating them to the web application. This is the Trusted Subsystem pattern. The web application acts as the trusted subsystem. In such a scenario, the best way to secure APIs is through Transport Layer Security (TLS) mutual authentication. All requests generated from the web application are secured with TLS mutual authentication. In some scenarios, there is a resistance to using TLS due to the overhead it adds. In such cases, in a controlled environment, security between the application server and the container that hosts APIs can be achieved at the network level. Network-level security must provide the assurance that no component other than the web application server can talk to the container that hosts the APIs.
Single Sign-On with the Delegated Access Control Pattern
Single Sign-On with the Integrated Windows Authentication Pattern
Identity Proxy with the Delegated Access Control Pattern
Delegated Access Control with the JSON Web Token Pattern
Nonrepudiation with the JSON Web Signature Pattern
Chained Access Delegation Pattern
Trusted Master Access Delegation Pattern
Resource Security Token Service (STS) with the Delegated Access Control Pattern
Delegated Access Control with the Hidden Credentials Pattern