Skip to main content

ModSecurity - Web Application Firewall

Quick Start

We have a dedicated ingress-controller with ModSecurity enabled.

To enable and point your application to this ingress-controller, use the following annotations and ingressClassName on your ingress manifest file:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: <ingress-name>
 namespace: <namespace-name>
 annotations:
   nginx.ingress.kubernetes.io/enable-modsecurity: "true"
   nginx.ingress.kubernetes.io/modsecurity-snippet: |
     SecRuleEngine On
spec:
 tls:
   ingressClassName: modsec

Introduction

What is a Web Application Firewall (WAF)?

A Web Application Firewall or WAF helps protect web applications by filtering and monitoring HTTP traffic between a web application and the Internet. A WAF is a layer 7 defense and is one of the most common means of protecting against malicious web application security flaws at the application layer. However, it must be noted that a WAF is not designed and does not protect against all types of attacks.

ModSecurity

ModSecurity is an open source, cross platform web application firewall (WAF) developed by Trustwave’s SpiderLabs. It has a robust event-based programming language which provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring and logging.

For the Cloud Platform, ModSecurity has been configured as an opt-in feature. New and current applications will require a specific set of annotations to be added to their ingress manifest file.

Ingress Annotations

We have a dedicated ingress-controller with ModSecurity enabled separate from the default ingress-controller. To point your application to the ModSec ingress-controller, add the following to your ingress spec field:

ingressClassName: modsec

To enable ModSecurity for your application, add the following annotation to your ingress manifest file:

nginx.ingress.kubernetes.io/enable-modsecurity: "true"

The above annotation enables ModSecurity for the ingress on the nginx ingress-controller in detection only mode. There is no disruptive action if a critical rule triggers, but it is logged in the nginx-ingress.log file. The SecRuleEngine defaults to Detection Only Mode.

Adding the annotation below, SecRuleEngine On configures ModSecurity to actively block traffic classed as malicious using Anomaly Scoring:

nginx.ingress.kubernetes.io/modsecurity-snippet: |
      SecRuleEngine On

The SecRuleEngine On configures ModSecurity to actively block traffic classed as malicious using Anomaly Scoring.

nginx.ingress.kubernetes.io/modsecurity-transaction-id: "$request_id"

The above annotation is optional, but it can be used to pass transactionIDs from nginx.

Example:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: <ingress-name>
  namespace: <namespace-name>
  annotations:
    external-dns.alpha.kubernetes.io/set-identifier: <ingress-name>-<namespace-name>-<colour>
    external-dns.alpha.kubernetes.io/aws-weight: "100"
    nginx.ingress.kubernetes.io/enable-modsecurity: "true"
    nginx.ingress.kubernetes.io/modsecurity-snippet: |
      SecRuleEngine On
spec:
  tls:
    ingressClassName: modsec
  - hosts:
    - <application_url>
  rules:
  - host: <application_url>
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
          backend:
            service:
              name: app-service
              port:
                name: 8080

(Note - Please change the ingress-name and namespace-name values in the above example. The colour should be green for ingress in EKS live cluster)

Logging

All disruptive actions are logged in the ModSecurity audit log file and the error log for for nginx ingress-controller. Fluent-bit is used to ship error logs into the Cloud Platform ELK stack.

To view your modsec ingress logs, log into kibana, select index live_kubernetes_ingress* and search for ModSecurity. You can filter down to a particular host using host-name. An example of this kibana search

To get the detailed modsec audit log for a malicious event transaction, do a search using the unique_id value from the above search result. An example of this modsec unique_id search

Error Log Example:

2019/01/01 11:00:00 [error] 12647#12647: *1158975 [client 12.123.1.12] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge'
 with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `5' ) [file "/etc/nginx/owasp-modsecurity-crs/rules/
 REQUEST-949-BLOCKING-EVALUATION.conf"] [line "01"] [id "00001"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""]
 [severity "2"] [ver ""] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag
 "attack-generic"] [hostname "12.123.1.12"] [uri "/"] [unique_id "1663242265"] [ref ""],
client: 12.123.1.12, server: test-ingress.url, request: "GET /?exec=/bin/bash HTTP/2.0", host: "test-ingress.url"

OWASP Rules

The OWASP ModSecurity Core Rule Set (CRS) is a set of generic attack detection rules for use with ModSecurity. These rules are enabled on the ingress-controller level on the dedicated ModSec ingress-controller. The CRS aims to protect web applications from a wide range of attacks, including the OWASP Top Ten, with a minimum of false alerts. The CRS provides protection against many common attack categories, including:

  • SQL Injection (SQLi)
  • Cross Site Scripting (XSS)
  • Local File Inclusion (LFI)
  • Remote File Inclusion (RFI)
  • PHP Code Injection
  • Shellshock
  • Unix/Windows Shell Injection
  • Session Fixation
  • Scripting/Scanner/Bot Detection
  • Metadata/Error Leakages

Paranoia Level

The Paranoia Level (PL) setting allows you to choose the desired level of rule checks. For the Cloud Platform implementation, this has been set to PL1. For more information on Paranoia Levels, please go to the What are paranoia levels, and which level should I choose? section here

Anomaly Scoring Mode

Traditional Detection or Passive Mode is the most basic operating mode where all of the rules are run as individual entities. In this mode no intelligence is shared between rules and each rule has no information about any previous rule matches. That is to say, in this mode, if a rule triggers, it will execute any disruptive/logging actions specified on the current rule.

Anomaly scoring mode implements the concept of Collaborative Detection and Delayed Blocking. Rule logic has been set to decouple the inspection/detection from the blocking functionality. The individual rules can be run so that the detection remains, however instead of applying any disruptive action at that point, the rules will contribute to a transactional anomaly score collection. In addition, each rule will also store meta-data about each rule match (such as the Rule ID, Attack Category, Matched Location and Matched Data) for later logging. For more information in anomaly scoring, click here

Sensitive logs

Audit log is quite large as it logs everything about the request, like Request Header, Response Header, Request Body and Body Response, etc. So, Modsec ingress-controller is configured with SecAuditLogParts AEFHKZ to be logged in the error logs. Please make sure you don’t send any sensitive information in the log parts.

A   Audit log header (mandatory)
E   Response body
F   Response headers
H   Audit log trailer, which contains additional data
K   Contains a list of all rules that matched for the transaction
Z   Final boundary (mandatory)
This page was last reviewed on 21 February 2023. It needs to be reviewed again on 21 May 2023 .
This page was set to be reviewed before 21 May 2023. This might mean the content is out of date.