NGINX Documentation

Configuration Guide

Overview

This guide explains the NGINX App Protect security features and how to use them. This guide also assumes that you have some familiarity with various Layer 7 (L7) Hypertext Transfer Protocol (HTTP) concepts, such as Uniform Resource Identifier (URI)/Uniform Resource Locator (URL), method, header, cookie, status code, request, response, and parameters.

For more information on the NGINX App Protect security features, see NGINX App Protect Terminology.

Supported Security Policy Features

The following security features are supported in NGINX App Protect. We show what is enabled in the default policy and the changes that the user can do on top of this policy.

Protection Mechanism Description
Attack Signatures Default policy covers all the OWASP top 10 attack patterns enabling signature sets detailed in a section below. The user can disable any of them or add other sets.
Signature attack for Server Technologies Support adding signatures per added server technology.
Threat Campaigns These are patterns that detect all the known attack campaigns. They are very accurate and have almost no false positives, but are very specific and do not detect malicious traffic that is not part of those campaigns. The default policy enables threat campaigns but it is possible to disable it through the respective violation.
HTTP Compliance All HTTP protocol compliance checks are enabled by default except for GET with body and POST without body. It is possible to enable any of these two. Some of the checks enabled by default can be disabled, but others, such as bad HTTP version and null in request are perfomed by NGINX parser and NGINX App Protect only reports them. These checks cannot be disabled.
Evasion Techniques All evasion techniques are enabled by default and each can be disabled. These include directory traversal, bad escaped character and more.
Data Guard Detects and masks credit card and/or US social security numbers in responses. Disabled by default but can be enabled.
Parameter parsing Support only auto-detect parameter value type and acts according to the result: plain alphanumeric string, XML or JSON.
Disallowed meta characters Detected in parameter names, parameter values, URLs, headers and in JSON and XML content. Metacharacters indicate suspicious traffic, but not necessarily an actual threat. It is the combination of meta characters, attack signatures and other violations that indicates an actual threat that should be blocked and this is determined by Violation Rating. See section below.
Disallowed file type extension Support any file type. Default includes a predefined list of file types. See Disallowed File Types list below.
Cookie enforcement By default all cookies are allowed and not enforced for integrity. The user can add specific cookies, wildcards or explicit, that will be enforced for integrity. It is also possible to set the cookie attributes: HttpOnly, Secure and SameSite for cookies found in the response.
Sensitive Parameters Default policy masks the “password” parameter in the security log. It is possible to add more such parameters.
JSON Content JSON content profile detects malformed content and detects signatures and metacharacters in the property values. Default policy checks maximum structure depth. It is possible to enable more size restrictions: maximum total length Of JSON data; maximum value length; maximum array length; tolerate json parsing errors. JSON parameterization and schema enforcement is not supported.
XML Content XML content profile detects malformed content and detects signatures in the element values. Default policy checks maximum structure depth. It is possible to enable more size restrictions: maximum total length of XML data, maximum number of elements are more. SOAP, Web Services and XML schema features are not supported.
Allowed methods Check HTTP allowed methods. By default all the standard HTTP methods are allowed.
Black & White IP listing Manually define black & white IP addresses.
Trust XFF header Disabled by default. User can enable it and optionally add a list of custom XFF headers.

Disallowed File Types

The following file types are disallowed by default:

  • bak, bat, bck, bkp, cfg, conf, config, ini, log, old, sav, save, temp, tmp
  • bin, cgi, cmd, com, dll, exe, msi, sys, shtm, shtml, stm
  • cer, crt, der, key, p12, p7b, p7c, pem, pfx
  • dat, eml, hta, htr, htw, ida, idc, idq, nws, pol, printer, reg, wmz

Additional Policy Features

Feature Description
Enforcement by Violation Rating By default block requests that are declared as threats, that is, their Violation Rating is 4 or 5. It is possible to change this behavior: either disable enforcement by Violation Rating or block also request with Violation Rating 3 - needs examination. See section on basic configuration below.
Request size checks Upper limit of request size as dictated by the maximum buffer size of 10 MB; Size checks for: URL, header, Query String, whole request (when smaller than the maximum buffer), cookie, POST data. By default all the checks are enabled with the exception of POST data and whole request. The user can enable or disable every check and customize the size limits.
Malformed cookie Requests with cookies that are not RFC compliant are blocked by default. This can be disabled.
Status code restriction Illegal status code in the range of 4xx and 5xx. By default only these are allowed: 400, 401, 404, 407, 417, 503. The user can modify this list or disable the check altogether.
Blocking pages The user can customize all blocking pages. By default the AJAX response pages are disabled, but the user can enable them.

Configuring Attack Signatures

App Protect includes predefined attack signatures to protect your application against all attack types identified by the system. As new attack signatures are identified, they will become available for download so that your system will always have the most up-to-date protection. You can update the attack signatures without updating the App Protect release, and conversely, you can update App Protect without changing the attack signature package, unless you moved to a new NGINX Plus release.

Signature Settings

Setting JSON Property in Policy Support in NGINX App Protect Value in Default Profile
Signature Sets signature-sets All available sets. See signature set list below
Signatures signatures “Enabled” flag can be modified. All signatures in the included sets are enabled.
Auto-Added signature accuracy minimumAccuracyForAutoAddedSignatures Editable Low
Attack Signature False Positive Mode attackSignatureFalsePositiveMode Editable detect-and-allow

Signature Sets in Default Policy

The following signature sets are included in the default policy. Most of the sets are defined by the Attack Type they protect from. In all sets the Alarm flag is enabled and Block disabled except High Accuracy Signatures, which are set to blocked (Block flag is enabled).

  • Command Execution Signatures
  • Cross Site Scripting Signatures
  • Directory Indexing Signatures
  • Information Leakage Signatures
  • OS Command Injection Signatures
  • Path Traversal Signatures
  • Predictable Resource Location Signatures
  • Remote File Include Signatures
  • SQL Injection Signatures
  • Authentication/Authorization Attack Signatures
  • XML External Entity (XXE) Signatures
  • XPath Injection Signatures
  • Buffer Overflow Signatures
  • Denial of Service Signatures
  • Vulnerability Scanner Signatures
  • High Accuracy Signatures
  • All CVE Signatures

Basic Signature Sets Included in App Protect

These signatures sets are included but are not part of the default template.

  • All Response Signatures
  • All Signatures
  • Generic Detection Signatures
  • Generic Detection Signatures (High Accuracy)
  • Generic Detection Signatures (High/Medium Accuracy)
  • High Accuracy Signatures
  • Low Accuracy Signatures
  • Medium Accuracy Signatures
  • OWA Signatures
  • WebSphere signatures

Policy Configuration

The NGINX App Protect ships with two reference policies:

  • The default policy which is identical to the base template and provides the OWASP Top 10 security protection out of the box.
  • The strict policy contains more restrictive criteria for blocking traffic than the default policy. It is meant to be used for protecting sensitive applications that require more security but with higher risk of false positives. You can use those policies as is, but usually you will use them as starting points and further customize them to the needs of the applications they protect.

Overview

The NGINX App Protect security policy configuration uses the declarative format based on a pre-defined base template. The policy is represented in a JSON file which you can edit to add, modify and remove security capabilities with respect to the base template. The way the policy is integrated into the NGINX configuration is via referencing the JSON file (using the full path) in the nginx.conf file.

In the following example, the NGINX configuration file with App Protect enabled in the HTTP context and the policy /etc/nginx/NginxDefaultPolicy.json is used:

user nginx;
worker_processes  4;
 
load_module modules/ngx_http_app_protect_module.so;
 
error_log /var/log/nginx/error.log debug;
working_directory /tmp/cores;
worker_rlimit_core 1000M;
 
events {
    worker_connections  65536;
}
 
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
 
    app_protect_enable on; # This is how you enable NGINX App Protect in the relevant context/block
    app_protect_policy_file "/etc/nginx/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 (remote logging only)
    app_protect_security_log "/etc/app_protect/conf/log_default.json" syslog:server=127.0.0.1:515; # This is where the remote logger is defined in terms of: logging options (defined in the referenced file), log server IP, log server port
 
    server {
        listen       80;
        server_name  localhost;
        proxy_http_version 1.1;
 
        location / {
            client_max_body_size 0;
            default_type text/html;
            proxy_pass http://172.29.38.211:80$request_uri;
        }
    }
}

Basic Configuration and the Default Policy

The base template is the common starting point to any policy you write. The default policy just reflects that template without any further modifications, thus we use the terms base template and default policy interchangeably.

The default policy enforces violations by Violation Rating, the App Protect computed assessment of the risk of the request based on the triggered violations.

  • 0: No violation
  • 1-2: False positive
  • 3: Needs examination
  • 4-5: Threat

The default policy enables most of the violations with Alarm turned on, but not Block. By default, if the violation rating is 4-5 the request is blocked using the VIOL_RATING_THREAT violation. By default, all other requests are not blocked. This is to minimize false positives. However, you can change the default behavior. For example, if you want to add blocking on a violation rating of 3 as well, enable blocking for the VIOL_RATING_NEED_EXAMINATION violation. The High Accuracy signatures that block a request regardless of its Violation Rating are an exception to this.

The Strict Policy

The Strict Policy is recommended as a starting point for applications requiring a higher level of security. Just like all other policies it is based on the base template, so it detects and blocks everything the default policy does. It can be found in: /etc/nginx/NginxStrictPolicy.json.

In addition the Strict Policy also blocks the following:

  • Requests that have a Violation Rating of 3, “Needs examination”. This occurs because the VIOL_RATING_NEED_EXAMINATION violation’s block flag is enabled in the strict policy.
  • Requests with the VIOL_EVASION violation (evasion techniques).
  • Requests with violations that restrict options in the request and response: HTTP method, response status code and disallowed file types.

Note: Other violations, specifically attack signatures and metacharacters, which are more prone to false positives, still have only Alarm turned on, without blocking, contributing to the Violation Rating as in the Default policy.

In addition, the Strict policy also enables the following features in alarm only mode:

  • Data Guard: masking Credit Card and US Social Security numbers found in HTTP responses.
  • HTTP response data leakage signatures: preventing exfiltration of sensitive information from the servers.
  • More restrictive limitations: mainly sizing and parsing of JSON and XML payloads.
  • Cookie attribute insertion: the Strict policy adds the Secure and SameSite=lax attributes to every cookie set by the application server. These attributes are enforced by the browsers and protect against session hijacking and CSRF attacks respectively.

Policy Authoring and Tuning

The policy JSON file specifies the settings that are different from the base template, such as enabling more signatures, disabling some violations, adding server technologies, etc. These will be shown in the next sections.

There are two ways to tune those settings:

  • Within the policy structure property, the organic structure of the policy.
  • Within the modifications structure property that contains a list of changes expressed in a generic manner.

Both options are equivalent in their semantic expression power, but different syntactically and are designated for different use cases. But before that, let’s look at an example - disabling a specific attack signature.

Signature 200001834 disabled in the policy property:

{
    "policy": {
        "name": "signature_exclude_1",
        "signatures": [
            {
                "signatureId": 200001834,
                "enabled": false                
            }
        ]
    }
}

As you can see, this is expressed using the signatures property that contains configuration of individual signatures in a policy. If you want to modify other parts of the policy, you would use different JSON properties.

The same configuration in the modifications array looks like this:

{
    "policy": {
        "name": "signature_exclude_2"
    },
    "modifications": [
        {
            "entityChanges": {
                "enabled": false
            },
            "entity": {
                "signatureId": 200001834
            },
            "entityType": "signature",
            "action": "add-or-update"
        }
    ]
}

Note the generic schema that can express manipulation in any policy element: entity, entityType, action etc. The modifications array is a flat list of individual changes applied to the policy after evaluating the policy block.

So when to use policy and when to use modifications? There are some recommended practice guidelines for that:

  • Use policy to express the security policy as you intended it to be: the features you want to enable, disable, the signature sets, server technologies and other related configuration attributes. This part of the policy is usually determined when the application is deployed and changes at a relatively slow pace.
  • Use modifications to express exceptions to the intended policy. These exceptions are usually the result of fixing false positive incidents and failures in tests applied to those policies. Usually these are granular modifications, typically disabling checks of individual signatures, metacharacters and sub-violations. These changes are more frequent.
  • Use modifications also for removing individual collection elements from the base template, for example disallowed file types.

It is a good practice to separate the modifications to a different file and have the main policy file reference the former, as the two parts have different lifecycles.

The sections just below review the common policy feature configurations using examples. For the full reference of the policy JSON properties see the Declarative Policy guide.

Policy Enforcement Modes

A policy’s enforcement mode can be:

  • Blocking: Any illegal or suspicious requests are logged and blocked.
  • Transparent: Any illegal or suspicious requests are logged but not blocked.

Specific security features can be defined as blocked or transparent in the policy.

Blocking Mode example:

{
    "policy": {
        "name": "policy_name",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking"
    }
}

Transparent Mode example:

{
    "policy": {
        "name": "policy_name",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "transparent"
    }
}

Enabling Violations

Adding and enabling additional security features to the policy can be done by specifying the violation name and the alarm block state to “true”. To set different states to sub-violations within the violation, enable the violation first, then specifying and enable the sub-violations. Also, a violation may have its own section that provides additional configuration granularity for a specific violation/sub-violation. The examples below show how to enable a violation and sub-violation in a declarative format.

Configuration details example:

In this example, we enable 2 violations: VIOL_JSON_FORMAT and VIOL_PARAMETER_VALUE_METACHAR.

Note that the example defines the blocking and alarm setting for each violation. These settings override the default configuration set above in the enforcementMode directive. Be aware, however, that in a transparent policy no violations are blocked, even if specific violations are set to block: true in the configuration.

{
   "policy": {
       "name": "policy_name",
       "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
       "applicationLanguage": "utf-8",
       "enforcementMode": "blocking",
       "blocking-settings": {
           "violations": [
               {
                   "name": "VIOL_JSON_FORMAT",
                   "alarm": true,
                   "block": true
               },
               {
                   "name": "VIOL_PARAMETER_VALUE_METACHAR",
                   "alarm": false,
                   "block": false
               }
           ]
       }
   }
}

HTTP Compliance

HTTP compliance is one of the basic application security violations. It validates the request itself and also prevents the use of the HTTP protocol as an entry point to the application.

In this example, we enable the HTTP compliance violation with the blocking as true. We also configure (enabled or disabled) all of its sub-violations in the relevant HTTP section. Note that you can add/remove sub-violations to match your desired configurations. However, not listing a violation does not mean it will be disabled. Rather, it would actually mean that the default configuration would not be overridden for that specific sub-violation.

{
    "name": "policy_name",
    "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
    "applicationLanguage": "utf-8",
    "enforcementMode": "blocking",
    "blocking-settings": {
        "violations": [
            {
                "name": "VIOL_HTTP_PROTOCOL",
                "alarm": true,
                "block": true
            }
        ],
        "http-protocols": [
            {
                "description": "Header name with no header value",
                "enabled": true
            },
            {
                "description": "Chunked request with Content-Length header",
                "enabled": true
            },
            {
                "description": "Check maximum number of parameters",
                "enabled": true,
                "maxParams": 5
            },
            {
                "description": "Check maximum number of headers",
                "enabled": true,
                "maxHeaders": 20
            },
            {
                "description": "Body in GET or HEAD requests",
                "enabled": true
            },
            {
                "description": "Bad multipart/form-data request parsing",
                "enabled": true
            },
            {
                "description": "Bad multipart parameters parsing",
                "enabled": true
            },
            {
                "description": "Unescaped space in URL",
                "enabled": true
            }
        ]
    }
}

Evasion Techniques

Evasion techniques refers to techniques usually used by hackers to attempt to access resources or evade what would otherwise be identified as an attack. Like HTTP compliance, evasion techniques have a list of sub-violations that can be configured for additional granularity and to reduce false positives.

In this example, we enable the evasion technique violation with the blocking as true. We also configure (enabled or disabled) all of its sub-violations in the relevant section. Note that you can add/remove sub-violations to match your desired configurations. However, not listing a violation does not mean it will be disabled. Rather, it would actually mean that the default configuration would not be overridden for that specific sub-violation.

{
    "policy": {
        "name": "evasions_enabled",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "blocking-settings": {
            "violations": [
                {
                    "name": "VIOL_EVASION",
                    "alarm": true,
                    "block": true
                }
            ],
            "evasions": [
                {
                    "description": "Bad unescape",
                    "enabled": true
                },
                {
                    "description": "Directory traversals",
                    "enabled": true
                },
                {
                    "description": "Bare byte decoding",
                    "enabled": true
                },
                {
                    "description": "Apache whitespace",
                    "enabled": true
                },
                {
                    "description": "Multiple decoding",
                    "enabled": true,
                    "maxDecodingPasses": 2
                },
                {
                    "description": "IIS Unicode codepoints",
                    "enabled": true
                },
                {
                    "description": "IIS backslashes",
                    "enabled": true
                },
                {
                    "description": "%u decoding",
                    "enabled": true
                }
            ]
        }
    }
}

Attack Signatures

Attack signatures may be a little more difficult to configure as there are a number of configuration items and values in different places that may seem confusing. The first thing to be done is to enable the attack signature violation itself. Then, we need to configure which signature sets are to be enforced. Note that there are different ways to configure these sets and that there might be some overlap when doing so. You can also enable/disable signatures individually (but that would be a very exhaustive process).

In this example, we enable the attack signature violation, and specify that we want to enforce all signatures. Note that blocking setting cannot be blank.

{
    "policy": {
        "name": "attack_sigs",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "signature-sets": [
            {
                "name": "All Signatures",
                "block": true,
                "alarm": true
            }
        ]
    }
}

In this example, we enable the attack signature violation, and specify that we want to enforce only high accuracy signatures.

{
    "policy": {
        "name": "attack_sigs",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "signature-sets": [
            {
                "name": "High Accuracy Signatures",
                "block": true,
                "alarm": true
            }
        ]
    }
}

In this example, we exclude the signature ID 200001834.

{
    "policy": {
        "name": "signature_exclude",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "signature-sets": [
            {
                "name": "All Signatures",
                "block": true,
                "alarm": true
            }
        ],
        "signatures": [
            {
                "signatureId": 200001834,
                "enabled": false                
            }
        ]
    }
}

In this example, the policy is the same but a new section is added and the attack signatures to be modified are appended. We use the same signature ID 200001834:

{
    "policy": {
        "name": "signature_modification_entitytype",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "signature-sets": [
            {
                "name": "All Signatures",
                "block": true,
                "alarm": true
            }
        ]
    },
    "modifications": [
        {
            "entityChanges": {
                "enabled": false
            },
            "entity": {
                "signatureId": 200001834
            },
            "entityType": "signature",
            "action": "add-or-update"
        }
    ]
}

For multiple attack signatures, the signature IDs need to be added as separate entities under the modifications list, each on its own, with only the signature ID updated:

{
    "modifications": [
        {
            "entityChanges": {
                "enabled": false
            },
            "entity": {
                "signatureId": 200001834
            },
            "entityType": "signature",
            "action": "add-or-update"
        },
        {
            "entityChanges": {
                "enabled": false
            },
            "entity": {
                "signatureId": 200004461
            },
            "entityType": "signature",
            "action": "add-or-update"
        }
    ]
}

Server Technologies

Another way to configure attack signature sets is by applying server technologies. Server technologies applies sets of signatures that would be relevant to attacks targeted to a specific OS, application, or server type.

In this example, we enable the attack signature violation, and enabled the Apache/NCSA HTTP Server server technology, which in turn enables attack signatures specific to this type of technology. We also enabled signatures with minimum accuracy of low. This would include low, medium, and high accuracy attack signatures.

{
    "policy": {
        "name": "policy_name",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "signature-settings": {
            "attackSignatureFalsePositiveMode": "disabled",
            "minimumAccuracyForAutoAddedSignatures": "low"
        },
        "server-technologies": [
            { "serverTechnologyName": "Apache/NCSA HTTP Server" }
        ]
    }
}
Available Server Technologies

The table below lists all the available Server Technologies. Some of them are built on top others on the stack and including them implies the inclusion of the latter. For example: ASP.NET implies both IIS and Microsoft Windows. This is indicated in the “implied technologies” column when applicable.

Server Technology Name Description Implied Technologies
Jenkins Jenkins is an open source automation server written in Java. Jenkins helps to automate the non-human part of the software development process, with continuous integration and facilitating technical aspects of continuous delivery. It is a server-based system that runs in servlet containers such as Apache Tomcat.  
SharePoint SharePoint is a web-based collaborative platform that integrates with Microsoft Office. Launched in 2001, SharePoint is primarily sold as a document management and storage system, but the product is highly configurable and usage varies substantially among organizations.  
Oracle Application Server Oracle Internet Application Server provides a single integrated packaged solution of for middleware infrastructure including Oracle Containers for J2EE, Oracle Web Cache, Oracle HTTP Server, Oracle Forms, Oracle Reports, Oracle Portal and Oracle Discoverer.  
Python Python is an interpreted, high-level, general-purpose programming language. Created by Guido van Rossum and first released in 1991, Python has a design philosophy that emphasizes code readability, notably using significant whitespace. It provides constructs that enable clear programming on both small and large scales.  
Oracle Identity Manager Oracle Identity Manager (OIM) enables enterprises to manage the entire user life-cycle across all enterprise resources both within and beyond a firewall. Within Oracle Identity Management it provides a mechanism for implementing the user-management aspects of a corporate policy.  
Spring Boot Spring Boot makes it easy to create Spring-powered, production-grade applications and services with absolute minimum fuss. It takes an opinionated view of the Spring platform so that new and existing users can quickly get to the bits they need.  
CouchDB Apache CouchDB is open source database software that focuses on ease of use and having a scalable architecture.  
SQLite SQLite is a relational database management system contained in a C programming library. In contrast to many other database management systems, SQLite is not a client-server database engine. Rather, it is embedded into the end program.  
Handlebars Handlebars provides the power necessary to let you build semantic templates effectively with no frustration.  
Mustache Mustache is a simple web template system.  
Prototype Prototype takes the complexity out of client-side web programming. Built to solve real-world problems, it adds useful extensions to the browser scripting environment and provides elegant APIs around the clumsy interfaces of Ajax and the Document Object Model.  
Zend Zend Server is a complete and certified PHP distribution stack fully maintained and supported by Zend Technologies. It ships with an updated set of advanced value-add features designed to optimize productivity, performance, scalability and reliability.  
Redis Redis is an open-source in-memory data structure project implementing a distributed, in-memory key-value database with optional durability. Redis supports different kinds of abstract data structures, such as strings, lists, maps, sets, sorted sets, hyperloglogs, bitmaps, streams and spatial indexes.  
Underscore.js Underscore.js is a JavaScript library which provides utility functions for common programming tasks. It is comparable to features provided by Prototype.js and the Ruby language, but opts for a functional programming design instead of extending object prototypes  
Ember.js Ember.js is an open-source JavaScript web framework, based on the Model-view-viewmodel pattern. It allows developers to create scalable single-page web applications by incorporating common idioms and best practices into the framework.  
ZURB Foundation Foundation is a responsive front-end framework. Foundation provides a responsive grid and HTML and CSS UI components, templates, and code snippets, including typography, forms, buttons, navigation and other interface elements, as well as optional functionality provided by JavaScript extensions. Foundation is maintained by ZURB and is an open source project.  
ef.js ef.js is an elegant HTML template engine & basic framework.  
Vue.js Vue.js is an open-source JavaScript framework for building user interfaces and single-page applications.  
UIKit UIkit is a lightweight and modular front-end framework for developing fast and powerful web interfaces.  
TYPO3 CMS TYPO3 is a free and open-source web content management system written in PHP. It is released under the GNU General Public License. It can run on several web servers, such as Apache or IIS, on top of many operating systems, among them Linux, Microsoft Windows, FreeBSD, macOS and OS/2.  
RequireJS RequireJS is a JavaScript library and file loader which manages the dependencies between JavaScript files and in modular programming. It also helps to improve the speed and quality of the code.  
React React is a JavaScript library for building user interfaces. It is maintained by Facebook and a community of individual developers and companies. React can be used as a base in the development of single-page or mobile applications.  
MooTools MooTools is a lightweight, object-oriented JavaScript framework. It is released under the free, open-source MIT License.  
Laravel Laravel is a free, open-source PHP web framework, created by Taylor Otwell and intended for the development of web applications following the model-view-controller architectural pattern and based on Symfony.  
GraphQL GraphQL is an open-source data query and manipulation language for APIs, and a runtime for fulfilling queries with existing data. GraphQL was developed internally by Facebook in 2012 before being publicly released in 2015.  
Google Web Toolkit Google Web Toolkit, or GWT Web Toolkit, is an open-source set of tools that allows web developers to create and maintain complex JavaScript front-end applications in Java. Other than a few native libraries, everything is Java source that can be built on any supported platform with the included GWT Ant build files.  
Express.js Express.js, or simply Express, is a web application framework for Node.js, released as free and open-source software under the MIT License. It is designed for building web applications and APIs. It has been called the de facto standard server framework for Node.js.  
CodeIgniter CodeIgniter is an open-source software rapid development web framework, for use in building dynamic web sites with PHP.  
Backbone.js Backbone.js is a JavaScript library with a RESTful JSON interface and is based on the Model-view-presenter application design paradigm. Backbone is known for being lightweight, as its only hard dependency is on one JavaScript library, Underscore.js, plus jQuery for use of the full library.  
AngularJS AngularJS is a JavaScript-based open-source front-end web application framework mainly maintained by Google and by a community of individuals and corporations to address many of the challenges encountered in developing single-page applications.  
JavaScript JavaScript, often abbreviated as JS, is a high-level, interpreted programming language that conforms to the ECMAScript specification. It is a language which is also characterized as dynamic, weakly typed, prototype-based and multi-paradigm.  
Nginx Nginx is a web server which can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache.  
Jetty Jetty is a Java HTTP (Web) server and Java Servlet container Java Servlets/JSP
Joomla Joomla is a free and open-source content management system (CMS) for publishing web content. PHP
JavaServer Faces (JSF) JavaServer Faces (JSF) is a Java specification for building component-based user interfaces for web applications. Java Servlets/JSP
Ruby Ruby is a dynamic, reflective, object-oriented, general-purpose programming language.  
MongoDB MongoDB is a free and open-source cross-platform document-oriented database program.  
Django Django is a free and open-source web framework, written in Python, which follows the model-view-template (MVT) architectural pattern.  
Node.js Node.js is an open-source, cross-platform JavaScript runtime environment for developing a diverse variety of tools and applications.  
Citrix Citrix Systems, Inc. is an American multinational software company that provides server, application and desktop virtualization, networking, software as a service (SaaS), and cloud computing technologies.  
JBoss The JBoss Enterprise Application Platform (or JBoss EAP) is a subscription-based/open-source Java EE-based application server runtime platform used for building, deploying, and hosting highly-transactional Java applications and services. Java Servlets/JSP
Elasticsearch Elasticsearch is a search engine based on Lucene.  
Apache Struts Apache Struts is an open-source web application framework for developing Java EE web applications. Java Servlets/JSP
XML Extensible Markup Language (XML) is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable.  
PostgreSQL PostgreSQL, often simply Postgres, is an object-relational database (ORDBMS) - i.e. a RDBMS, with additional (optional use) “object” features - with an emphasis on extensibility and standards-compliance.  
IBM DB2 IBM DB2 contains database server products developed by IBM.  
Sybase/ASE SAP ASE (Adaptive Server Enterprise), originally known as Sybase SQL Server, and also commonly known as Sybase DB or ASE, is a relational model database server product for businesses developed by Sybase Corporation which became part of SAP AG.  
CGI Common Gateway Interface (CGI) offers a standard protocol for web servers to interface with executable programs running on a server that generate web pages dynamically.  
Proxy Servers A proxy server is a server (a computer system or an application) that acts as an intermediary for requests from clients seeking resources from other servers.  
SSI (Server Side Includes) Server Side Includes (SSI) is a simple interpreted server-side scripting language used almost exclusively for the Web.  
Cisco Cisco Systems, Inc. is an American multinational corporation technology company headquartered in San Jose, California, that designs, manufactures and sells networking equipment worldwide.  
Novell Novell Directory Services (NDS) is a popular software product for managing access to computer resources and keeping track of the users of a network, such as a company’s intranet, from a single point of administration.  
Macromedia JRun JRun is a J2EE application server, originally developed in 1997 as a Java Servlet engine by Live Software and subsequently purchased by Allaire, who brought out the first J2EE compliant version.  
BEA Systems WebLogic Server Oracle WebLogic Server is a Java EE application server currently developed by Oracle Corporation. Java Servlets/JSP
Lotus Domino IBM Notes and IBM Domino are the client and server, respectively, of a collaborative client-server software platform sold by IBM.  
MySQL MySQL is an open-source relational database management system (RDBMS).  
Oracle Oracle Database (commonly referred to as Oracle RDBMS or simply as Oracle) is an object-relational database management system produced and marketed by Oracle Corporation.  
Microsoft SQL Server Microsoft SQL Server is a relational database management system developed by Microsoft.  
PHP PHP is a server-side scripting language designed primarily for web development but is also used as a general-purpose programming language.  
Outlook Web Access Outlook on the web (previously called Exchange Web Connect, Outlook Web Access, and Outlook Web App in Office 365 and Exchange Server 2013) is a personal information manager web app from Microsoft. ASP.NET, IIS, Microsoft Windows
Apache/NCSA HTTP Server The Apache HTTP Server, colloquially called Apache, is the world’s most used web server software.  
Apache Tomcat Apache Tomcat, often referred to as Tomcat, is an open-source Java Servlet Container developed by the Apache Software Foundation (ASF). Java Servlets/JSP
WordPress WordPress is a free and open-source content management system (CMS) based on PHP and MySQL. XML, PHP
Macromedia ColdFusion Adobe ColdFusion is a commercial rapid web application development platform created by JJ Allaire in 1995.  
Unix/Linux Unix is a family of multitasking, multiuser computer operating systems that derive from the original AT&T Unix, developed in the 1970s at the Bell Labs research center by Ken Thompson, Dennis Ritchie, and others.  
Microsoft Windows Microsoft Windows (or simply Windows) is a metafamily of graphical operating systems developed, marketed, and sold by Microsoft.  
ASP.NET ASP.NET is an open-source server-side web application framework designed for web development to produce dynamic web pages. IIS, Microsoft Windows
Front Page Server Extensions (FPSE) FrontPage Server Extensions are a software technology that allows Microsoft FrontPage clients to communicate with web servers, and provide additional functionality intended for websites.  
IIS Internet Information Services (IIS, formerly Internet Information Server) is an extensible web server created by Microsoft for use with Windows NT family. Microsoft Windows
WebDAV Web Distributed Authoring and Versioning (WebDAV) is an extension of the Hypertext Transfer Protocol (HTTP) that allows clients to perform remote Web content authoring operations.  
ASP Active Server Pages (ASP), later known as Classic ASP or ASP Classic, is Microsoft’s first server-side script engine for dynamically generated web pages. IIS, Microsoft Windows
Java Servlets/JSP A Java servlet is a Java program that extends the capabilities of a server.  
jQuery jQuery is a cross-platform JavaScript library designed to simplify the client-side scripting of HTML.  

Threat Campaigns

The Threat Campaign mechanism detects attacks coming from known attack campaigns. They are based on patterns that identify the traffic from those campaigns. The mechanism is very accurate and has very low false positive rate. However it does not cover malicious traffic that is not part of those campaigns.

Just like attack signatures, the Threat Campaign patterns are updated regularly. Unlike attack signatures, the NGINX App Protect installation does not include any Threat Campaigns and you need to install the them in order for the protection to take effect. Due to the highly dynamic nature of those campaigns the updates are issued far more frequently than the attack signatures. You need to install those updates close to the time they are issued in order to get the most effective protection.

The default policy enables the mechanism with all available Threat Campaigns and blocks when detecting one. Since the risk of false positive is very low, you do not need to enable or disable specific Threat Campaigns. Rather, you can disable the whole mechanism or decide to only alarm rather than block. You can do that by modifying the properties of the Threat Campaign Violation - VIOL_THREAT_CAMPAIGN.

In this example we disable both alarm and blocking.

{
   "policy": {
       "name": "policy_name",
       "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
       "applicationLanguage": "utf-8",
       "enforcementMode": "blocking",
       "blocking-settings": {
           "violations": [
               {
                   "name": "VIOL_THREAT_CAMPAIGN",
                   "alarm": false,
                   "block": false
               }
           ]
       }
   }
}

Data Guard

Data Guard is a security feature that can be used to prevent the leakage of sensitive information from an application. This could be credit card numbers or Social Security numbers (CCN, SSN, etc.). Once this feature is enabled, sensitive data is either blocked or masked, depending on the configuration.

In this example, we enable the data guard violation in blocking mode. In the detailed configuration, we enable enforcement of data guard and specify which items are being protected against information leakage. Note that if blocking is enabled, data masking will have no effect in this case.

{
    "policy": {
        "name": "dataguard_blocking",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "blocking-settings": {
            "violations": [
                {
                    "name": "VIOL_DATA_GUARD",
                    "alarm": true,
                    "block": true
                }
            ]
        },
        "data-guard": {
            "enabled": true,
            "maskData": true,
            "creditCardNumbers": true,
            "usSocialSecurityNumbers": true,
            "enforcementMode": "ignore-urls-in-list",
            "enforcementUrls": []            
        }
    }
}

Masking

Masking is used when we do not want to block the page entirely, but want to mask all sensitive data in the response.

In this example, we enable data guard in alarm mode. In the detailed configuration, we enable enforcement of data guard and specify which items are being protected against information leakage.

{
    "policy": {
        "name": "nginx_default_policy",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "blocking-settings": {
            "violations": [
                {
                    "name": "VIOL_DATA_GUARD",
                    "alarm": true,
                    "block": false
                }
            ]
        },
        "data-guard": {
            "enabled": true,
            "maskData": true,
            "creditCardNumbers": true,
            "usSocialSecurityNumbers": true,
            "enforcementMode": "ignore-urls-in-list",
            "enforcementUrls": []
        }
    }
}

File Types

A user can enable/disable specific file types in the policy.

In this example, we enable the file type violation in blocking mode. In the detailed configuration, we allow the * wildcard entity which would allow all file types by default. In the last section, we explicitly disable the bat file type. This is an example of allowing all, but specifically blocking (blacklisting) certain items. You may add as many file types as you wish, each declared in its own curly brackets, along with the "allowed": false directive.

{
    "policy": {
        "name": "policy1",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "blocking-settings": {
            "violations": [
                {
                    "name": "VIOL_FILETYPE",
                    "alarm": true,
                    "block": true
                }
            ]
        },
        "filetypes": [
            {
                "name": "*",
                "type": "wildcard",
                "allowed": true,
                "checkPostDataLength": false,
                "postDataLength": 4096,
                "checkRequestLength": false,
                "requestLength": 8192,
                "checkUrlLength": true,
                "urlLength": 2048,
                "checkQueryStringLength": true,
                "queryStringLength": 2048,
                "responseCheck": false
            },
            {
                "name": "bat",
                "allowed": false
            }
        ]
    }
}    

Allowed Methods

In the policy, you can specify what methods to allow or disallow.

In this example, we enable the illegal method violation in blocking mode. In the methods configuration, we define which of the methods are allowed, and how they will be treated in terms of flow. Note that the “act as” does not imply enforcement on the method as the “act as”.

{
    "policy": {
        "name": "blocking_policy",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "blocking-settings": {
            "violations": [
                {
                    "name": "VIOL_METHOD",
                    "alarm": true,
                    "block": true
                }
            ]
        },
        "methods": [
            {
                "name": "GET"
            },
            {
                "name": "POST"
            },
            {
                "name": "HEAD"
            },
            {
                "name": "PUT"
            },
            {
                "name": "PATCH"
            },
            {
                "name": "DELETE"
            },
            {
                "name": "OPTIONS"
            }
        ]
    }
}

Response Codes

Response codes are a general setting that defines which response codes are acceptable, while all others will be blocked.

In this example, we enable the response status codes violation in blocking mode. In the general configuration, we define which of the response codes are allowed. This would mean that all others will be considered as illegal response codes and will be blocked. In this configuration, you specify a list of comma-separated response codes that are allowed.

{
    "policy": {
        "name": "allowed_response",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "blocking-settings": {
            "violations": [
                {
                    "name": "VIOL_HTTP_RESPONSE_STATUS",
                    "alarm": true,
                    "block": true
                }
            ]
        },
        "general": {
            "allowedResponseCodes": [
                400,
                401,
                403,
                404,
                502,
                499
            ]
        }
    }
}

Parameters

When configuring handling of parameters, it is a bit different from other configurations we have dealt with earlier, where we enable a violation and configure its details. With parameters, there are a number of independent violations that need to be enabled on their own, as well as a parameter section to define further customization. The full list of parameter violations can be extracted from the above violation list.

{
    "policy": {
        "name": "parameters_blocking",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "blocking-settings": {
            "violations": [
                {
                    "name": "VIOL_PARAMETER_MULTIPART_NULL_VALUE",
                    "alarm": true,
                    "block": true
                },
                {
                    "name": "VIOL_PARAMETER_NAME_METACHAR",
                    "alarm": true,
                    "block": true
                },
                {
                    "name": "VIOL_PARAMETER_VALUE_METACHAR",
                    "alarm": true,
                    "block": true
                }
            ]
        },
        "parameters": [
            {
                "checkMetachars": true,
                "parameterLocation": "any",
                "valueType": "auto-detect",
                "metacharsOnParameterValueCheck": true,
                "name": "*",
                "type": "wildcard",                
            }
        ]
    }
}

In this example we configure allowed meta-characters in parameter name and value.

{
    "policy": {
        "name": "parameters_allowed_metachars",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "blocking-settings": {
            "violations": [
                {
                    "name": "VIOL_PARAMETER_MULTIPART_NULL_VALUE",
                    "alarm": true,
                    "block": true
                },
                {
                    "name": "VIOL_PARAMETER_NAME_METACHAR",
                    "alarm": true,
                    "block": true
                },
                {
                    "name": "VIOL_PARAMETER_VALUE_METACHAR",
                    "alarm": true,
                    "block": true
                }
            ]
        },
        "parameters": [
            {
                "checkMetachars": true,
                "sensitiveParameter": false,
                "parameterLocation": "any",
                "valueType": "auto-detect",
                "nameMetacharOverrides": [
                    {
                        "isAllowed": true,
                        "metachar": "0x3c"
                    },
                    {
                        "isAllowed": true,
                        "metachar": "0x3e"
                    }
                ],
                "metacharsOnParameterValueCheck": true,
                "allowEmptyValue": true,
                "checkMaxValueLength": false,
                "valueMetacharOverrides": [
                    {
                        "isAllowed": true,
                        "metachar": "0x3c"
                    },
                    {
                        "isAllowed": true,
                        "metachar": "0x3e"
                    }
                ],
                "name": "*",
                "level": "global",
                "allowRepeatedParameterName": true,
                "attackSignaturesCheck": true,
                "signatureOverrides": [],
                "type": "wildcard",                
            }
        ]
    }
}

In this example, we define a sensitive parameter “mypass” configuration.

{
    "policy": {
        "name": "parameters_sensitive",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "blocking-settings": {
            "violations": [
                {
                    "name": "VIOL_PARAMETER_MULTIPART_NULL_VALUE",
                    "alarm": true,
                    "block": false
                },
                {
                    "name": "VIOL_PARAMETER_NAME_METACHAR",
                    "alarm": true,
                    "block": false
                },
                {
                    "name": "VIOL_PARAMETER_VALUE_METACHAR",
                    "alarm": true,
                    "block": false
                }
            ]        
        },
        "sensitive-parameters": [
            {
                "name": "mypass"
            }
        ]
    }
}

Blacklisting and Whitelisting

It is possible to define IP addresses or ranges that will be blacklisted or whitelisted despite the rest of the configuration settings in the policy.

In this example, we use the default configuration while enabling the blacklisting violation. In the configuration section, we define:

  • A whitelisted IP 1.1.1.1
  • A blacklisted IP 2.2.2.2
  • A whitelisted range of IPs 3.3.3.0/24
{
    "policy": {
        "name": "blacklist_whitelist",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "blocking-settings": {
            "violations": [                
                {
                    "name": "VIOL_BLACKLISTED_IP",
                    "alarm": true,
                    "block": true
                }
            ]
        },
        "whitelist-ips": [
            {
                "blockRequests": "never",
                "neverLogRequests": false,
                "ipAddress": "1.1.1.1",
                "ipMask": "255.255.255.255"
            },
            {
                "blockRequests": "always",
                "ipAddress": "2.2.2.2",
                "ipMask": "255.255.255.255"
            },
            {
                "blockRequests": "never",
                "neverLogRequests": false,
                "ipAddress": "3.3.3.0",
                "ipMask": "255.255.255.0"
            }
        ]
    }
}

Additional Configuration Options

XFF Headers and Trust

XFF trust is disabled by default but can be enabled.

In this example, we use the default configuration but enable the trust of XFF header.

{
    "policy": {
        "name": "xff_enabled",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "general": {
            "customXffHeaders": [],
            "trustXff": true
        }
    }
}

In this example, we configure a policy with a custom-defined XFF header.

{
    "policy": {
        "name": "xff_custom_headers",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "general": {
            "customXffHeaders": [
                "xff"
            ],
            "trustXff": true
        }
    }
}

Blocking Page Customization

You can customize the blocking page text and formatting to suit your particular design requirements.

In this example, we use the default configuration but modify the response page that is displayed to the customer.

 {
    "policy": {
        "name": "blocking_page",
        "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",    
        "response-pages": [
            {
                "responseContent": "<html><head><title>Custom Reject Page</title></head><body>This is a custom response page, it is supposed to overwrite the default page with custom text.<br><br>Your support ID is: <%TS.request.ID()%><br><br><a href='javascript:history.back();'>[Go Back]</a></body></html>",
                "responseHeader": "HTTP/1.1 302 OK\\r\\nCache-Control: no-cache\\r\\nPragma: no-cache\\r\\nConnection: close",
                "responseActionType": "custom",
                "responsePageType": "default"
            }
        ]
    }
}

AJAX Response Page for Single Page Applications (SPAs)

There is a special scenario where default or regular custom response pages cannot be used. SPAs (Single Page Applications) are applications that provide application functionality within the boundaries of a single HTML page. Once a SPA application has been loaded in the browser, it typically makes REST API calls to remote resources expecting JSON response bodies rather than HTML markup. If this SPA application were to receive a default HTML-formatted block page, it would not be able to interpret this, likely causing an application error.

A way to handle such a situation is via configuring an AJAX response page. The AJAX response page will cause a pop-up to appear on the client browser, informing them that the request has been blocked.

In this example, we set up an AJAX response page.

{
    "policy": {
        "name": "NGINX-SPA",
        "description": "Policy with AJAX response page enabled for blocking AJAX requests",
        "template": {
            "name": "POLICY_TEMPLATE_NGINX_BASE"
        },
        "enforcementMode": "blocking",
        "response-pages": [
            {
                "responsePageType": "ajax",
                "ajaxEnabled": true,
                "ajaxPopupMessage": "My customized popup message! Your support ID is: <%TS.request.ID()%>"
            }
        ]
    }
}

Response Page for gRPC Applications

Another scenario where default or regular custom response pages cannot be used is in the context of a gRPC application. If a gRPC client were to receive a block page, it would not be able to interpret this, likely causing an application error.

A way to handle such a situation is via configuring a custom response in a format that a gRPC client can interpret in its error handling code. This is an example configuration for this scenario.

{
    "policy": {
        "name": "NGINX-GRPC",
        "description": "Policy with gRPC response page enabled for blocking gRPC requests",
        "template": {
            "name": "POLICY_TEMPLATE_NGINX_BASE"
        },
        "enforcementMode": "blocking",
        "response-pages": [
            {
                "responseContent": "",
                "responseHeader": "HTTP/1.1 403 FORBIDDEN\r\nContent-Type: application/grpc+proto\r\nGrpc-status: 7\r\nGrpc-message: Blocked by NGINX App Protect, Your support ID is <%TS.request.ID()%>\r\nSupport-ID: <%TS.request.ID()%>\r\nCache-Control: no-cache\r\nPragma: no-cache\r\nConnection: close",
                "responseActionType": "custom",
                "responsePageType": "default"
            }
        ]
    }
}

Modifying Configurations

What we have been seeing so far has been related to making changes by actually overriding specific configuration values. What would happen in the case we wanted to remove a specific configuration entity from the policy. For example, let’s say we have added file types “aaa”, “bbb”, and “ccc”, and now we wish to remove “bbb” from the list of disallowed file types. Deleting this entity from the declarative configuration file will simply mean that this entity will be left intact when the policy is rebuilt, meaning that the entity is still in the disallowed file types list. To resolve such situations, we have a modifications section where we can force modification where otherwise it is not possible using direct declarative configuration.

There is a specific section named modifications where we can configure items to be removed/deleted or forcefully modified in the policy.

In this example, we specify that we wish to remove the file type log from the disallowed file types list.

{
    "policy": {
        "name": "modifying_disallowed_file_types",
        "template": {
            "name": "POLICY_TEMPLATE_NGINX_BASE"
        },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking"
    },
    "modifications": [
        {
            "entityChanges": {
                "type": "explicit"
            },
            "entity": {
                "name": "log"
            },
            "action": "delete",
            "entityType": "filetype"
        }
    ]
}

External References

External references in policy are defined as any code blocks that can be used as part of the policy without being explicitly pasted within the policy file. This means that you can have a set of pre-defined configurations for parts of the policy, and you can incorporate them as part of the policy by simply referencing them. This would save a lot of overhead having to concentrate everything into a single policy file.

A perfect use case for external references is when you wish to build a dynamic policy that depends on moving parts. You can have code create and populate specific files with the configuration relevant to your policy, and then compile the policy to include the latest version of these files, ensuring that your policy is always up-to-date when it comes to a constantly changing environment.

Note: Any update of a single file referenced in the policy will not trigger a policy compilation. This action needs to be done actively by the user.

To use the external references capability, in the policy file the direct property is replaced by “xxxReference” property, where xxx defines the replacement text for the property. For example, modifications section is replaced by modificationsReference.

Types of References

There are different implementations based on the type of references that are being made.

URL Reference

URL reference is the method of referencing an external source via providing its full URL. This is a very useful method when trying to combine or consolidate parts of the policy that are present on different server machines.

Note: You need to make sure that the server where the resource files are located is always available when you are compiling your policy.

Example Configuration

In this example, we are creating a skeleton policy, then enabling the file type violation. However, we do not wish to specify the file types as these file types depend on an app that defines these types. We therefore wish to have this section populated from an external reference. Please note that the filetypes section is replaced by the filetypeReference section. For a list of all the available reference options, please consult with the documentation (declarative section). In the filetypeReference section, we define a key/value pair, where the key defines what type of reference we are making, while the value defines the actual URL to use to reach that reference item.

For the content of the file itself, it is an extension of the original JSON format for the policy, as if this section was cut from the policy and pasted into the file.

Policy configuration:

{
    "name": "external_resources_file_types",
    "template": {
        "name": "POLICY_TEMPLATE_NGINX_BASE"
    },
    "applicationLanguage": "utf-8",
    "enforcementMode": "blocking",
    "blocking-settings": {
        "violations": [
            {
                "name": "VIOL_FILETYPE",
                "alarm": true,
                "block": true
            }
        ]
    },
    "filetypeReference": {
        "link": "http://domain.com:8081/file-types.txt"
    }
}

Content of the referenced file file-types.txt:

[
    {
        "name": "*",
        "type": "wildcard",
        "allowed": true,
        "checkPostDataLength": false,
        "postDataLength": 4096,
        "checkRequestLength": false,
        "requestLength": 8192,
        "checkUrlLength": true,
        "urlLength": 2048,
        "checkQueryStringLength": true,
        "queryStringLength": 2048,
        "responseCheck": false
    },
    {
        "name": "pat",
        "allowed": false
    },
    {
        "name": "mat",
        "allowed": false
    }
]

HTTPS Reference

HTTPS references are a special case of URL references. It uses the HTTPS protocol instead of the HTTP protocol. Please make sure that the webserver you are downloading the resources from does also support HTTPS protocol and has certificates setup properly.

  • Certificates must be valid in date (not expired) during the policy compilation.
  • Certificates must be signed by a trusted CA.
  • For Self-signed certificates, you need to make sure to add your certificates to the trusted CA of the machine where App Protect is installed.
  • Certificates must use the exact domain name that the certificate was issued for. For example, SSL will differentiate between domain.com and www.domain.com, considering each a different domain name.
Example Configuration

In this configuration, we are completely satisfied with the basic default policy, and we wish to use it as is. However, we wish to define a custom response page using an external file located on an HTTPS web server. The external reference file contains our custom response page configuration.

Policy configuration:

{
    "name": "external_references_custom_respsonse",
    "template": {
        "name": "POLICY_TEMPLATE_NGINX_BASE"
    },
    "applicationLanguage": "utf-8",
    "enforcementMode": "blocking",
    "responsePageReference": {
        "link": "https://securedomain.com:8081/response-pages.txt"
    }
}

Content of the referenced file response-pages.txt:

[
    {
        "responseContent": "<html><head><title>Custom Reject Page</title></head><body>This is a custom response page, it is supposed to overwrite the default page with custom text.<br><br>Your support ID is: <%TS.request.ID()%><br><br><a href='javascript:history.back();'>[Go Back]</a></body></html>",
        "responseHeader": "HTTP/1.1 302 OK\\r\\nCache-Control: no-cache\\r\\nPragma: no-cache\\r\\nConnection: close",
        "responseActionType": "custom",
        "responsePageType": "default"
    }
]
Example Configuration

In this example, we would like to enable all attack signatures. Yet, we want to exclude specific signatures from being enforced.

Policy configuration:

{
    "policy": {
        "name": "external_resources_signature_modification",
        "template": {
            "name": "POLICY_TEMPLATE_NGINX_BASE"
        },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "signature-sets": [
            {
                "name": "All Signatures",
                "block": true,
                "alarm": true
            }
        ]
    },
    "modificationsReference": {
        "link": "http://my-domain.com:8081/modifications.txt"
    }
}

Content of the referenced file modifications.txt:

{
    "modifications": [
        {
            "entityChanges": {
                "enabled": false
            },
            "entity": {
                "signatureId": 200001834
            },
            "entityType": "signature",
            "action": "add-or-update"
        }
    ]
}

File Reference

File references refers to accessing local resources on the same machine, as opposed to accessing a remote resource on another server/machine. The user can specify any location that is accessible by App Protect except for the root folder (“/”). If no full path is provided, the default path /etc/app_protect/conf will be assumed. Note that file references can only be on the local machine: you cannot use remote hosts!

Here are some examples of the typical cases:

Link URL Format (examples) File Path Comment
file:///foo.json /etc/app_protect/conf/foo.json Default directory assumed
file://foo.json /etc/app_protect/conf/foo.json Formally illegal, but tolerated as long as there is no trailing slash.
file:///etc/app_protect/conf/foo.json /etc/app_protect/conf/foo.json Full path, but still the default one
file:///bar/foo.json /bar/foo.json Non-default path
file://etc/app_protect/conf/foo.json Not accepted “etc” is interpreted as remote host name
Example Configuration

In this example, we would like to enable all attack signatures. Yet, we want to exclude specific signatures from being enforced. To do this, we reference a local file on the machine.

Policy Configuration:

{
    "policy": {
        "name": "external_resources_signature_modification",
        "template": {
            "name": "POLICY_TEMPLATE_NGINX_BASE"
        },
        "applicationLanguage": "utf-8",
        "enforcementMode": "blocking",
        "signature-sets": [
            {
                "name": "All Signatures",
                "block": true,
                "alarm": true
            }
        ]
    },
    "modificationsReference": {
        "link": "file:///modifications.txt"
    }
}

Content of the referenced file modifications.txt:

{
    "modifications": [
        {
            "entityChanges": {
                "enabled": false
            },
            "entity": {
                "signatureId": 200001834
            },
            "entityType": "signature",
            "action": "add-or-update"
        }
    ]
}

Configuration Errors

If, for any reason, the configuration was done incorrectly, the policy compilation process will fail with the following error:

APP_PROTECT { "event": "configuration_load_failure" ...

The error details that follow will depend on the exact situation causing the policy compilation to fail. If the policy compilation process fails, the compiler will revert to the last working policy and all the changes for the last policy compilation attempt will be lost.

Directives

Global Directives

Global configuration consists of a series of nginx.conf directives at the http context controlling aspects that are not specific to a specific application.

When applied to a cluster, all cluster members will get the same globals as expected.

Note: Whether an incoming request is inspected by NGINX App Protect may be determined by the URL in the request. This happens if you configure app_protect_enable and app_protect_policy_file directives in the location scope. In the case where the URL itself has violations such as bad unescape or illegal metacharacter then the request might be assigned to a location in which NGINX App Protect is disabled or has a relaxed policy that does not detect these violations. Such malicious requests will be allowed without inspection. In order to avoid this, it is recommended to have a basic policy enabled at the http scope or at least at the server scope to process malicious requests in a more complete manner.

Directive Name Syntax Description Default
app_protect_physical_memory_util_thresholds app_protect_physical_memory_util_thresholds high=<number_0-100> low=<number_0-100> Sets the physical memory utilization thresholds for entering (high) and exiting (low) failure mode. When the high threshold is exceeded the system enters failure mode until memory drops below the low threshold. Setting the value of 100 disables this feature. high=low=100 (disabled)
app_protect_cpu_thresholds app_protect_cpu_thresholds high=<number_0-100> low=<number_0-100>
Sets the CPU utilization thresholds for entering and exiting failure mode respectively: when the high threshold is exceeded the system enters failure mode until CPU drops below the low threshold. Setting the value of 100 disables this feature.
Note: The system does not enter failure mode during policy compilation after reload even if the threshold is exceeded.
high=low=100 (disabled)
app_protect_failure_mode_action app_protect_failure_mode_action pass | drop
How to handle requests when the App Protect Enforcer cannot process them, either because it is down, disconnected or because of excessive CPU or memory utilization. There are two values:
  • pass: Pass the request without App Protect Enforcer inspection, a.k.a. “fail-open”.
  • drop: Drop the request by resetting connection. No response page is returned, a.k.a. “fail-close”.
pass
app_protect_cookie_seed app_protect_cookie_seed <string> A long randomized string that serves to generate the encryption key for the cookies generated by App Protect. The string should contain only alphanumeric characters and be no longer than 1000 characters. Auto-generated random string
app_protect_compressed_requests_action app_protect_compressed_requests_action pass | drop
Determines how to handle compressed requests. There are two values:
  • pass: Pass the request without App Protect Enforcer inspection, a.k.a. “fail-open”.
  • drop: Drop the request by resetting connection. No response page is returned, a.k.a. “fail-close”.
drop
app_protect_request_buffer_overflow_action app_protect_request_buffer_overflow_action pass | drop
Determines how to handle requests in case the NGINX request buffer is full and requests cannot be buffered anymore. There are two values:
  • pass: Pass the request without App Protect Enforcer inspection, a.k.a. “fail-open”.
  • drop: Drop the request by resetting connection. No response page is returned, a.k.a. “fail-close”.
pass

App Protect Specific Directives

This table summarizes the nginx.conf directives for NGINX App Protect functionality.

Directive Name Syntax Functionality nginx.conf Contexts Example
load_module load_module <library_file_path> NGNIX directive to load the App Protect module. It must be invoked with the App Protect library path Global load_module /lib/app_protect.so
app_protect_enable app_protect_enable on | off Whether to enable App Protect at the respective context. If not present, inherits from the parent context HTTP, Server, Location app_protect_enable on
app_protect_policy_file app_protect_policy_file <file_path> Set a App Protect policy configuring behavior for the respective context. HTTP, Server, Location app_protect_policy /config/waf/strict_policy.json
app_protect_security_log_enable app_protect_security_log_enable on | off Whether to enable the App Protect per-request log at the respective context. HTTP, Server, Location app_protect_security_log_enable on
app_protect_security_log app_protect_security_log <file_path> <destination> Specifies the per-request logging: what to log and where HTTP, Server, Location app_protect_security_log /config/waf/log_illegal.json syslog:localhost:522

Horizontal Scaling

NGINX App Protect can be deployed in multiple instances that share the traffic to the same applications. In that case all the instances must share the same configuration files. It is your responsibility to synchronize the files on all instances. You also have to provide a load balancing solution in front of those instances such as another NGINX instance.

When deploying multiple scalability instances you have to add the app_protect_cookie_seed directive to nginx.conf in the http block:

...
http {
    ...
    app_protect_cookie_seed jkldsf90upiokasdj120;
    ...
    server {
        listen       80;
...
}
...

As the argument of this directive, put a random alphanumeric string of at least 20 characters length (but not more than 1000 characters). That seed is used by NGINX App Protect to generate the encryption key for the cookies it creates. These cookies are used for various purposes such as validating the integrity of the cookies generated by the application.

In the absence of this directive, App Protect generates a random string by itself. In that case, each instance will have a different seed. A cookie created and encrypted on one instance of App Protect will fail to be decrypted when sent by the same client to another App Protect instance having a different encryption key.

Failure Mode

If the App Protect daemons are down or disconnected from the NGINX workers, there are two modes of operation until they are up and connected again:

  • Pass the traffic without inspection. Use this when preferring availability over security. This mode is also known as “fail open”.
  • Drop the traffic. Use this when preferring security over availability. This mode is also known as “fail closed”.

The default is to pass, fail open, but you can control this using the app_protect_failure_mode_action directive with one argument with two possible values: “pass” or “fail” for the two above options.

This directive is also placed in the http block of the nginx.conf file.

...
http {
    ...
    app_protect_failure_mode_action drop;
    ...
    server {
        listen       80;
...
    }
...

Handling Compressed Requests

Requests with compressed body encoding are rarely used and NGINX App Protect does not support them. Similar to failure mode, you can decide what to do with those requests. Either:

  • Pass the traffic without inspection, or
  • Drop the traffic. This is the preferred option as passing would create a security breach.

The default is to Drop, fail open, but you can control this using the app_protect_compressed_requests_action directive with one argument with two possible values: “pass” or “fail” for the two above options.

This directive is also placed in the http block of the nginx.conf file.

...
http {
    ...
    app_protect_compressed_requests_action drop;
    ...
    server {
        listen       80;
...
    }
...

Violations

App Protect violations are rated by the App Protect algorithms to help distinguish between attacks and potential false positive alerts. A violation rating is a numerical rating that our algorithms give to requests based on the presence of violation(s). Each violation type and severity contributes to the calculation of the final rating. The final rating then defines the action taken for the specific request. As per the default policy, any violation rating of 1, 2 and 3 will not cause the request to be blocked and only a log will be generated with alerted status. If the violation rating is 4 or 5, the request is blocked: a blocking page is displayed and a log generated for the transaction with blocked status. Violation ratings are displayed in the logs by default.

Supported Violations

The following violations are supported and can be enabled by turning on the alarm and/or block flags.

Violation Name Title Enabled Flags in Default Template Description Comment
VIOL_ASM_COOKIE_MODIFIED Modified ASM cookie Alarm The system checks that the request contains an ASM cookie that has not been modified or tampered with. Blocks modified requests.  
VIOL_ATTACK_SIGNATURE Attack signature detected N/A The system examines the HTTP message for known attacks by matching it against known attack patterns. Determined per signature set.
VIOL_BLACKLISTED_IP IP is blacklisted Alarm The violation is issued when a request comes from an IP address that falls in the range of an IP address exception marked for “always blocking”, that is, the black list of IPs. Would trigger Violation Rating of 5.
VIOL_COOKIE_EXPIRED Expired timestamp Alarm The system checks that the timestamp in the HTTP cookie is not old. An old timestamp indicates that a client session has expired. Blocks expired requests. The timestamp is extracted and validated against the current time. If the timestamp is expired and it is not an entry point, the system issues the Expired Timestamp violation.  
VIOL_COOKIE_LENGTH Illegal cookie length Alarm The system checks that the request does not include a cookie header that exceeds the acceptable length specified in the security policy. Determined by policy setting which is disabled in default template.
VIOL_COOKIE_MALFORMED Cookie not RFC-compliant Alarm

This violation occurs when HTTP cookies contain at least one of the following components:

  • Quotation marks in the cookie name.
  • A space in the cookie name.
  • An equal sign (=) in the cookie name. Note: A space between the cookie name and the equal sign (=), and between the equal sign (=) and cookie value is allowed.
  • An equal sign (=) before the cookie name.
  • A carriage return (hexadecimal value of 0xd) in the cookie name.
 
VIOL_COOKIE_MODIFIED Modified domain cookie(s) Alarm The system checks that the web application cookies within the request have not been tampered, and the system checks that the request includes a web application cookie defined in the security policy. Determined by cookie type: applied to “enforced” cookies.
VIOL_DATA_GUARD Data Guard: Information leakage detected Alarm The system examines responses and searches for sensitive information. Controlled by the DG enable flag which is disabled in default template.
VIOL_ENCODING Failed to convert character Alarm The system detects that one of the characters does not comply with the configured language encoding of the web application’s security policy. Enforced by NGINX core, reported by App Protect.
VIOL_EVASION Evasion technique detected Alarm This category contains a list of evasion techniques that attackers use to bypass detection.  
VIOL_FILETYPE Illegal file type Alarm The system checks that the requested file type is configured as a valid file type, or not configured as an invalid file type, within the security policy. Only for disallowed file types.
VIOL_HEADER_LENGTH Illegal header length Alarm The system checks that the request includes a total HTTP header length that does not exceed the length specified in the security policy. The actual size in default policy is 4 KB
VIOL_HEADER_METACHAR Illegal meta character in header Alarm The system checks that the values of all headers within the request only contain meta characters defined as allowed in the security policy.  
VIOL_HTTP_PROTOCOL HTTP protocol compliance failed Alarm This category contains a list of validation checks that the system performs on HTTP requests to ensure that the requests are formatted properly.  
VIOL_HTTP_RESPONSE_STATUS Illegal HTTP response status Alarm The server response contains an HTTP status code that is not defined as valid in the security policy.  
VIOL_JSON_FORMAT JSON data does not comply with format settings Alarm The system checks that the request contains JSON content and complies with the various request limits within the defense configuration in the security policy’s JSON profile. Enforces valid JSON requests and protects the server from JSON parser attacks. This violation is generated when a problem is detected in a JSON request, generally checking the message according to boundaries such as the message’s size and meta characters in parameter value. Controlled from the default JSON profile.
VIOL_JSON_MALFORMED Malformed JSON data Alarm The system checks that the request contains JSON content that is well-formed. Enforces parsable JSON requests.  
VIOL_METHOD Illegal method Alarm The system checks that the request references an HTTP request method that is found in the security policy. Enforces desired HTTP methods; GET and POST are always allowed.

These HTTP methods are supported:

  • GET
  • HEAD
  • POST
  • PUT
  • PATCH
  • DELETE
  • OPTIONS
VIOL_POST_DATA_LENGTH Illegal POST data length Alarm The system checks that the request contains POST data whose length does not exceed the acceptable length specified in the security policy. In * file type entity. This check is disabled by default.
VIOL_QUERY_STRING_LENGTH Illegal query string length Alarm The system checks that the request contains a query string whose length does not exceed the acceptable length specified in the security policy. In * file type entity. Actual size is 2 KB.
VIOL_REQUEST_LENGTH Illegal request length Alarm The system checks that the request length does not exceed the acceptable length specified in the security policy per the requested file type. In * file type entity. This check is disabled by default.
VIOL_REQUEST_MAX_LENGTH Request length exceeds defined buffer size Alarm The system checks that the request length is not larger than the maximum memory buffer size of the ASM. Note that this is a BIG-IP unit parameter that protects the ASM from consuming too much memory across all security policies which are active on the device. Default is 10MB
VIOL_URL_LENGTH Illegal URL length Alarm The system checks that the request is for a URL whose length does not exceed the acceptable length specified in the security policy. In * file type entity. Actual size is 2 KB.
VIOL_URL_METACHAR Illegal meta character in URL Alarm The system checks that the incoming request includes a URL that contains only meta characters defined as allowed in the security policy. Enforces a desired set of acceptable characters.  
VIOL_XML_FORMAT XML data does not comply with format settings Alarm The system checks that the request contains XML data that complies with the various document limits within the defense configuration in the security policy’s XML profile. Enforces proper XML requests and the data failed format/defense settings such as the maximum document length. This violation is generated when a problem in an XML document is detected (for example, an XML bomb), generally checking the message according to boundaries such as the message’s size, maximum depth, and maximum number of children. Controlled by the default XML profile
VIOL_XML_MALFORMED Malformed XML data Alarm The system checks that the request contains XML data that is well-formed, according to W3C standards. Enforces proper XML requests.  
VIOL_RATING_THREAT Request is likely a threat Alarm and Block The combination of violations in this request determined that the request is likely to be a threat. For VR = 4 or 5
VIOL_RATING_NEED_EXAMINATION Request needs further examination Disabled The combination of violations could not determine whether the request is a threat or violations are false positives thus requiring more examination. For VR = 3
VIOL_PARAMETER_MULTIPART_NULL_VALUE Null in multi-part parameter value Disabled

The system checks that the multi-part request has a parameter value that does not contain the NULL character (0x00). If a multipart parameter with binary content type contains NULL in its value, the enforcer issues this violation. The exceptions to this are:

  • If that parameter is configured in the policy as “Ignore value”.
  • If that parameter is configured in the security policy as “user-input file upload”.
  • If the parameter has a content-type that contains the string ‘XML’ and the parameter value contains a valid UTF16 encoded XML document (the encoding is valid). In this case NULL is allowed as it is part of the UTF16 encoding.
 
VIOL_PARAMETER_NAME_METACHAR Illegal meta character in parameter name Alarm The system checks that all parameter names within the incoming request only contain meta characters defined as allowed in the security policy.  
VIOL_PARAMETER_VALUE_METACHAR Illegal meta character in value Alarm The system checks that all parameter values, XML element/attribute values, or JSON values within the request only contain meta characters defined as allowed in the security policy. Enforces proper input values.  
VIOL_THREAT_CAMPAIGN Threat campaign detected Block The system examines the HTTP message for known threat campaigns by matching it against known attack patterns.  

HTTP Compliance Sub-Violations

The following table specifies the HTTP Compliance sub-violation settings. All are supported in NGINX, but not all are enabled in the default App Protect security template. The table specifies which. Some of the checks are enforced by NGINX Plus and App Protect only gets a notification. Note: In this case, the request is always blocked regardless of the App Protect policy.

Sub-Violation Default Template Enforced by Description
Unparsable request content Enabled NGINX This violation is triggered when the system’s parser cannot parse the message.
Several Content-Length headers Enabled NGINX More than one content-length header is a non RFC violation. Indicates an HTTP response splitting attack.
POST request with Content-Length: 0 Disabled App Protect POST request is usually sent with request body. This sub-violation is issued when a request has empty or no body at all.
Null in request Enabled Null in header - NGINX, null in body - App Protect The system issues a violation for requests with a NULL character anywhere in the request (except for a NULL in the binary part of a multipart request).
No Host header in HTTP/1.1 request Enabled NGINX Examines requests using HTTP/1.1 to see whether they contain a “Host” header.
Multiple host headers Enabled App Protect Examines requests to ensure that they contain only a single “Host” header.
Host header contains IP address Enabled App Protect The system verifies that the request’s host header value is not an IP address to prevent non-standard requests.
High ASCII characters in headers Enabled NGINX Checks for high ASCII characters in headers (greater than 127).
Header name with no header value Disabled App Protect The system checks for a header name without a header value.
CRLF characters before request start Enabled App Protect Examines whether there is a CRLF character before the request method. If there is, the system issues a violation.
Content length should be a positive number Enabled NGINX The Content-Length header value should be greater than zero; only a numeric positive number value is accepted.
Chunked request with Content-Length header Enabled App Protect The system checks for a Content-Length header within chunked requests.
Check maximum number of parameters Enabled: 500 App Protect The system compares the number of parameters in the request to the maximum configured number of parameters.
Check maximum number of headers Enabled : 50 App Protect The system compares the request headers to the maximal configured number of headers.
Unescaped space in URL Enabled App Protect The system checks that there is no unescaped space within the URL in the request line. Such spaces split URLs introducing ambiguity on picking the actual one.
Body in GET or HEAD requests Disabled App Protect Examines GET and HEAD requests which have a body.
Bad multipart/form-data request parsing Enabled App Protect When the content type of a request header contains the substring “Multipart/form-data”, the system checks whether each multipart request chunk contains the strings “Content-Disposition” and “Name”. If they do not, the system issues a violation.
Bad multipart parameters parsing Enabled App Protect
The system checks the following:
  1. A boundary follows immediately after request headers.
  2. The parameter value matches the format: ‘name=”param_key”;rn.
  3. A chunked body contains at least one CRLF.
  4. A chunked body ends with CRLF.
  5. Final boundary was found on multipart request.
  6. There is no payload after final boundary.

If one of these is false, the system issues a violation.

Bad HTTP version Enabled NGINX Enforces legal HTTP version number (only 0.9 or higher allowed).
Bad host header value Enabled Detected non RFC compliant header value. NGINX

Evasion Techniques Sub-Violations

The following table specifies the Evasion Techniques sub-violation settings. All are supported in NGINX Plus.

Sub-Violation Default Template Description
%u decoding Enabled Performs Microsoft %u unicode decoding (%UXXXX where X is a hexadecimal digit). For example, the system turns a%u002fb to a/b. The system performs this action on URI and parameter input to evaluate if the request contains an attack.
Apache whitespace Enabled The system detects the following characters in the URI: 9 (0x09), 11 (0x0B), 12 (0x0C), and 13 (0x0D).
Bad unescape Enabled The system detects illegal HEX encoding. Reports unescaping errors (such as %RR).
Bare byte decoding Enabled The system detects higher ASCII bytes (greater than 127).
Directory traversals Enabled Ensures that directory traversal commands like ../ are not part of the URL. While requests generated by a browser should not contain directory traversal instructions, sometimes requests generated by JavaScript have them.
IIS backslashes Enabled Normalizes backslashes () to slashes (/) for further processing.
IIS Unicode codepoints Enabled Handles the mapping of IIS specific non-ASCII codepoints. Indicates that, when a character is greater than ‘0x00FF’, the system decodes %u according to an ANSI Latin 1 (Windows 1252) code page mapping. For example, the system turns a%u2044b to a/b. The system performs this action on URI and parameter input.
Multiple decoding Enabled: 3 The system decodes URI and parameter values multiple times according to the number specified before the request is considered an evasion.

Security Logs

Overview

Security logs (also known as Request logs or Traffic logs) contain information on HTTP requests and responses, how App Protect processes them, and the final decision made based on the configured policy parameters. The policy configuration defines the information contained in the Security log, such as whether requests are passed, blocked or alerted, due to violations, attack signatures, and other criteria.

App Protect uses its own logging mechanism for request logging rather than NGINX’s access logging mechanism (which is NGINX’s default logging mechanism).

The Security log has the following properties:

  • Log Configuration: app_protect_security_log directive referencing security_log.json file

  • Configuration contexts: nginx.conf: http, server, location

  • File Destination? Yes. You can set the destination to either stderr, or an absolute path to a local file, or you can use syslog, and redirect the log with Netcat and pipe:

    nc -vv -l “[ip]” “[port]” > “[name_of_file]” 2>&1
    
  • Syslog Destination? Yes

Directives in nginx.conf

app_protect_security_log_enable

This directive determines whether security logging will be enabled in the respective context.

The security log attributes are determined by the app_protect_security_log directive. The directive can be at the following contexts: http, server and location. When not present at a certain context, the directive is inherited from the context above it: location from server, then from http. If there is no directive at any of these context levels, then the logging is disabled for the respective context.

• Syntax: app_protect_security_log_enable on | off

• Levels: http, server, location

• Example: app_protect_security_log_enable on

Arguments
Argument Mandatory Meaning Default
ON-OFF Yes Whether to enable logging or not off

app_protect_security_log

The security log attributes are determined by the app_protect_security_log directive, if it was enabled in the respective context. The directive can be at the following context levels: http, server and location. When not present at a certain context, the directive is inherited from the context above it: location from server, then from http. If there is no directive at any of these context levels, but logging is enabled then the default is used for the respective context.

• Syntax: app_protect_security_log [LOG-CONFIG-FILE] [DESTINATION]

• Levels: http, server, location

• Examples:

app_protect_security_log "/etc/app_protect/conf/log_default.json" syslog:server=localhost:5144;
app_protect_security_log "/etc/app_protect/conf/log_default.json" /var/log/app_protect/security.log;
app_protect_security_log "/etc/app_protect/conf/log_default.json" stderr;

Note: When using stderr, please make sure that the process bd-socket-plugin is not redirecting the stderr output to file.
- When using the Docker entrypoint.sh startup script from the admin guide, make sure that it doesn’t redirect stderr.
- When using services startup, make sure that the service startup file for nginx-app-protect.service doesn’t redirect stderr.

Arguments
Argument Mandatory Meaning Default
LOG-CONFIG-FILE No The path to the log configuration file. See details below. /etc/app_protect/conf/log_default.json This file is identical to “/opt/app_protect/share/defaults/log_illegal.json” after installation, but can be modified later.
DESTINATION No The destination of the log messages in NGINX format. Only stderr, or an absolute path to a local file, or syslog: and IP/hostname options are accepted. Note: Hostname destination, except for localhost, is currently not supported in App Protect. syslog:server=localhost:514

Security Log Configuration File

The file is in JSON format and consists of two parts:

  1. filter: which requests are to be logged.
  2. content: how the message is formatted.

Filter

The filter is mandatory, although it may be left blank.

Element Meaning Type/Values Default
request_type Log according to what App Protect detected in the request.
Enumerated values:
  • all: all requests, both legal and illegal.
  • illegal: requests with violations (i.e., either alerted or blocked).
  • blocked: requests with violations that were blocked.
all

Content

This part of the configuration file specifies what will be logged, the format of the message, and size restrictions.

Content is mandatory. If the entire content field or any of its attributes are not defined, system-defined default values are used.

Element Meaning Type/Values Mandatory Default Comment
format Selects one of the predefined formats of log messages or a custom format that will be defined by the format_string field.
Enumerated values:
  • splunk: formatted for Splunk SIEM with F5 plugin.
  • arcsight: formatted according to ArcSight Common Event Format (CEF) with custom fields adapted for F5.
  • default: default format for App Protect. See the NGINX Default Format String section below for more details.
  • user-defined: custom format defined by the user in the format_string field.
No default  
format_string Layout template of the logged fields in the log message. String representing the template of the message with placeholders for the message attributes. The currently available security log attributes are specified below in the Available Security Log Attributes section. Each attribute name is delimited by percent signs, for example: %violation_rating% If, and only if, format=user-defined N/A  
max_request_size|Limit in bytes for the size of the request attribute in the log. Must be smaller than max_message_size. Integer representing bytes in the range of 1-2048, or any. any is synonymous to 2048. The type is string in terms of JSON schema, to accommodate the any option. No any Relevant only if the request field is present in the log.  
max_message_size Limit in KB for the total size of the message. Range of values between 1k-64k, must not be smaller than the max_request_size No 2k  

Examples

Default logging content

This is the content of /etc/app_protect/conf/log_default.json. It is used by default when app_protect_security_log_enabled on is set, but app_protect_security_log is not:

{
    "filter": {
        "request_type": "illegal"
    },
    "content": {
        "format": "default",
        "max_request_size": "any",
        "max_message_size": "5k"
    }
}
Log illegal requests in key-value format
{
    "filter": {
        "request_type": "illegal"
    },
    "content": {
        "format": "user-defined",
        "format_string": "client_ip=%ip_client%,client_port=%src_port%,request=%request%,violations=%violations%,signature_ids=%sig_ids%",
        "max_request_size": 2000,
        "max_message_size": "5k"
    }
}
Log state changing requests
{
    "filter": {
        "request_type": "all"
    },
    "content": {
        "format": "default",
        "max_request_size": "any",
        "max_message_size": "5k"
    }
}
A verbose custom formatted message
{
    "filter": {
        "request_type": "illegal"
    },
    "content": {
        "format": "user-defined",
        "format_string": "Request ID %support_id%: %method% %uri% received on %date_time% from IP %ip_client% had the following violations: %violations%",
        "max_request_size": "any",
        "max_message_size": "5k"
    }
}

NGINX Default Format String

When format = default, messages are shown in comma separated key-value pairs consisting of all the attributes appearing in Available Security Log Attributes.

The string starts like this:

“attack_type=“%attack_type%“,blocking_exception_reason=“%blocking_exception_reason%“,...”

Syslog Transport

The syslog transport is over TCP. It is currently unsecured, meaning that SSL/TLS is not supported.

It is not guaranteed that all requests that match the filters will indeed reach their destination especially if the system is overwhelmed by the incoming traffic. In this case some log records may be dropped.

Factory Configuration Files

NGINX will provide example configuration files under /opt/app_protect/share/defaults/ with the following settings:

Name Filter Content
log_illegal illegal requests format=default
log_f5_splunk illegal requests format=splunk, sizes are system-defined and cannot be changed.
log_f5_arcsight illegal requests format=arcsight, sizes are system-defined and cannot be changed.
log_all all format=default

Available Security Log Attributes

The table below lists attributes that are generated in the security logs. When using customized logs (i.e., format=user-defined), you can add or remove entries from the list below.

Attribute Name Description
attack_type A list of comma separated names of suspected attacks identified in a transaction.
blocking_exception_reason The blocking exception reason when a configured violation was not blocked.|
date_time The date and time the request was received by App Protect.
dest_port The port assigned to listen to incoming requests.
ip_client The source IP of the client initiating the request Note: if a proxy is being used, this may differ from the IP in the X-forwarded-for header.
is_truncated A flag that returns true if a request is truncated in the security logs, or false if it is not.
method The method of request. For example, GET, POST, HEAD.
policy_name The name of the App Protect policy for which the violation was triggered.
protocol The protocol used, either HTTP or HTTPS if terminating SSL on App Protect.
request The entire request including headers, query string, and data.
request_status
The status of client request made to Web Application as assigned by the App Protect policy. The possible values are:
  • blocked: The request was blocked due to a violation encountered. A blocking response page was returned to the client.
  • alerted: The request contains violation(s) but is not blocked (typical in cases where the enforcement mode is set to transparent).
  • passed: A successful request with no violations.
response_code The response code returned by the server.
severity The maximum severity calculated from all violations found in the request. It is a static value coming from the Violations.
sig_cves Signature CVEs value of the matched signatures.
sig_ids Signature ID value of the matching signature that resulted in the violation.
sig_names Signature name of the matching signature that resulted in the violation.
sig_set_names The signature set names of the matched signatures.
src_port The source port of the client.
sub_violations Refers to the sub-violations detected under the ‘HTTP protocol compliance failed’ and the ‘Evasion technique detected’ violations.
support_id A unique identifier for a transaction.
unit_hostname host name of the app-protect instance
uri The URI or Uniform Resource Identifier of the request.
violation_details XML including details about each violation.
violation_rating Estimation of the likelihood that the request is indeed a threat on a scale of 0 to 5: 0 - not a threat (no violations), 5 - most likely a threat
vs_name A unique identifier of the location in the nginx.conf file that this request is associated with. It contains the line number of the containing server block in nginx.conf, the server name, a numeric discriminator that distinguishes between multiple entries within the same server, and the location name. For example: ’34-mydomain.com:0-~/.*php(2).
x_forwarded_for_header_value X-Forwarded-For header information. This option is commonly used when proxies are involved to track the originator of the request.
outcome
One of the following:
  • PASSED: the request was sent to the backend server.
  • REJECTED: the request was blocked.
outcome_reason
One of the following:
  • SECURITY_WAF_OK: allowed with no violations (legal request).
  • SECURITY_WAF_VIOLATION: blocked due to security violations.
  • SECURITY_WAF_FLAGGED: allowed, although it has violations (illegal).
violations Comma-separated list of logical violation names (e.g. “VIOL_ATTACK_SIGNATURES,VIOL_HTTP_PROTOCOL”)

NGINX App Protect Terminology

This guide assumes that you have some familiarity with various Layer 7 (L7) Hypertext Transfer Protocol (HTTP) concepts, such as Uniform Resource Identifier (URI)/Uniform Resource Locator (URL), method, header, cookie, status code, request, response, and parameters.

Term Definition
Alarm If selected, the NGINX App Protect system records requests that trigger the violation in the remote log (depending on the settings of the logging profile).
Attack signature Textual patterns which can be applied to HTTP requests and/or responses by NGINX App Protect to determine if traffic is malicious. For example, the string <script> inside an HTTP request triggers an attack signature violation.
Attack signature set A collection of attack signatures designed for a specific purpose (such as Apache).
Block To prevent a request from reaching a protected web application.
Block If selected (and enforcement mode is set to Blocking), NGINX App Protect blocks requests that trigger the violation.
Blocking response page A blocking response page is displayed to a client when a request from that client has been blocked. Also called blocking page and response page.
Enforcement mode
Security policies can be in one of two enforcement modes:
  • Transparent mode In Transparent mode, Blocking is disabled for the security policy. Traffic is not blocked even if a violation is triggered with block flag enabled. You can use this mode when you first put a security policy into effect to make sure that no false positives occur that would stop legitimate traffic.
  • Blocking mode In Blocking mode, Blocking is enabled for the security policy, and you can enable or disable the Block setting for individual violations. Traffic is blocked when a violation occurs if you configure the system to block that type of violation. You can use this mode when you are ready to enforce the security policy. You can change the enforcement mode for a security policy in the security policy JSON file.
Entities The elements of a security policy, such as HTTP methods, as well as file types, URLs, and/or parameters, which have attributes such as byte length. Also refers to elements of a security policy for which enforcement can be turned on or off, such as an attack signature.
False positive An instance when NGINX App Protect treats a legitimate request as a violation.
File types Examples of file types are .php, .asp, .gif, and .txt. They are the extensions for many objects that make up a web application. File Types are one type of entity a NGINX App Protect policy contains.
Illegal request A request which violates a security policy
Legal request A request which has not violated the security policy.
Loosening The process of adapting a security policy to allow specific entities such as File Types, URLs, and Parameters. The term also applies to attack signatures, which can be manually disabled — effectively removing the signature from triggering any violations.
Parameters Parameters consist of “name=value” pairs, such as OrderID=10. The parameters appear in the query string and/or POST data of an HTTP request. Consequently, they are of particular interest to NGINX App Protect because they represent inputs to the web application.
TPS/RPS Transactions per second (TPS)/requests per second (RPS). In NGINX App Protect, these terms are used interchangeably.
Tuning Making manual changes to an existing security policy to reduce false positives and increase the policy’s security level.
URI/URL The Uniform Resource Identifier (URI) specifies the name of a web object in a request. A Uniform Resource Locator (URL) specifies the location of an object on the Internet. For example, in the web address, http://www.siterequest.com/index.html, index.html is the URI, and the URL is http://www.siterequest.com/index.html. In NGINX App Protect, the terms URI and URL are used interchangeably.
Violation Violations occur when some aspect of a request or response does not comply with the security policy. You can configure the blocking settings for any violation in a security policy. When a violation occurs, the system can Alarm or Block a request (blocking is only available when the enforcement mode is set to Blocking).