Secure Modern Applications and MicroServices SSO with NGINX

In Enhanced Modern Applications and MicroServices SSO with NGINX by Mohammed Mahdy, he discussed the use of F5 NGINX Plus as a reverse proxy with single sign-on (SSO). This article delves into the usefulness of F5 NGINX App Protect WAF as a tool for protecting SSO applications against SQL injection and provides instructions for setting up a lab for this use case. NGINX App Protect WAF is a highly efficient and reliable dynamic module that safeguards apps and APIs against a wide range of potential attacks, including the OWASP Top 10. This powerful web application firewall (WAF) not only prevents attacks, but also conducts thorough response inspection, ensuring that your web applications remain secure and free from any vulnerabilities. 

Testing Flow

  1.  The attacker utilizes SQL injection techniques to gain unauthorized access to the application's URL. (http://nginxsso-app.f5-local.demo/search?q=qwert%27%29%29%20UNION%20SELECT%20id%2C%20email%2C%20password%2C%20%274%27%2C%20%275%27%2C%20%276%27%2C%20%277%27%2C%20%278%27%2C%20%279%27%20FROM%20Users--)
  2. NGINX App Protect WAF will  block the URL 
  3. The attacker will receive a customized message indicating that access has been blocked and a support ID will be generated.


LAB Setup

UDF link NGINX SSO With Auth0 

NGINX App Protect WAF Configuration

  1. Install NGINX App Protect WAF.  
  2. Reference the following configuration in the nginx.conf file to load NGINX App Protect WAF. 
load_module modules/;

     3. Activate NGINX App Protect WAF in your SSO application by inserting the provided configuration into frontend.conf. 

app_protect_enable on;
app_protect_policy_file "/etc/app_protect/conf/NginxDefaultPolicy.json"; #App Protect Policy
app_protect_security_log_enable on; 
app_protect_security_log "/etc/app_protect/conf/log_default.json" /tmp/security.log; 

Once the above steps are completed, NGINX App Protect WAF is ready. To customize the NGINX App Protect policy visit the documentation page for information.  

Here is the full configuration for frontend.conf 

# This is the backend application we are protecting with OpenID Connect
upstream my_backend {
    zone my_backend 64k;

# Custom log format to include the 'sub' claim in the REMOTE_USER field
log_format main_jwt '$remote_addr - $jwt_claim_sub [$time_local] "$request" $status '
                    '$body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';

# The frontend server - reverse proxy with OpenID Connect authentication
server {
    include conf.d/openid_connect.server_conf; # Authorization code flow and Relying Party processing
    error_log /var/log/nginx/error.log debug;  # Reduce severity level as required

    listen 80; # Use SSL/TLS in production
    location / {
        # This site is protected with OpenID Connect
        auth_jwt "" token=$session_jwt;
        error_page 401 = @do_oidc_flow;
        app_protect_enable on; # This is how you enable NGINX App Protect WAF in the relevant context/block
        app_protect_policy_file "/etc/app_protect/conf/NginxDefaultPolicy.json"; # This is a reference to the policy file to use. If not defined, the default policy is used
        app_protect_security_log_enable on; # This section enables the logging capability
        app_protect_security_log "/etc/app_protect/conf/log_default.json" /tmp/security.log; # This is where the remote logger is defined in terms of: logging options (defined in the referenced file), log server IP, log server port
        #auth_jwt_key_file $oidc_jwt_keyfile; # Enable when using filename
        auth_jwt_key_request /_jwks_uri; # Enable when using URL
        proxy_set_header x-email $jwt_claim_email;
        # Successfully authenticated users are proxied to the backend,
        # with 'sub' claim passed as HTTP header
        proxy_set_header username $jwt_claim_sub;
        # Bearer token is uses to authorize NGINX to access protected backend
        #proxy_set_header Authorization "Bearer $access_token";
        # Intercept and redirect "401 Unauthorized" proxied responses to nginx
        # for processing with the error_page directive. Necessary if Access Token
        # can expire before ID Token.
        #proxy_intercept_errors on;
        proxy_pass http://my_backend$request_uri; # The backend site/app
        access_log /var/log/nginx/access.log main_jwt;
  • If you want to see the App Protect log from your NGINX PLUS instance, navigate to the directory /tmp/security.log. You will find all the relevant information there.
  • Now, we have both our application and NGINX App Protect WAF  ready for testing.


Published Aug 07, 2023
Version 1.0

Was this article helpful?