SBN

Making your APIs Safe: How to Test REST, gRPC, and GraphQL

No matter what approach you take to building your API, it’s important to test your API for security. In a previous post, we talked about the key features of REST, gRPC, and GraphQL APIs

In this post, we’ll first cover general principles of API security, then we’ll break down specific recommendations and examples for testing REST, gRPC and GraphQL. 

Core Principles of Security Testing for APIs

API security isn’t a one and done task. While it may generate a lot of buzz as an ‘emerging technology’ or ‘new market’, the principles of API security aren’t much different than those for any other cybersecurity discipline. Securing your APIs requires effective testing to identify risks, as well as appropriate measures to mitigate risks where possible. 

No matter the type of API, when conducting API security testing you should always: 

  1. Verify proper authentication and authorization: This means making sure that only those with the correct credentials can access an API or associated resources. To do this, you should closely examine how user authentication is handled and review all user roles and privileges.

  2. Monitor access control measures: Access control measures define who can access what through your API. You should monitor these measures to ensure that only intended users have access.

  3. Perform input validation: Input validation is a crucial component of API security testing, as it helps prevent malicious data from entering your system through the API. All user-supplied data must be examined and verified before sending it to the server. 

  4. Scan for vulnerabilities regularly: Vulnerability scanning should be done on a regular basis to identify any potential security issues, such as SQL injections and cross-site scripting (XSS). This will help you take action quickly and reduce the risk of serious damage.

  5. Encrypt sensitive data: All sensitive data stored or transferred through the API should be encrypted at all times to protect it from unauthorized access.

  6. Use secure protocols: When using web services, always use SSL or TLS protocols for secure communication between the client and server. 

  7. Implement a logging system: Logging is an essential part of any security system and allows you to track user activity and detect malicious behavior. 

The exact ways you test should be tailored to your team and needs. In general, the less friction that security testing presents, the better. Having actionable results delivered to your team without requiring them to change their workflows will drive more risk awareness and increase your risk mitigation.

Complete API Security in 5 Minutes

Get started with Mayhem today for fast, comprehensive, API security. 

Get Mayhem for API Free

 

Testing RESTFul APIs

REST APIs use standard HTTP methods, such as GET or PUT and support formats like JSON and XML. While Restful APIs are an architectural approach rather than a defined spec, there are several aspects that are distinct when testing them. 

REST APIs expose multiple endpoints that correspond to different resources. Test cases should be created for each endpoint, covering various HTTP methods, query parameters, and request/response payloads. 

You should ensure that REST API tests validate the HTTP status codes returned by the API, such as 200 (OK), 201 (Created), 400 (Bad Request), and 500 (Internal Server Error), as well as that API responses are in the expected data format (e.g. JSON, XML)

For example, you might run a test of the users endpoint with the GET method, to ensure that expected data is returned:

GET /api/users/1

Expected response:

{ "id": 1, "name": "John Doe", "email": "[email protected]" }

Moving beyond basic testing, it’s important to ensure your API not only functions as expected, but is secure as well. Considerations for testing RESTful APIs include:

  • Authentication and Authorization: Test the implementation of authentication and authorization mechanisms, such as OAuth, JWT, or API keys. Ensure that unauthorized access attempts are correctly handled and that users have access only to the resources they are permitted to access.

  • Input Validation: Test for potential injection attacks, such as SQL injection or XSS, by sending malicious input data in query parameters, request headers, or request payloads.

  • Rate Limiting: Verify that the API enforces rate limiting to prevent DoS attacks or abuse.

  • Transport Layer Security: Ensure that the API enforces HTTPS to protect data in transit.

  • CORS (Cross-Origin Resource Sharing) Configuration: Verify the correct implementation of CORS policies to prevent unauthorized access from other domains.

As an example, input validation testing can be performed with a simple request that delivers a SQL injection payload:

GET /api/users?email=' OR 1=1;--

The API should respond with an error indicating that the input is not valid, and the SQL injection attempt should be blocked.

 

Testing gRPC APIs

gRPC (gRPC Remote Procedure Call) is an open-source, high-performance RPC framework that uses Protocol Buffers for serialization and HTTP/2 for transport. gRPC APIs are strongly typed, which can simplify testing by reducing ambiguity.

gRPC APIs expose services with defined methods, which should be tested individually. Test cases should cover various input parameters, return types, and error handling. For example, testing a gRPC method to fetch user details will look similar to the below:

service UserService {
  rpc GetUser (GetUserRequest) returns (User) {}
}

Because gRPC APIs use HTTP/2 and Protocol Buffers, they can be less prone to some traditional web-based attacks. However, they still require careful testing across several factors:

  • Authentication and Authorization: Test the implementation of authentication and authorization mechanisms, such as OAuth or token-based authentication. Ensure that unauthorized access is handled appropriately and that users have the necessary permissions.

  • Input Validation: Test for potential injection attacks by sending malformed Protocol Buffer messages, as well as validating the input data on the server-side.

  • Rate Limiting: Ensure that the API enforces rate limiting to prevent DoS attacks or abuse.

  • Transport Layer Security: Verify that the API enforces TLS (Transport Layer Security) to protect data in transit.

  • Service-Level Access Control: Test the access control policies at the service and method levels to prevent unauthorized access.

Example: Testing for unauthorized access in a gRPC API method. Test case:

service UserService {
  rpc GetUser (GetUserRequest) returns (User) {}
}

 

Attempt to access the GetUser method without a valid authentication token:

import grpc
from user_service_pb2 import GetUserRequest
from user_service_pb2_grpc import UserServiceStub

channel = grpc.insecure_channel('localhost:50051')
stub = UserServiceStub(channel)

request = GetUserRequest(id=1)
response = stub.GetUser(request)

The API should respond with an error indicating that the request is unauthorized, and access to the GetUser method should be blocked.

 

Testing GraphQL

GraphQL is a query language and runtime for APIs that enables clients to request only the data they need. It supports a single endpoint, which can handle multiple queries and mutations. Test cases should be created for each query and mutation, covering different input parameters, return types, and error handling. For example: 

query {
  user(id: 1) {
    id
    name
    email
  }
}

When testing GraphQL APIs, it’s important to validate schema, as well as to undergo extensive performance testing to ensure the API can handle complex queries and large datasets.

GraphQL APIs have unique security concerns due to their flexible query language and single endpoint. Key security testing aspects for GraphQL APIs include:

  • Authentication and Authorization: Test the implementation of authentication and authorization mechanisms, such as OAuth, JWT, or API keys. Verify that unauthorized access is handled correctly and that users have the necessary permissions.

  • Input Validation: Test for potential injection attacks by sending malicious input data in GraphQL queries and mutations.

  • Rate Limiting and Query Complexity: Ensure that the API enforces rate limiting and query complexity limits to prevent DoS attacks or resource exhaustion.

  • Transport Layer Security: Verify that the API enforces HTTPS to protect data in transit.

  • Field-Level Access Control: Test the access control policies at the field level to prevent unauthorized access to sensitive data.

  • Introspection Query Protection: Ensure that introspection queries, which provide information about the API schema, are protected from unauthorized access.

 For example, testing for excessive resource usage in a GraphQL API:

query {
  allUsers {
    id
    name
    posts {
      id
      title
      comments {
        id
        content
      }
    }
  }
}

The above query has no limits on it—query depth or pagination are both missing. The API should respond with an error indicating that the query complexity or depth limit has been exceeded, and the resource-intensive query should be blocked.  

 

Comprehensive API Security Testing

These are just a few examples of security testing for REST, gRPC, and GraphQL APIs. In practice, developers should perform a comprehensive security assessment, including various types of attacks and vulnerabilities, to ensure the overall security of their APIs.

Mayhem: An API Testing Solution

Regardless of what approach you take to building an API, it’s important to ensure you’re undergoing appropriate security testing. Mayhem automatically tests APIs and integrates easily into your CI/CD pipeline, allowing developers to get meaningful testing results in under five minutes. Try it free for 30 days.

*** This is a Security Bloggers Network syndicated blog from Latest blog posts authored by Josh Thorngren. Read the original post at: https://forallsecure.com/blog/making-your-apis-safe-how-to-test-rest-grpc-and-graphql