TR7 WAF Log Format (HTTP)
About the Format
TR7 WAF Log Format is a specialized log format that contains only the WAF (Web Application Firewall) event information. It takes place in the Line Format list in the profile form with the TR7 WAF Log option.
This format focuses on the security events: a log is produced only for the requests blocked by the WAF; the clean traffic and the requests that are only monitored (monitor) do not produce a log. It is ideal for the environments that want to monitor only the security events instead of a full access log.
Use cases
- WAF-only security monitoring.
- Security event correlation.
- Low-volume security log.
- SOC and security analytics.
Warning
This format works only on the vServices that have a WAF profile assigned. On the vServices that do not have a WAF profile (including L7 TCP), no log is produced at all even if this format is selected; no sending is made to the defined log servers either and no warning is given in the interface.
Supported Features
Example Log
{
"uid": "AC10652A:D7236AA19B66:240002D",
"totalScore": 8,
"attacks": [
{
"payload": "/cmd.exe",
"id": 130005,
"score": 8,
"monitor": false,
"scope": "path"
}
],
"action": "block",
"wafTime": 1.485
}Field Descriptions
Basic Fields
| Field | Example | Description |
|---|---|---|
uid | AC10652A:D7236AA19B66:240002D | The unique event identifier |
totalScore | 8 | The total attack score |
action | block | The applied action: block · monitor · fpc. In this format it is in practice always block; in the other two situations the record is not produced anyway. |
wafTime | 1.485 | The WAF processing time (milliseconds) |
The order of the fields is not fixed; while the JSON is being parsed, it must be read according to the key name. The score, scope, monitor and payload fields depend on the log field selection in the WAF profile and can be turned off; in addition, severity and the rule meta information (name, desc, category, cwe, mitre, capec, owaspWeb, owaspApi, target) can be added.
The WAF timeout record does not carry this schema
In the synthetic record produced when the WAF scan times out, the uid and action fields are not present; the attacks entry does not carry payload and monitor either. The record comes with the values totalScore 100, id 369999 and wafTime 2000. The parsers that assume a fixed schema give an error on this line.
The attacks Array
Every attack object contains the following fields:
| Field | Example | Description |
|---|---|---|
attacks | [...] | The list of the detected matches. As more than one rule can match in the same request, the same rule can enter the list more than once as well. |
payload | /cmd.exe | The detected malicious content. If the rule does not produce a payload, the description of the rule is written instead; it can be turned off completely from the WAF profile. |
id | 130005 | The WAF rule ID. It is the only field printed unconditionally. |
score | 8 | The score of this rule |
monitor | false | The state of the rule itself: if true, the score of this rule is not included in the total. On its own it does not show whether the request was blocked or not. |
scope | path | The component in which the attack was detected: path · query · header · form · json · xml · raw |
The uid Structure
The unique event identifier (uid) consists of the hexadecimal representation of five pieces of information separated into three groups by colons; the colons are not aligned with the boundaries of this information:
AC10652A : D7236AA19B66 : 240002D
│ │ │ │ │
│ │ │ │ └── The request counter
│ │ │ └───── The millisecond
│ │ └──────────── The Unix timestamp (seconds)
│ └─────────────────── The client source port
└──────────────────────────── The client IP addressThe resolution of the value in the example:
| Part | Hex | Its equivalent |
|---|---|---|
| The client IP address | AC10652A | AC=172, 10=16, 65=101, 2A=42 → 172.16.101.42 |
| The client source port | D723 | 55075 |
| The Unix timestamp | 6AA19B66 | The second at which the record was produced |
| The millisecond | 240 | 576 ms |
| The request counter | 002D | 45 |
Thanks to this structure:
- The attacks coming from the same client can be grouped with the IP component.
- Every record can be identified uniquely and matched with the WAF Event Log.
WARNING
The value does not carry a session identity. Two requests of the same client share a common middle component only when they come from the same source port in the same second; in practice it changes on every TCP connection. The source port (4 digits) and the timestamp (8 digits) are of fixed length; since the millisecond (2-3 digits) and the request counter (at least 4 digits) are joined without a separator, the last group cannot always be parsed definitely.
Score Calculation
The WAF defines a score for every rule. The total score (totalScore) is the sum of the scores of only those that are not in monitoring mode among the matching rules:
totalScore = Σ (attacks[n].score) , the ones where attacks[n].monitor == falseIn the example log above a single rule matched and, since it is monitor: false, the total score is equal to the score of that rule:
Rule 130005: score = 8 (monitor: false)
──────────────────────────────────────────
totalScore = 8The rules in monitoring mode are not included in the total
A rule that is monitor: true appears in the attacks list with its real score, but it is not added to totalScore. For this reason, summing the scores in the list can give a result greater than the totalScore value. In learning mode, on the other hand, no score is summed and totalScore remains 0.
When the score threshold defined in the WAF profile is reached or the threshold is exceeded, the request is blocked; the totalScore: 8 value in the example produced block exactly for this reason in a profile whose threshold is 8.
Use Example: Log Parsing
The examples assume a raw log line
The commands below assume that the file consists of the raw JSON lines. If local (default), rfc3164, rfc5424 or priority is selected as the Log Standard in the log profile, a syslog prefix is added to the beginning of every line and jq cannot parse the line. In this case, either the collector must strip the prefix or raw must be selected in the profile.
# Filter the high-scored attacks
cat waf.log | jq 'select(.totalScore >= 20)'
# Search for a specific rule ID (it prints once per record)
cat waf.log | jq 'select(any(.attacks[]; .id == 130005))'
# Group according to the scope (if the field is turned off, it is skipped as empty)
cat waf.log | jq -r '.attacks[] | select(.scope) | .scope' | sort | uniq -c