BLOG | NGINX

Tutorial: Deliver and Secure GraphQL APIs with F5 NGINX

NGINX-Part-of-F5-horiz-black-type-RGB
Akash Ananthanarayanan Thumbnail
Akash Ananthanarayanan
Published July 20, 2023

Developers are increasingly embracing GraphQL as a preferred method to build APIs. GraphQL simplifies retrieving data from multiple sources, streamlining data access and aggregation. By querying multiple data sources with one POST request from a single endpoint, developers using GraphQL can precisely request the data they need from various sources. This approach helps solve limitations encountered in REST API architectures, where problems like under-querying (requests lacking all the necessary data) or over-querying (requests going to multiple endpoints and gathering excessive data) can occur.

GraphQL is the optimal choice for microservices architectures, as it grants clients the ability to retrieve only the essential data from each service or data source. This fosters heightened flexibility and agility, which are critical components to thrive in a modern business environment.

Security Is Critical for GraphQL APIs

With a greater degree of access and flexibility, GraphQL APIs also present a more extensive attack surface that’s enticing to bad actors. Despite being relatively new, GraphQL is still prone to many of the same vulnerabilities found in other API architectures. Fortunately, you can protect GraphQL APIs from these common threats by leveraging some of your existing infrastructure and tools.

Tutorial Overview

This tutorial helps build an understanding of how to deliver and secure GraphQL APIs. We illustrate how to deploy an Apollo GraphQL server on F5 NGINX Unit with F5 NGINX Plus as the API gateway. In addition, we show how to deploy F5 NGINX App Protect WAF at the API gateway for advanced security and use F5 NGINX Management Suite to configure your WAF and monitor for potential threats. This setup also allows you to use NGINX App Protect WAF to detect attacks like SQL injection.

Follow the steps in these sections to complete the tutorial:

Architecture with NGINX providing security and authentication for GraphQL APIs, monitoring for attacks, and the Apollo GraphQL server running on NGINX Unit
Figure 1: Architecture with NGINX Plus and NGINX App Protect WAF providing security and authentication for GraphQL APIs, NGINX Management Suite monitoring for attacks, and the Apollo GraphQL server running on NGINX Unit

Prerequisites

Before you begin this tutorial, you need the following:

Install and Configure NGINX Management Suite Security Monitoring

NGINX Management Suite integrates several advanced features into a unified platform to simplify the process of configuring, monitoring, and troubleshooting NGINX instances. It also facilitates the management and governance of APIs, optimizes application load balancing, and enhances overall security for organizations.

Follow these steps to install and configure NGINX Management Suite:

  • Follow the instructions on the Virtual Machine or Bare Metal page of the Installation page. This page includes the Security Monitoring module (used in this tutorial) and other modules you may install at your discretion.
  • Add the license for each installed module.
  • Install the NGINX Agent package from the NGINX Management Suite host and set up Security Monitoring for NGINX App Protect instances by following the instructions here.

Deploy NGINX Unit and Install the Apollo GraphQL Server

NGINX Unit is an efficient and streamlined runtime application with a lightweight design, making it an ideal choice for organizations seeking high performance without compromising speed or agility. It’s an open-source server that can handle TLS, request routing, and run application code. You can learn more about NGINX Unit on its Key Features page.

In this tutorial, we use Express as a Node.js web application framework on NGINX Unit that offers extensive capabilities for constructing an Apollo GraphQL server. At the time of this writing, the current version is Apollo Server 4.

Follow these steps to deploy NGINX Unit and install the Apollo GraphQL server:

  1. Install NGINX Unit on a supported operating system.
  2. Follow the GitHub repo to build an Apollo GraphQL server and create your Apollo GraphQL hello app.

Deploy NGINX Plus as an API Gateway and Install NGINX App Protect WAF

Select a suitable environment to deploy an NGINX Plus instance. In this tutorial, we use an AWS Ubuntu instance and set up an API gateway reverse proxy using NGINX Plus. We then deploy NGINX App Protect WAF in front of our API gateway for added security.

Follow these instructions to install NGINX Plus and NGINX App Protect WAF:

  1. Install NGINX Plus on a supported operating system.
  2. Install the NGINX JavaScript module (njs).
  3. Add the load_modules in the nginx.conf directory.
  4. load_module modules/ngx_http_js_module.so;load_module modules/ngx_stream_js_module.so;
  5. Install NGINX App Protect WAF on a supported operating system.
  6. Add the NGINX App Protect WAF module to the main context in the nginx.conf file:
  7. load_module modules/ngx_http_app_protect_module.so;
  8. Enable NGINX App Protect WAF on an http/server/location context in the nginx.conf file:
  9. app_protect_enable on;
  10. Create a GraphQL policy configuration in the directory /etc/app_protect/conf. For further information on how to create an NGINX App Protect WAF policy, please refer to the relevant guidelines.

    Here is an example GraphQL policy configuration:

  11. {   "name": "graphql_policy",
          "template": {
              "name": "POLICY_TEMPLATE_NGINX_BASE"
          },
          "applicationLanguage": "utf-8",
          "caseInsensitive": false,
          "enforcementMode": "blocking",
          "blocking-settings": {
              "violations": [
                  {
                      "name": "VIOL_GRAPHQL_FORMAT",
                      "alarm": true,
                      "block": false
                  },
                  {
                      "name": "VIOL_GRAPHQL_MALFORMED",
                      "alarm": true,
                      "block": false
                  },
                  {
                      "name": "VIOL_GRAPHQL_INTROSPECTION_QUERY",
                      "alarm": true,
                      "block": false
                  },
                  {
                      "name": "VIOL_GRAPHQL_ERROR_RESPONSE",
                      "alarm": true,
                      "block": false
                  }
              ]
          } 
  12. To enforce GraphQL settings, update the app_protect_policy_file field with the GraphQL policy name in the nginx.conf file. Once you have updated the file, perform an NGINX reload to enforce the GraphQL settings.

    Here is an example of the nginx.conf file that includes an NGINX App Protect policy:

  13. user nginx;  worker_processes  4;
      load_module modules/ngx_http_js_module.so;
      load_module modules/ngx_stream_js_module.so; 
      load_module modules/ngx_http_app_protect_module.so;
      error_log /var/log/nginx/error.log debug;
      events {
          worker_connections  65536;
      }
    http {     include       /etc/nginx/mime.types;     default_type  application/octet-stream;     sendfile        on;     keepalive_timeout  65;     server {         listen       <port>;         server_name  <name>;         app_protect_enable on;         app_protect_security_log_enable on; # This section enables the logging capability         app_protect_security_log "/etc/app_protect/conf/log_sm.json" syslog:server=127.0.0.1:514; # This is where the remote logger is defined in terms of: logging options (defined in the referenced file), log server IP, log server port         app_protect_security_log "/etc/app_protect/conf/log_default.json" /var/log/app_protect/security.log;         proxy_http_version 1.1;            location / {             client_max_body_size 0;             default_type text/html;             proxy_pass http://<ip addr>:<port>$request_uri;#<ip addr> of Nginx unit         }         location /graphql {             client_max_body_size 0;             default_type text/html;             app_protect_policy_file "/etc/app_protect/conf/graphql_policy.json";             proxy_pass http://<ip addr>:<port>$$request_uri; #<ip addr> of Nginx unit         
            }     } }
  14. Restart NGINX Plus by running this command:
  15.    

    $ nginx -s reload

Test the Configuration

Now you can test your configuration by following these steps:

  1. Start the Apollo GraphQL application by navigating to the NGINX Unit server and typing in this command:
  2. $ curl -X PUT --data-binary @demo.json --unix-socket /var/run/control.unit.sock http://localhost/config
  3. After a successful update, you should see that the app is available on the listener’s IP address and port:
  4. {          "success": "Reconfiguration done."
      }
  5. To access the Apollo GraphQL server, open your web browser and paste the public IP address of your server. For example: http://3..X.X.X:4003/graphql (this example uses port 4003).
  6. To test the application, enter the correct GraphQL query and run the query.
  7. Screenshot of Apollo GraphQL UI playground
    Figure 2: Apollo GraphQL UI playground
  8. Consider a situation where an individual inputs an SQL injection into a query. In this case, NGINX App Protect WAF safeguards the Apollo GraphQL server and produces a support ID that describes the nature of the attack.
  9. $ curl -X POST http://3.X.X.X:4003/graphql/ -H "Content-Type:application/json" -d '{"query": "query {hello OR 1=1;} "}'
    <html><head><title>Request Rejected</title></head><body>The requested URL was rejected. Please consult with your administrator.<br><br>Your support ID is: 7313092578494613509<br><br><ahref='javascript:history.back();'>[GoBack]</a></body><html>
  10. To check the attack’s details, refer to the NGINX Plus instance’s logs, which are located in /var/log/app_protect/security.log.
  11. attack_type="Non-browser Client,Abuse of Functionality,SQL-Injection,Other Application Activity,HTTP Parser Attack",blocking_exception_reason="N/A",date_time="2023-07-05 21:22:38",dest_port="4003",ip_client="99.187.244.63",is_truncated="false",method="POST",policy_name="graphql_policy",protocol="HTTP",request_status="blocked",response_code="0",severity="Critical",sig_cves="N/A,N/A",sig_ids="200002147,200002476",sig_names="SQL-INJ expressions like ""or 1=1"" (3),SQL-INJ expressions like ""or 1=1"" (6) (Parameter)",sig_set_names="{SQL Injection Signatures},{SQL Injection Signatures}",src_port="64257",sub_violations="HTTP protocol compliance failed:Host header contains IP address",support_id="7313092578494613509",
  12. In the NGINX Management Security Monitoring module, you can monitor the data of your instances and review potential threats, as well as adjust policies as needed for optimal protection.
  13. Screenshot of overview of the NGINX Management Suite Security Monitoring module
    Figure 3: Overview of the NGINX Management Suite Security Monitoring module
    Screenshot of comprehensive summary of security violations in the Security Monitoring module
    Figure 4: Comprehensive summary of security violations in the Security Monitoring module

Conclusion

In this tutorial, you learned how to set up an Apollo GraphQL Server on NGINX Unit, deploy NGINX Plus as an API gateway, and secure your GraphQL APIs with NGINX App Protect WAF in front of your API gateway.

You can also use NGINX Management Suite Security Monitoring to identify and block common advanced threats before they compromise your GraphQL APIs. This simple architecture defends GraphQL APIs from some of the most common API vulnerabilities, including missing authentication and authorization, injection attacks, unrestricted resource consumption, and more.

Test drive NGINX today with a 30-day free trial of the API Connectivity Stack, which includes NGINX Plus, NGINX App Protect, and NGINX Management Suite.

Additional Resources


"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."