@waftester/cli 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +80 -0
- package/LICENSE-COMMUNITY +28 -0
- package/README.md +121 -0
- package/bin/cli.js +152 -0
- package/package.json +52 -0
- package/payloads/community/README.md +45 -0
- package/payloads/community/ai/ml-poisoning.json +173 -0
- package/payloads/community/ai/prompt-injection.json +247 -0
- package/payloads/community/ai/workflow-abuse.json +222 -0
- package/payloads/community/auth/jwt.json +855 -0
- package/payloads/community/auth/login-bypass.json +623 -0
- package/payloads/community/auth/mfa.json +402 -0
- package/payloads/community/auth/oauth.json +421 -0
- package/payloads/community/auth/open-redirect.json +1028 -0
- package/payloads/community/auth/session.json +404 -0
- package/payloads/community/cache/deception.json +402 -0
- package/payloads/community/cache/poisoning.json +403 -0
- package/payloads/community/deserialization/gadget.json +375 -0
- package/payloads/community/deserialization/prototype.json +370 -0
- package/payloads/community/fuzz/content-type.json +397 -0
- package/payloads/community/fuzz/headers.json +401 -0
- package/payloads/community/fuzz/methods.json +397 -0
- package/payloads/community/fuzz/obfuscation.json +362 -0
- package/payloads/community/fuzz/special-chars.json +740 -0
- package/payloads/community/fuzz/waf-bypass.json +452 -0
- package/payloads/community/graphql/batching-abuse.json +271 -0
- package/payloads/community/graphql/depth-limit.json +271 -0
- package/payloads/community/graphql/introspection.json +267 -0
- package/payloads/community/injection/crlf.json +569 -0
- package/payloads/community/injection/ldap.json +357 -0
- package/payloads/community/injection/nosqli.json +529 -0
- package/payloads/community/injection/oscmd.json +662 -0
- package/payloads/community/injection/rce-polyglots.json +452 -0
- package/payloads/community/injection/sqli.json +681 -0
- package/payloads/community/injection/ssti.json +584 -0
- package/payloads/community/injection/upload-attacks.json +632 -0
- package/payloads/community/injection/xpath.json +357 -0
- package/payloads/community/injection/xxe.json +716 -0
- package/payloads/community/logic/forced-browsing.json +405 -0
- package/payloads/community/logic/idor.json +1026 -0
- package/payloads/community/logic/privilege.json +337 -0
- package/payloads/community/media/exif-injection.json +225 -0
- package/payloads/community/media/metadata-poison.json +239 -0
- package/payloads/community/protocol/http-smuggling.json +798 -0
- package/payloads/community/protocol/http2-attacks.json +382 -0
- package/payloads/community/protocol/websocket-abuse.json +375 -0
- package/payloads/community/rate-limit/burst-simulation.json +286 -0
- package/payloads/community/rate-limit/bypass-attempts.json +326 -0
- package/payloads/community/rate-limit/zone-tests.json +332 -0
- package/payloads/community/services/authentik.json +415 -0
- package/payloads/community/services/immich.json +423 -0
- package/payloads/community/services/n8n.json +366 -0
- package/payloads/community/sqli-basic.json +182 -0
- package/payloads/community/ssrf/cloud-metadata.json +999 -0
- package/payloads/community/ssrf/dns-rebinding.json +503 -0
- package/payloads/community/ssrf/internal-networks.json +627 -0
- package/payloads/community/ssrf/protocol-smuggling.json +350 -0
- package/payloads/community/ssti/multi-language-templates.json +191 -0
- package/payloads/community/ssti/python-templates.json +200 -0
- package/payloads/community/traversal/basic.json +675 -0
- package/payloads/community/traversal/cloud-credentials.json +107 -0
- package/payloads/community/traversal/config-files.json +193 -0
- package/payloads/community/traversal/encoding.json +558 -0
- package/payloads/community/traversal/null-byte.json +105 -0
- package/payloads/community/traversal/symlink.json +93 -0
- package/payloads/community/traversal/unicode.json +134 -0
- package/payloads/community/traversal/unix-advanced.json +195 -0
- package/payloads/community/traversal/windows-advanced.json +195 -0
- package/payloads/community/waf-bypass/cloudflare-bypass.json +102 -0
- package/payloads/community/waf-bypass/encoding-bypass.json +120 -0
- package/payloads/community/waf-bypass/evasion-techniques.json +164 -0
- package/payloads/community/waf-bypass/hpp-bypass.json +92 -0
- package/payloads/community/waf-bypass/modsecurity-crs.json +220 -0
- package/payloads/community/waf-bypass/protocol-attacks.json +101 -0
- package/payloads/community/waf-bypass/sqlmap-tamper.json +252 -0
- package/payloads/community/waf-bypass/unicode-charset.json +152 -0
- package/payloads/community/waf-bypass/vendor-bypasses.json +72 -0
- package/payloads/community/waf-validation/README.md +172 -0
- package/payloads/community/waf-validation/bypass-techniques.json +272 -0
- package/payloads/community/waf-validation/custom-rules.json +952 -0
- package/payloads/community/waf-validation/evasion-techniques.json +272 -0
- package/payloads/community/waf-validation/modsecurity-core.json +151 -0
- package/payloads/community/waf-validation/owasp-top10.json +236 -0
- package/payloads/community/waf-validation/regression-tests.json +227 -0
- package/payloads/community/xss/csp-bypass.json +431 -0
- package/payloads/community/xss/dom.json +389 -0
- package/payloads/community/xss/filter-bypass.json +1242 -0
- package/payloads/community/xss/mutation.json +263 -0
- package/payloads/community/xss/polyglots.json +371 -0
- package/payloads/community/xss/reflected.json +187 -0
- package/payloads/community/xss/stored.json +330 -0
- package/payloads/crlf-injection.json +182 -0
- package/payloads/ids-map.json +155 -0
- package/payloads/ldap-injection.json +182 -0
- package/payloads/nosql-injection.json +227 -0
- package/payloads/prototype-pollution.json +182 -0
- package/payloads/request-smuggling.json +182 -0
- package/payloads/version.json +28 -0
- package/payloads/xss-advanced.json +227 -0
- package/templates/README.md +221 -0
- package/templates/nuclei/http/waf-bypass/crlf-bypass.yaml +146 -0
- package/templates/nuclei/http/waf-bypass/lfi-bypass.yaml +152 -0
- package/templates/nuclei/http/waf-bypass/nosqli-bypass.yaml +166 -0
- package/templates/nuclei/http/waf-bypass/rce-bypass.yaml +171 -0
- package/templates/nuclei/http/waf-bypass/sqli-basic.yaml +142 -0
- package/templates/nuclei/http/waf-bypass/sqli-evasion.yaml +192 -0
- package/templates/nuclei/http/waf-bypass/ssrf-bypass.yaml +130 -0
- package/templates/nuclei/http/waf-bypass/ssti-bypass.yaml +147 -0
- package/templates/nuclei/http/waf-bypass/xss-basic.yaml +163 -0
- package/templates/nuclei/http/waf-bypass/xss-evasion.yaml +217 -0
- package/templates/nuclei/http/waf-bypass/xxe-bypass.yaml +204 -0
- package/templates/nuclei/http/waf-detection/akamai-detect.yaml +105 -0
- package/templates/nuclei/http/waf-detection/aws-waf-detect.yaml +115 -0
- package/templates/nuclei/http/waf-detection/azure-waf-detect.yaml +114 -0
- package/templates/nuclei/http/waf-detection/cloudflare-detect.yaml +121 -0
- package/templates/nuclei/http/waf-detection/modsecurity-detect.yaml +129 -0
- package/templates/nuclei/workflows/waf-assessment-workflow.yaml +71 -0
- package/templates/output/asff.tmpl +61 -0
- package/templates/output/csv.tmpl +4 -0
- package/templates/output/junit.tmpl +34 -0
- package/templates/output/markdown-report.tmpl +92 -0
- package/templates/output/slack-notification.tmpl +95 -0
- package/templates/output/text-summary.tmpl +56 -0
- package/templates/overrides/api-only.yaml +130 -0
- package/templates/overrides/crs-tuning.yaml +204 -0
- package/templates/overrides/false-positive-suppression.yaml +159 -0
- package/templates/policies/owasp-top10.yaml +152 -0
- package/templates/policies/pci-dss.yaml +124 -0
- package/templates/policies/permissive.yaml +40 -0
- package/templates/policies/standard.yaml +57 -0
- package/templates/policies/strict.yaml +72 -0
- package/templates/report-configs/compliance.yaml +173 -0
- package/templates/report-configs/dark.yaml +136 -0
- package/templates/report-configs/enterprise.yaml +175 -0
- package/templates/report-configs/minimal.yaml +84 -0
- package/templates/report-configs/print.yaml +139 -0
- package/templates/workflows/api-scan.yaml +132 -0
- package/templates/workflows/ci-gate.yaml +129 -0
- package/templates/workflows/full-scan.yaml +133 -0
- package/templates/workflows/quick-probe.yaml +80 -0
- package/templates/workflows/waf-detection.yaml +89 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
id: waf-detect-modsecurity
|
|
2
|
+
info:
|
|
3
|
+
name: ModSecurity WAF Detection
|
|
4
|
+
author: waftester
|
|
5
|
+
severity: info
|
|
6
|
+
description: |
|
|
7
|
+
Detects ModSecurity WAF presence via response headers, Server header
|
|
8
|
+
patterns, error page signatures, and OWASP CRS indicators. Identifies
|
|
9
|
+
ModSecurity version, CRS paranoia level, and audit log patterns.
|
|
10
|
+
Supports both Apache and Nginx + ModSecurity configurations.
|
|
11
|
+
reference:
|
|
12
|
+
- https://www.modsecurity.org/
|
|
13
|
+
- https://coreruleset.org/
|
|
14
|
+
- https://github.com/0xInfection/Awesome-WAF
|
|
15
|
+
tags: waf,detection,modsecurity,crs,owasp,fingerprint,waftester
|
|
16
|
+
classification:
|
|
17
|
+
cwe-id:
|
|
18
|
+
- CWE-200
|
|
19
|
+
metadata:
|
|
20
|
+
verified: true
|
|
21
|
+
max-request: 2
|
|
22
|
+
shodan-query: "http.headers.server:mod_security"
|
|
23
|
+
fofa-query: "server=\"mod_security\""
|
|
24
|
+
|
|
25
|
+
http:
|
|
26
|
+
- method: GET
|
|
27
|
+
path:
|
|
28
|
+
- "{{BaseURL}}/"
|
|
29
|
+
|
|
30
|
+
stop-at-first-match: true
|
|
31
|
+
matchers-condition: or
|
|
32
|
+
matchers:
|
|
33
|
+
- type: word
|
|
34
|
+
part: header
|
|
35
|
+
words:
|
|
36
|
+
- "mod_security"
|
|
37
|
+
- "modsecurity"
|
|
38
|
+
- "NOYB"
|
|
39
|
+
- "Mod_Security"
|
|
40
|
+
- "OWASP_CRS"
|
|
41
|
+
- "mod_security/"
|
|
42
|
+
condition: or
|
|
43
|
+
case-insensitive: true
|
|
44
|
+
|
|
45
|
+
- type: regex
|
|
46
|
+
part: header
|
|
47
|
+
regex:
|
|
48
|
+
- "(?i)server:.*mod_security"
|
|
49
|
+
- "(?i)server:.*ModSecurity"
|
|
50
|
+
- "(?i)x-modsecurity-id:\\s*\\d+"
|
|
51
|
+
- "(?i)x-mod-sec-rule:\\s*\\d+"
|
|
52
|
+
|
|
53
|
+
- type: word
|
|
54
|
+
part: body
|
|
55
|
+
words:
|
|
56
|
+
- "ModSecurity"
|
|
57
|
+
- "mod_security"
|
|
58
|
+
- "This error was generated by Mod_Security"
|
|
59
|
+
- "rules of the mod_security module"
|
|
60
|
+
- "OWASP CRS"
|
|
61
|
+
- "OWASP ModSecurity Core Rule Set"
|
|
62
|
+
- "mod_security-message"
|
|
63
|
+
- "ModSecurity Action"
|
|
64
|
+
- "ModSecurity: Access denied"
|
|
65
|
+
- "Mod_Security - Block"
|
|
66
|
+
- "Apache/ModSecurity"
|
|
67
|
+
- "SecRule"
|
|
68
|
+
condition: or
|
|
69
|
+
case-insensitive: true
|
|
70
|
+
|
|
71
|
+
- type: dsl
|
|
72
|
+
dsl:
|
|
73
|
+
- "status_code == 403 && (contains(tolower(body), 'modsecurity') || contains(tolower(body), 'mod_security'))"
|
|
74
|
+
|
|
75
|
+
extractors:
|
|
76
|
+
- type: kval
|
|
77
|
+
kval:
|
|
78
|
+
- server
|
|
79
|
+
|
|
80
|
+
- type: regex
|
|
81
|
+
part: header
|
|
82
|
+
group: 1
|
|
83
|
+
regex:
|
|
84
|
+
- "(?i)mod_security/([0-9.]+)"
|
|
85
|
+
- "(?i)ModSecurity/([0-9.]+)"
|
|
86
|
+
|
|
87
|
+
- type: regex
|
|
88
|
+
part: body
|
|
89
|
+
group: 1
|
|
90
|
+
regex:
|
|
91
|
+
- "(?i)ModSecurity[/ ]+v?([0-9.]+)"
|
|
92
|
+
|
|
93
|
+
# Trigger WAF block with SQLi payload to confirm CRS rules
|
|
94
|
+
- method: GET
|
|
95
|
+
path:
|
|
96
|
+
- "{{BaseURL}}/?id=1' OR '1'='1"
|
|
97
|
+
|
|
98
|
+
matchers-condition: or
|
|
99
|
+
matchers:
|
|
100
|
+
- type: word
|
|
101
|
+
part: body
|
|
102
|
+
words:
|
|
103
|
+
- "ModSecurity"
|
|
104
|
+
- "mod_security"
|
|
105
|
+
- "OWASP CRS"
|
|
106
|
+
- "Access denied"
|
|
107
|
+
- "This error was generated by"
|
|
108
|
+
- "SecRule"
|
|
109
|
+
- "Coraza"
|
|
110
|
+
condition: or
|
|
111
|
+
case-insensitive: true
|
|
112
|
+
|
|
113
|
+
- type: regex
|
|
114
|
+
part: body
|
|
115
|
+
regex:
|
|
116
|
+
- "(?i)id\\s*\"[0-9]+\""
|
|
117
|
+
- "(?i)rule\\s+[0-9]+"
|
|
118
|
+
|
|
119
|
+
- type: dsl
|
|
120
|
+
dsl:
|
|
121
|
+
- "status_code == 403"
|
|
122
|
+
|
|
123
|
+
extractors:
|
|
124
|
+
- type: regex
|
|
125
|
+
part: body
|
|
126
|
+
group: 1
|
|
127
|
+
regex:
|
|
128
|
+
- "(?i)id\\s*\"([0-9]+)\""
|
|
129
|
+
- "(?i)rule\\s+([0-9]+)"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
id: waf-full-assessment-workflow
|
|
2
|
+
info:
|
|
3
|
+
name: WAF Full Assessment Workflow
|
|
4
|
+
author: waftester
|
|
5
|
+
description: |
|
|
6
|
+
Complete WAF assessment workflow. First detects the WAF vendor (Cloudflare,
|
|
7
|
+
AWS, Akamai, Azure, ModSecurity), then runs all relevant bypass templates
|
|
8
|
+
matched by tags. Detection runs in parallel, bypass tests run conditionally
|
|
9
|
+
based on detected WAF vendor for vendor-specific evasion tuning.
|
|
10
|
+
|
|
11
|
+
workflows:
|
|
12
|
+
- template: nuclei/http/waf-detection/cloudflare-detect.yaml
|
|
13
|
+
subtemplates:
|
|
14
|
+
- tags: waf,bypass,sqli
|
|
15
|
+
- tags: waf,bypass,xss
|
|
16
|
+
- tags: waf,bypass,rce
|
|
17
|
+
- tags: waf,bypass,ssrf
|
|
18
|
+
- tags: waf,bypass,lfi
|
|
19
|
+
- tags: waf,bypass,ssti
|
|
20
|
+
- tags: waf,bypass,xxe
|
|
21
|
+
- tags: waf,bypass,crlf
|
|
22
|
+
- tags: waf,bypass,nosqli
|
|
23
|
+
|
|
24
|
+
- template: nuclei/http/waf-detection/aws-waf-detect.yaml
|
|
25
|
+
subtemplates:
|
|
26
|
+
- tags: waf,bypass,sqli
|
|
27
|
+
- tags: waf,bypass,xss
|
|
28
|
+
- tags: waf,bypass,rce
|
|
29
|
+
- tags: waf,bypass,ssrf
|
|
30
|
+
- tags: waf,bypass,lfi
|
|
31
|
+
- tags: waf,bypass,ssti
|
|
32
|
+
- tags: waf,bypass,xxe
|
|
33
|
+
- tags: waf,bypass,crlf
|
|
34
|
+
- tags: waf,bypass,nosqli
|
|
35
|
+
|
|
36
|
+
- template: nuclei/http/waf-detection/modsecurity-detect.yaml
|
|
37
|
+
subtemplates:
|
|
38
|
+
- tags: waf,bypass,evasion
|
|
39
|
+
- tags: waf,bypass,sqli
|
|
40
|
+
- tags: waf,bypass,xss
|
|
41
|
+
- tags: waf,bypass,rce
|
|
42
|
+
- tags: waf,bypass,ssrf
|
|
43
|
+
- tags: waf,bypass,lfi
|
|
44
|
+
- tags: waf,bypass,ssti
|
|
45
|
+
- tags: waf,bypass,xxe
|
|
46
|
+
- tags: waf,bypass,crlf
|
|
47
|
+
- tags: waf,bypass,nosqli
|
|
48
|
+
|
|
49
|
+
- template: nuclei/http/waf-detection/akamai-detect.yaml
|
|
50
|
+
subtemplates:
|
|
51
|
+
- tags: waf,bypass,sqli
|
|
52
|
+
- tags: waf,bypass,xss
|
|
53
|
+
- tags: waf,bypass,rce
|
|
54
|
+
- tags: waf,bypass,ssrf
|
|
55
|
+
- tags: waf,bypass,lfi
|
|
56
|
+
- tags: waf,bypass,ssti
|
|
57
|
+
- tags: waf,bypass,xxe
|
|
58
|
+
- tags: waf,bypass,crlf
|
|
59
|
+
- tags: waf,bypass,nosqli
|
|
60
|
+
|
|
61
|
+
- template: nuclei/http/waf-detection/azure-waf-detect.yaml
|
|
62
|
+
subtemplates:
|
|
63
|
+
- tags: waf,bypass,sqli
|
|
64
|
+
- tags: waf,bypass,xss
|
|
65
|
+
- tags: waf,bypass,rce
|
|
66
|
+
- tags: waf,bypass,ssrf
|
|
67
|
+
- tags: waf,bypass,lfi
|
|
68
|
+
- tags: waf,bypass,ssti
|
|
69
|
+
- tags: waf,bypass,xxe
|
|
70
|
+
- tags: waf,bypass,crlf
|
|
71
|
+
- tags: waf,bypass,nosqli
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"SchemaVersion": "2018-10-08",
|
|
3
|
+
"Id": "waftester-{{ default "scan" .ScanID }}-{{ .Timestamp }}",
|
|
4
|
+
"ProductArn": "arn:aws:securityhub:{{ default "us-east-1" .Region }}:{{ default "000000000000" .AWSAccountID }}:product/waftester/waftester",
|
|
5
|
+
"GeneratorId": "waftester",
|
|
6
|
+
"AwsAccountId": "{{ default "000000000000" .AWSAccountID }}",
|
|
7
|
+
"CreatedAt": "{{ .Timestamp }}",
|
|
8
|
+
"UpdatedAt": "{{ .Timestamp }}",
|
|
9
|
+
"Title": "WAF Security Assessment - {{ .Target }}",
|
|
10
|
+
"Description": "WAFtester scan of {{ .Target }}: {{ .TotalTests }} tests, {{ .BypassCount }} bypasses, {{ .Effectiveness }}% effectiveness (Grade: {{ .Grade }})",
|
|
11
|
+
"Severity": {
|
|
12
|
+
"Label": "{{ upper .HighestSeverity }}",
|
|
13
|
+
"Original": "{{ .HighestSeverity }}"
|
|
14
|
+
},
|
|
15
|
+
"Types": [
|
|
16
|
+
"Software and Configuration Checks/AWS Security Best Practices"
|
|
17
|
+
],
|
|
18
|
+
"Resources": [
|
|
19
|
+
{
|
|
20
|
+
"Type": "Other",
|
|
21
|
+
"Id": "{{ .Target }}",
|
|
22
|
+
"Details": {
|
|
23
|
+
"Other": {
|
|
24
|
+
"TotalTests": "{{ toString .TotalTests }}",
|
|
25
|
+
"Blocked": "{{ toString .Blocked }}",
|
|
26
|
+
"Bypassed": "{{ toString .BypassCount }}",
|
|
27
|
+
"Effectiveness": "{{ .Effectiveness }}",
|
|
28
|
+
"Grade": "{{ .Grade }}"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"Compliance": {
|
|
34
|
+
"Status": "{{ ternary "PASSED" "FAILED" (eq .BypassCount 0) }}"
|
|
35
|
+
},
|
|
36
|
+
"Findings": [
|
|
37
|
+
{{- range $idx, $bypass := .Bypasses }}
|
|
38
|
+
{{- if $idx }},{{ end }}
|
|
39
|
+
{
|
|
40
|
+
"Id": "{{ $bypass.Test.ID }}",
|
|
41
|
+
"Title": "{{ $bypass.Test.Name }}",
|
|
42
|
+
"Description": "WAF bypass via {{ $bypass.Test.Category }} at {{ $bypass.Target.URL }}",
|
|
43
|
+
"Severity": {
|
|
44
|
+
"Label": "{{ upper $bypass.Test.Severity }}"
|
|
45
|
+
},
|
|
46
|
+
"Types": ["Software and Configuration Checks"],
|
|
47
|
+
"Resources": [
|
|
48
|
+
{
|
|
49
|
+
"Type": "Other",
|
|
50
|
+
"Id": "{{ $bypass.Target.URL }}"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"Remediation": {
|
|
54
|
+
"Recommendation": {
|
|
55
|
+
"Text": "Review WAF rules for {{ $bypass.Test.Category }} coverage. See {{ owaspLink $bypass.Test.Category }}"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
{{- end }}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"Test ID","Category","Severity","Name","URL","Method","Status Code","Outcome","Latency (ms)","Payload","OWASP","CWE"
|
|
2
|
+
{{- range $result := .Results }}
|
|
3
|
+
{{ escapeCSV $result.Test.ID }},{{ escapeCSV $result.Test.Category }},{{ escapeCSV (upper $result.Test.Severity) }},{{ escapeCSV $result.Test.Name }},{{ escapeCSV $result.Target.URL }},{{ escapeCSV $result.Target.Method }},{{ escapeCSV (toString $result.Result.StatusCode) }},{{ escapeCSV $result.Result.Outcome }},{{ escapeCSV (toString $result.Result.LatencyMs) }},{{ escapeCSV $result.Payload }},{{ escapeCSV (owaspLink $result.Test.Category) }},{{ escapeCSV (cweLink $result.Test.Category) }}
|
|
4
|
+
{{- end }}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<testsuites name="WAFtester Security Assessment" tests="{{ .TotalTests }}" failures="{{ .BypassCount }}" errors="{{ .Errors }}" time="{{ .Duration }}">
|
|
3
|
+
<testsuite name="WAF Bypass Tests" tests="{{ .TotalTests }}" failures="{{ .BypassCount }}" errors="{{ .Errors }}" timestamp="{{ .Timestamp }}">
|
|
4
|
+
<properties>
|
|
5
|
+
<property name="target" value="{{ escapeXML .Target }}"/>
|
|
6
|
+
<property name="effectiveness" value="{{ .Effectiveness }}"/>
|
|
7
|
+
<property name="grade" value="{{ .Grade }}"/>
|
|
8
|
+
<property name="scan_id" value="{{ default "N/A" .ScanID }}"/>
|
|
9
|
+
<property name="highest_severity" value="{{ .HighestSeverity }}"/>
|
|
10
|
+
</properties>
|
|
11
|
+
{{- range $result := .Results }}
|
|
12
|
+
<testcase name="{{ escapeXML $result.Test.Name }}" classname="{{ $result.Test.Category }}.{{ $result.Test.ID }}" time="{{ $result.Result.LatencyMs }}">
|
|
13
|
+
{{- if eq $result.Result.Outcome "bypass" }}
|
|
14
|
+
<failure message="WAF bypass detected" type="{{ upper $result.Test.Severity }}">
|
|
15
|
+
Category: {{ $result.Test.Category }}
|
|
16
|
+
Severity: {{ upper $result.Test.Severity }}
|
|
17
|
+
URL: {{ $result.Target.URL }}
|
|
18
|
+
Method: {{ $result.Target.Method }}
|
|
19
|
+
Status Code: {{ $result.Result.StatusCode }}
|
|
20
|
+
Payload: {{ escapeXML $result.Payload }}
|
|
21
|
+
OWASP: {{ owaspLink $result.Test.Category }}
|
|
22
|
+
CWE: {{ cweLink $result.Test.Category }}
|
|
23
|
+
</failure>
|
|
24
|
+
{{- end }}
|
|
25
|
+
{{- if eq $result.Result.Outcome "error" }}
|
|
26
|
+
<error message="Test execution error" type="Error">
|
|
27
|
+
URL: {{ $result.Target.URL }}
|
|
28
|
+
Status Code: {{ $result.Result.StatusCode }}
|
|
29
|
+
</error>
|
|
30
|
+
{{- end }}
|
|
31
|
+
</testcase>
|
|
32
|
+
{{- end }}
|
|
33
|
+
</testsuite>
|
|
34
|
+
</testsuites>
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# WAF Security Assessment Report
|
|
2
|
+
{{- $target := .Target }}
|
|
3
|
+
{{- $ts := .Timestamp }}
|
|
4
|
+
|
|
5
|
+
## Target: {{ $target }}
|
|
6
|
+
**Generated:** {{ $ts }}
|
|
7
|
+
**Duration:** {{ .Duration }}
|
|
8
|
+
**Scan ID:** {{ default "N/A" .ScanID }}
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Executive Summary
|
|
13
|
+
|
|
14
|
+
| Metric | Value |
|
|
15
|
+
|--------|-------|
|
|
16
|
+
| Total Tests | {{ .TotalTests }} |
|
|
17
|
+
| Blocked | {{ .Blocked }} |
|
|
18
|
+
| Bypassed | {{ .BypassCount }} |
|
|
19
|
+
| Errors | {{ .Errors }} |
|
|
20
|
+
| Timeouts | {{ .Timeouts }} |
|
|
21
|
+
| **Effectiveness** | **{{ .Effectiveness }}%** |
|
|
22
|
+
| **Grade** | **{{ .Grade }}** |
|
|
23
|
+
| Highest Severity | {{ severityIcon .HighestSeverity }} {{ .HighestSeverity }} |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Severity Distribution
|
|
28
|
+
|
|
29
|
+
| Severity | Count | Icon |
|
|
30
|
+
|----------|-------|------|
|
|
31
|
+
{{- range $sev, $count := .SeverityCounts }}
|
|
32
|
+
| {{ upper $sev }} | {{ $count }} | {{ severityIcon $sev }} |
|
|
33
|
+
{{- end }}
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Category Breakdown
|
|
38
|
+
|
|
39
|
+
| Category | Tests | Status |
|
|
40
|
+
|----------|-------|--------|
|
|
41
|
+
{{- range $cat, $count := .CategoryCounts }}
|
|
42
|
+
| {{ title $cat }} | {{ $count }} | {{ ternary "PASS" "REVIEW" (gt $count 0) }} |
|
|
43
|
+
{{- end }}
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Bypasses Found
|
|
48
|
+
|
|
49
|
+
{{- if .Bypasses }}
|
|
50
|
+
|
|
51
|
+
> **WARNING:** {{ len .Bypasses }} bypass(es) detected. Immediate remediation recommended.
|
|
52
|
+
|
|
53
|
+
{{- range $idx, $bypass := .Bypasses }}
|
|
54
|
+
|
|
55
|
+
### {{ add $idx 1 }}. {{ $bypass.Test.Name }}
|
|
56
|
+
|
|
57
|
+
| Field | Detail |
|
|
58
|
+
|-------|--------|
|
|
59
|
+
| **ID** | {{ $bypass.Test.ID }} |
|
|
60
|
+
| **Category** | {{ $bypass.Test.Category }} |
|
|
61
|
+
| **Severity** | {{ severityIcon $bypass.Test.Severity }} {{ upper $bypass.Test.Severity }} |
|
|
62
|
+
| **URL** | {{ $bypass.Target.URL }} |
|
|
63
|
+
| **Method** | {{ $bypass.Target.Method }} |
|
|
64
|
+
| **Status Code** | {{ $bypass.Result.StatusCode }} |
|
|
65
|
+
| **Outcome** | {{ $bypass.Result.Outcome }} |
|
|
66
|
+
| **Latency** | {{ $bypass.Result.LatencyMs }}ms |
|
|
67
|
+
| **OWASP** | {{ owaspLink $bypass.Test.Category }} |
|
|
68
|
+
|
|
69
|
+
**Payload:**
|
|
70
|
+
```
|
|
71
|
+
{{ $bypass.Payload }}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
{{- end }}
|
|
76
|
+
{{- else }}
|
|
77
|
+
|
|
78
|
+
No bypasses detected. WAF is blocking all tested attack vectors.
|
|
79
|
+
|
|
80
|
+
{{- end }}
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Detailed Results
|
|
85
|
+
|
|
86
|
+
{{- range $idx, $result := .Results }}
|
|
87
|
+
| {{ add $idx 1 }} | {{ $result.Test.ID }} | {{ $result.Test.Category }} | {{ severityIcon $result.Test.Severity }} | {{ $result.Result.StatusCode }} | {{ $result.Result.Outcome }} | {{ $result.Result.LatencyMs }}ms |
|
|
88
|
+
{{- end }}
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
*Report generated by [WAFtester](https://github.com/waftester/waftester)*
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
{{- $target := .Target -}}
|
|
2
|
+
{{- $effectiveness := .Effectiveness -}}
|
|
3
|
+
{{- $grade := .Grade -}}
|
|
4
|
+
{{- $bypasses := .BypassCount -}}
|
|
5
|
+
{
|
|
6
|
+
"blocks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "header",
|
|
9
|
+
"text": {
|
|
10
|
+
"type": "plain_text",
|
|
11
|
+
"text": "WAF Security Assessment Report"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"type": "section",
|
|
16
|
+
"fields": [
|
|
17
|
+
{
|
|
18
|
+
"type": "mrkdwn",
|
|
19
|
+
"text": "*Target:*\n{{ $target }}"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"type": "mrkdwn",
|
|
23
|
+
"text": "*Grade:*\n{{ $grade }}"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"type": "mrkdwn",
|
|
27
|
+
"text": "*Effectiveness:*\n{{ $effectiveness }}%"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"type": "mrkdwn",
|
|
31
|
+
"text": "*Duration:*\n{{ .Duration }}"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"type": "section",
|
|
37
|
+
"fields": [
|
|
38
|
+
{
|
|
39
|
+
"type": "mrkdwn",
|
|
40
|
+
"text": "*Total Tests:* {{ .TotalTests }}"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type": "mrkdwn",
|
|
44
|
+
"text": "*Blocked:* {{ .Blocked }}"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"type": "mrkdwn",
|
|
48
|
+
"text": "*Bypassed:* {{ $bypasses }}"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"type": "mrkdwn",
|
|
52
|
+
"text": "*Errors:* {{ .Errors }}"
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"type": "divider"
|
|
58
|
+
}
|
|
59
|
+
{{- if .Bypasses -}}
|
|
60
|
+
,{
|
|
61
|
+
"type": "section",
|
|
62
|
+
"text": {
|
|
63
|
+
"type": "mrkdwn",
|
|
64
|
+
"text": ":warning: *{{ len .Bypasses }} Bypass(es) Detected*"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
{{- range $idx, $bypass := .Bypasses -}}
|
|
68
|
+
,{
|
|
69
|
+
"type": "section",
|
|
70
|
+
"text": {
|
|
71
|
+
"type": "mrkdwn",
|
|
72
|
+
"text": "{{ severityIcon $bypass.Test.Severity }} *{{ $bypass.Test.Name }}*\nCategory: {{ $bypass.Test.Category }} | Severity: {{ upper $bypass.Test.Severity }}\nStatus: {{ $bypass.Result.StatusCode }} | Latency: {{ $bypass.Result.LatencyMs }}ms"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
{{- end -}}
|
|
76
|
+
{{- else -}}
|
|
77
|
+
,{
|
|
78
|
+
"type": "section",
|
|
79
|
+
"text": {
|
|
80
|
+
"type": "mrkdwn",
|
|
81
|
+
"text": ":white_check_mark: All attack vectors blocked. No bypasses detected."
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
{{- end }}
|
|
85
|
+
,{
|
|
86
|
+
"type": "context",
|
|
87
|
+
"elements": [
|
|
88
|
+
{
|
|
89
|
+
"type": "mrkdwn",
|
|
90
|
+
"text": "Generated by WAFtester | {{ .Timestamp }}"
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
WAF Security Assessment — Text Summary
|
|
2
|
+
========================================
|
|
3
|
+
Target: {{ .Target }}
|
|
4
|
+
Timestamp: {{ .Timestamp }}
|
|
5
|
+
Duration: {{ .Duration }}
|
|
6
|
+
Scan ID: {{ default "N/A" .ScanID }}
|
|
7
|
+
========================================
|
|
8
|
+
|
|
9
|
+
RESULTS OVERVIEW
|
|
10
|
+
----------------
|
|
11
|
+
Total Tests: {{ .TotalTests }}
|
|
12
|
+
Blocked: {{ .Blocked }}
|
|
13
|
+
Bypassed: {{ .BypassCount }}
|
|
14
|
+
Errors: {{ .Errors }}
|
|
15
|
+
Timeouts: {{ .Timeouts }}
|
|
16
|
+
|
|
17
|
+
EFFECTIVENESS: {{ .Effectiveness }}%
|
|
18
|
+
GRADE: {{ .Grade }}
|
|
19
|
+
HIGHEST SEV: {{ upper .HighestSeverity }}
|
|
20
|
+
|
|
21
|
+
SEVERITY DISTRIBUTION
|
|
22
|
+
---------------------
|
|
23
|
+
{{- range $sev, $count := .SeverityCounts }}
|
|
24
|
+
{{ upper $sev }}: {{ $count }}
|
|
25
|
+
{{- end }}
|
|
26
|
+
|
|
27
|
+
CATEGORY BREAKDOWN
|
|
28
|
+
------------------
|
|
29
|
+
{{- range $cat, $count := .CategoryCounts }}
|
|
30
|
+
{{ title $cat }}: {{ $count }}
|
|
31
|
+
{{- end }}
|
|
32
|
+
|
|
33
|
+
{{- if .Bypasses }}
|
|
34
|
+
|
|
35
|
+
BYPASSES FOUND ({{ len .Bypasses }})
|
|
36
|
+
====================
|
|
37
|
+
{{- range $idx, $bypass := .Bypasses }}
|
|
38
|
+
|
|
39
|
+
[{{ add $idx 1 }}] {{ $bypass.Test.Name }}
|
|
40
|
+
ID: {{ $bypass.Test.ID }}
|
|
41
|
+
Category: {{ $bypass.Test.Category }}
|
|
42
|
+
Severity: {{ upper $bypass.Test.Severity }}
|
|
43
|
+
URL: {{ $bypass.Target.URL }}
|
|
44
|
+
Method: {{ $bypass.Target.Method }}
|
|
45
|
+
Status: {{ $bypass.Result.StatusCode }}
|
|
46
|
+
Outcome: {{ $bypass.Result.Outcome }}
|
|
47
|
+
Latency: {{ $bypass.Result.LatencyMs }}ms
|
|
48
|
+
Payload: {{ trunc 120 $bypass.Payload }}
|
|
49
|
+
{{- end }}
|
|
50
|
+
{{- else }}
|
|
51
|
+
|
|
52
|
+
NO BYPASSES — All attack vectors blocked by WAF.
|
|
53
|
+
{{- end }}
|
|
54
|
+
|
|
55
|
+
========================================
|
|
56
|
+
Generated by WAFtester
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# WAFtester API-Only Override Configuration
|
|
2
|
+
# Tailors scanning behavior for API endpoints (no browser-based attacks)
|
|
3
|
+
# Focuses on JSON/XML payloads and API-specific vulnerabilities
|
|
4
|
+
|
|
5
|
+
overrides:
|
|
6
|
+
- id: api-content-type
|
|
7
|
+
description: "Force JSON Content-Type for all API requests"
|
|
8
|
+
match:
|
|
9
|
+
path: ".*"
|
|
10
|
+
action:
|
|
11
|
+
set_headers:
|
|
12
|
+
Content-Type: "application/json"
|
|
13
|
+
Accept: "application/json"
|
|
14
|
+
enabled: true
|
|
15
|
+
priority: 100
|
|
16
|
+
|
|
17
|
+
- id: disable-browser-xss
|
|
18
|
+
description: "Disable browser-specific XSS payloads (no DOM, no HTML context)"
|
|
19
|
+
match:
|
|
20
|
+
category: "xss"
|
|
21
|
+
tags:
|
|
22
|
+
- "dom"
|
|
23
|
+
- "browser"
|
|
24
|
+
- "html-context"
|
|
25
|
+
- "document-write"
|
|
26
|
+
action:
|
|
27
|
+
skip: true
|
|
28
|
+
enabled: true
|
|
29
|
+
priority: 90
|
|
30
|
+
|
|
31
|
+
- id: disable-clickjacking
|
|
32
|
+
description: "Skip clickjacking tests — not applicable to APIs"
|
|
33
|
+
match:
|
|
34
|
+
category: "clickjacking"
|
|
35
|
+
action:
|
|
36
|
+
skip: true
|
|
37
|
+
enabled: true
|
|
38
|
+
priority: 90
|
|
39
|
+
|
|
40
|
+
- id: disable-csrf
|
|
41
|
+
description: "Skip CSRF tests — APIs use token-based auth"
|
|
42
|
+
match:
|
|
43
|
+
category: "csrf"
|
|
44
|
+
action:
|
|
45
|
+
skip: true
|
|
46
|
+
enabled: true
|
|
47
|
+
priority: 90
|
|
48
|
+
|
|
49
|
+
- id: disable-cookie-attacks
|
|
50
|
+
description: "Skip cookie-based session attacks for token-auth APIs"
|
|
51
|
+
match:
|
|
52
|
+
category: "session-fixation"
|
|
53
|
+
tags:
|
|
54
|
+
- "cookie"
|
|
55
|
+
- "session-cookie"
|
|
56
|
+
action:
|
|
57
|
+
skip: true
|
|
58
|
+
enabled: true
|
|
59
|
+
priority: 80
|
|
60
|
+
|
|
61
|
+
- id: enable-json-injection
|
|
62
|
+
description: "Enable all JSON-specific injection tests"
|
|
63
|
+
match:
|
|
64
|
+
tags:
|
|
65
|
+
- "json-injection"
|
|
66
|
+
- "json-body"
|
|
67
|
+
- "api-injection"
|
|
68
|
+
action:
|
|
69
|
+
skip: false
|
|
70
|
+
priority_boost: 10
|
|
71
|
+
enabled: true
|
|
72
|
+
priority: 70
|
|
73
|
+
|
|
74
|
+
- id: enable-graphql
|
|
75
|
+
description: "Enable GraphQL-specific attack vectors"
|
|
76
|
+
match:
|
|
77
|
+
category: "graphql"
|
|
78
|
+
action:
|
|
79
|
+
skip: false
|
|
80
|
+
priority_boost: 10
|
|
81
|
+
enabled: true
|
|
82
|
+
priority: 70
|
|
83
|
+
|
|
84
|
+
- id: enable-mass-assignment
|
|
85
|
+
description: "Enable mass assignment and BOLA/BFLA tests"
|
|
86
|
+
match:
|
|
87
|
+
category:
|
|
88
|
+
- "mass-assignment"
|
|
89
|
+
- "idor"
|
|
90
|
+
- "bola"
|
|
91
|
+
- "bfla"
|
|
92
|
+
action:
|
|
93
|
+
skip: false
|
|
94
|
+
priority_boost: 15
|
|
95
|
+
enabled: true
|
|
96
|
+
priority: 70
|
|
97
|
+
|
|
98
|
+
- id: api-rate-limit
|
|
99
|
+
description: "Enforce conservative rate limiting for API scanning"
|
|
100
|
+
match:
|
|
101
|
+
path: ".*"
|
|
102
|
+
action:
|
|
103
|
+
rate_limit: 20
|
|
104
|
+
delay_ms: 100
|
|
105
|
+
enabled: true
|
|
106
|
+
priority: 50
|
|
107
|
+
|
|
108
|
+
- id: json-body-sqli
|
|
109
|
+
description: "Use JSON body format for SQLi payloads"
|
|
110
|
+
match:
|
|
111
|
+
category: "sqli"
|
|
112
|
+
action:
|
|
113
|
+
body_format: "json"
|
|
114
|
+
inject_in:
|
|
115
|
+
- "json-value"
|
|
116
|
+
- "json-key"
|
|
117
|
+
enabled: true
|
|
118
|
+
priority: 60
|
|
119
|
+
|
|
120
|
+
- id: remove-html-payloads
|
|
121
|
+
description: "Skip payloads that rely on HTML rendering"
|
|
122
|
+
match:
|
|
123
|
+
tags:
|
|
124
|
+
- "html-render"
|
|
125
|
+
- "browser-render"
|
|
126
|
+
- "document-context"
|
|
127
|
+
action:
|
|
128
|
+
skip: true
|
|
129
|
+
enabled: true
|
|
130
|
+
priority: 85
|