惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
量子位
大猫的无限游戏
大猫的无限游戏
Hugging Face - Blog
Hugging Face - Blog
S
SegmentFault 最新的问题
Blog — PlanetScale
Blog — PlanetScale
月光博客
月光博客
Google DeepMind News
Google DeepMind News
小众软件
小众软件
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
MongoDB | Blog
MongoDB | Blog
B
Blog RSS Feed
博客园 - Franky
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
B
Blog
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
Recent Announcements
Recent Announcements
Y
Y Combinator Blog
Microsoft Security Blog
Microsoft Security Blog
雷峰网
雷峰网
Jina AI
Jina AI
酷 壳 – CoolShell
酷 壳 – CoolShell

TrustedSec

So… You Found AWS Access Keys (Part 1) LLMHaxor Update SpooNMAP Grows Up: Findings, Local LLM Detection, and a Whole Lot Less Waiting We've Seen This Movie: The OT/IT Technology Divide AI Offense is Not Noclip Mode A Vault With No Treasure - CMMC Level 2 Compliance for Subcontractors With No CUI The Art of Hunting Azure Cloud Secrets TLS Encryption and Compliance AI Directives and AI Strategy Development CCPA Update: Cybersecurity Requirements (Part 2) CCPA Update: Who’s In Scope (Part 1) device, code, phishing, attacks, hotness, m365 CMMC is (Not) Cancelled Pandora’s Container Part 1: Unpacking Azure Container Security Vulnify: Giving Your Agents a CVE Brain Welcoming ObfusGit Inheriting the Receipts: Securing the AI Your Company Already Adopted Large Workflows with Local LLMs Modern Web Application Content Discovery JQ for Hackers JS-Tap v3: Endpoint Post-Exploitation With JavaScript Implants Hardening Intune: The Implementation Guide How to Train Your (Dragons) Analysts - A TrustedSec Guide to Picking… The Privileged Roles Nobody Talks About CMMC Conditional Status - Contracting Without Compliance PCI DSS, Telephone Payments, and the Problems With VoIP Shai-Hulud Is Back, and This Time It Ate the Whole Ecosystem Coverage-Driven Sustained Testing (CDST): A Graph-Oriented Model for… Finding Your Way on the Passkey Path Slamming the Door on Quick Assist Tech Support Scams and Abuse
waf-fu, or Some Log Replay Nonsense
Lilly Mayo · 2026-09-01 · via TrustedSec

1    waf-fu Your Way to Better Credential Access

So, a gig or two ago I was reviewing CloudWatch logs to search for any credentials that I may be able to use, in order to gain additional access to the environment. Various Web Application Firewalls (WAFs) were configured so that all headers were captured in the log, which was pretty convenient!

The part that wasn’t so fun was trying to replay multiple requests across multiple WAF logs, each with their own required content, just to see if at least one may provide a way to hopefully gain additional access into the applications the WAFs were configured to protect. It’s possible to do it all manually, but I found it to be a frustrating process when reviewing dozens or hundreds of log groups or individual log entries that needed to be checked to find out which may get me where I wanted to go.

Soo, I figured that there must be a better solution to handle building AWS WAF log replay traffic more at scale and that’s what was built. Feel free to jump to Replay With waf-fu if you want to see the tool that’s being released. But for everyone else, we’ll first talk about what WAF does and doesn’t capture by default.

Figure 1 - Surprises Abound

2    Straight From the Horse’s Docs

Okay, so what does an AWS WAF capture with the default configuration? Surprisingly a lot, and none of it is automatically redacted. So…good news for us. You may see some cutoff if dealing with logs of exceptional size, but for most cases it’s probably the whole hog. Here’s a small table with the details to look professional about it.

Field

Source

Details

HTTP Method

httpRequest.httpMethod

Request operation, such as GET, POST, PUT, DELETE, etc.

URI Path

httpRequest.uri

Path identifying the requested resource

Query String

httpRequest.args

Query parameters and their values

All Headers

httpRequest.headers[]

Header names and values supplied with the request

HTTP Version

httpRequest.httpVersion

HTTP protocol version used for the request

Client IP

httpRequest.clientIp

IP address of the client sending the request

Country

httpRequest.country

Country associated with the request's origin or a literal ‘-‘ when AWS WAF cannot determine it

Timestamp

timestamp

Request timestamp recorded in milliseconds since the Unix epoch

It’s a lot of neato stuff. And as seen with the CAPTCHA log example on the AWS WAF logging examples documentation, their examples show that logged content can certainly include session cookie data.

To be fair, some of WAFv2 documentation does recommend redacting common headers, but I only found this mentioned in the WAFv2 Best Practices documentation, which is not part of their main documentation site at https://docs.aws.amazon.com/.

“Common headers to redact include Authorization, Proxy-Authorization, Cookie, Set-Cookie, X-API-Key, and X-Amz-Security-Token.”

While full POST request body details aren’t captured, we can still find use for everything else. After all, just because a POST request uses body content doesn’t mean the service will fully validate it.

Figure 2 - I Care A Lot

3    Hunting to be Repetitive

So, the logs may be used to re-create a replay attack, which is pretty darn nice. But where do we find them and how difficult is it to do that. Honestly, it’s not too bad. For our use case we looked at three that can be used to pull logs from that can potentially be replayed.

But, as can be seen below, obtaining WAF logs doesn’t require too many permissions overall, and because it’s made of mostly read permissions, it’s more likely to be part of an overly permissive principal.

3.1  CloudWatch Logs Groups

By default, all WAF logs set to store logs in CloudWatch are configured with the prefix aws-waf-logs-, followed by whatever name is desired. Most deployments seem to just use the WAF name for this. Either way, the required prefix makes it super simple to search for any CloudWatch Log Groups that are configured for WAF logging. And just two actions are needed to list the log groups and then read log group data.

{
  "Effect": "Allow",
  "Action": [
    "logs:DescribeLogGroups",
    "logs:FilterLogEvents"
  ],
  "Resource": "*"
}

3.2  S3 Buckets

Similarly, all WAF logs configured to store logs in an S3 bucket use the same prefix aws-waf-logs-, again followed by whatever name is desired. Here we only need three actions to find and download WAF logs delivered to an S3 bucket.

{
  "Effect": "Allow",
  "Action": [
    "s3:ListAllMyBuckets",
    "s3:ListBucket",
    "s3:GetObject"
  ],
  "Resource": "*"
}

3.3  WAF Sample Pulling

The last method we’re looking at for pulling WAF logs is to get them from the WAF directly, which can have a few benefits, but also some disadvantages. The big one is that the WAF’s logging configuration RedactedFields element “has no impact on request sampling”. This means that any fields configured for redaction using the RedactedFields element will not be redacted when retrieved directly from the WAF through request sampling.

The downside is that sampling only pulls up to 500 log entries of sampled log data, which is randomly pulled from a 5,000 log sample set. This time we just need four actions to complete WAF log sampling requests.

{
  "Effect": "Allow",
  "Action": [
    "wafv2:ListWebACLs",
    "wafv2:GetWebACL",
    "wafv2:GetLoggingConfiguration",
    "wafv2:GetSampledRequests"
  ],
  "Resource": "*"
}
Figure 3 - Minimal Indeed

4    Replay With waf-fu

But that’s enough fancy talk! Now for the new toy: waf-fu. We’ll leave additional details of the tool to the markdown files in the repo. But it’s a simple tool that pulls AWS WAF log data to store in a local sqlite database for cache, analysis, review, and replay of a logged session. All done with a nifty TUI so nobody is required to leave their favorite shell.

Figure 4 - Thanks, WAF Defaults

waf-fu --profile $PROFILE --region $REGION --log-group aws-waf-logs-$WEBACL

Once started, you're dropped into the interactive TUI, where you can browse, filter, and search until you find a log to replay as curl commands, through Chrome or Firefox with full header injection, or as a batch HAR (HTTP Archive) export for Burp Suite import.

Figure 5 - WAF TUI
Figure 6 - Enjoy It!

5    Plugging the Gaps

New toys are fun and all, but what can be done to help prevent this? AWS has two redaction mechanisms to choose from. But, as mentioned before, one doesn’t really provide great coverage if request sampling is achievable.

5.1  RedactedFields Configuration

As the docs say, RedactedFields on PutLoggingConfiguration accepts four FieldToMatch types: UriPath, QueryString, SingleHeader, Method. No Cookies option, you use SingleHeader with Name: cookie.

Three things it doesn’t cover:

  • SingleHeader vs. Headers. From the AWS API reference: SingleHeader redaction doesn’t apply to rules using the Headers aggregate match type. A rule inspecting all Headers logs those values unredacted even with SingleHeader redaction configured for the same header name.
  • Sampling. From AWS: “This setting has no impact on request sampling.” So GetSampledRequests returns full, unredacted headers regardless.
  • Amazon Security Lake. consumes an independent WAF log stream and only respects DataProtectionConfig, not RedactedFields. We didn’t include that as a source to look for WAF logs, but I still felt it was worth including in this list of limitations.

5.2  DataProtectionConfig Configuration

Released in February 2025, this option provides better web ACL-level data protection. Like is talked about, this setting provides actual redacting of content for CloudWatch, S3 buckets, request sampling, and others. Yeah, the three destinations for logs we talked about here aren't all that’s supported. It’s better, but it still has these quirks to keep in mind:

  • aws-waf-token is explicitly exempt, so you can’t protect it.
  • SINGLE_HEADER protection doesn’t cover rules inspecting all Headers. Same caveat as RedactedFields.
Figure 7 - Readable Logs Meow, Please

6    Live, Log, (Replay), Laugh

So that's the end of our story. WAF logs are undoubtedly useful for troubleshooting, building and firing detections, and analysis when tracking down what a bad actor may have done. But they can also reveal a lot about the applications they protect, including exposing sensitive authentication details for their users.

There's nothing inherently wrong with keeping such logs to get work done, but it's worth locking down who can access the data, making sure nothing gets written to the logs that shouldn't be there, and that redaction is working how it is intended. After all, anything readable in logs, wherever they live, could be the final piece of the puzzle we need to get the access we're after.

Figure 8 - Bye, For Now…