gRPC (gRPC Remote Procedure Call) is a protocol that is gaining a lot of traction in the microservices world and is becoming a popular alternative for developers to use instead of REST (representational state transfer). Many organizations are trying to adopt gRPC, and technology blog sites are abuzz with chatter about choosing between REST and gRPC APIs.
Recently, F5 Labs learned that a large organization had challenges with gRPC-enabled applications aligning to the Zero Trust security model, as many conventional security tools do not cover gRPC as a protocol. So, we at F5 Labs decided to write a demo gRPC application to boost understanding and to test some of the security controls. This article briefly introduces gRPC and shares details on setting up a vulnerable demo application.
What is gRPC?
A remote procedure call (RPC) is used by a program to call a subroutine that is available on another computer as though it were available locally. To support different kinds of clients, RPCs use an interface description language (IDL).1 gRPC is the latest iteration of RPC. It uses HTTP/2 for transport and Protocol Buffers (protobufs) (alternate data formats like JSON can be used) as the IDL. Protocol Buffers is a mechanism for serializing structured data useful for transmitting or storing. It produces compact binary messages.
The website grpc.io defines gRPC as a modern, open source remote procedure call framework that can run anywhere.2 It enables client–server applications to communicate transparently and makes it easier to build connected systems. It is a Cloud Native Computing Foundation (CNCF) project and is used by several organizations like Google, Netflix, Docker, and others.
The sample architecture in Figure 1 shows a cluster of gRPC servers communicating with a gRPC client.
Design principles of gRPC provide significant advantages compared to RESTful styles of APIs in terms of client libraries and performance. This makes it a suitable choice for inter-service API calls. Advantages come in the form of:
- Data format: Use of protocol buffers leads to smaller payloads, improving the performance of gRPC
- Contracts: Service definitions are mandatory, unlike Open API specs for RESTful APIs
- Streaming: Support for client, server, and bi-directional streaming
- Multi-language support: gRPC supports cross-language invocations; server code can be written in Java whereas the client language can be Python
- Client code generation: Native support for generating codes in multiple languages such as Python, Go, and Java1
- Server stub generation: Developers need to focus on business logic, while the process for serialization, parsing, validation, etc. are autogenerated
The Security Concern with gRPC
As the adoption of gRPC rises, security operations teams need to measure the effectiveness of existing security solutions towards the protocol. As an example, gRPC messages are in binary format, which might cause issues in the inspection process with inspection devices that expect to see ASCII-based communications.
gRPC-based APIs need defense against modern-day challenges, and the security checks listed below are needed:
- Content validation: Weed out malicious payload within the binary messages
- Protection against accidental disclosures: Mask or block sensitive data leaving the system
- Application of rate limits: Rate limit a malicious client
- Authentication: Enforce authentication and authorization prior to granting access to data
The Practice Range
Security practitioners can set up an environment to test the efficacy of their tools for gRPC by either pulling down the containers from docker hub2 or building the code base available on github3 for the Hello Nerd application.
Hello Nerd Application
This is a simple application built in Python. It responds to a user’s gRPC call with a random message.
Steps to pull down the containers and set up a test environment
- Pull down the image
docker pull sbacker/hellonerd:v1
- Create instance for server
docker run --name hellonerd_s -d sbacker/hellonerd:v1 python server.py
- Get IP address for the hellonerd server
docker inspect hellonerd_s | grep IPAddress
- Create a client instance
docker run --name hellonerd_c --rm sbacker/hellonerd python client.py shaan 172.17.0.2 50055 --normal
Vulnerabilities Built into the Hello Nerd Application
The application is built with the following three vulnerabilities:
- There is no user input validation, however, the response changes when the server detects special characters in user input to show the attack went through.
docker run --name hellonerd_c --rm sbacker/hellonerd:v1 python client.py “1\’ OR 1=1” 172.17.0.2 50055 –normal
- Accidental disclosure of credit card numbers.
docker run --name hellonerd_c --rm sbacker/hellonerd:v1 python client.py shaan 172.17.0.2 50055 --norm
- No application of rate limits. Usage of –detonate option on clients starts firing the request in a loop.
gRPC is gaining in popularity as the compact format of messages with protobuf and usage of HTTP/2 bring significant performance improvements. It is critical for security teams to assess their tools’ effectiveness for this protocol. The Hello Nerd application can be a starting point in testing security controls.