http
233 TopicsA Method for the Madness: Meet HTTP QUERY
Note to the reader: I saw a headline on the new QUERY method and in a quick read didn't really understand the need, so I did a deep dive with Claude to understand the method itself, then followed with the larger infrastructure, security, and operational impacts for the implementation transitional period. This article is a summary of that session and co-authored by Claude. Every REST API grows a POST /search endpoint sooner or later — not because POST is the right tool for reading data, but because GET can't carry a body and your filter JSON stopped fitting in the URL years ago. The IETF closed that gap. On 15 June 2026 the RFC Editor published RFC 10008, "The HTTP QUERY Method" — a 24-page Proposed Standard on the IETF Standards Track. It's the first genuinely new HTTP method since PATCH landed as RFC 5789 in 2010, a 16-year gap. QUERY gives you the one thing GET and POST each refuse to provide: a safe, idempotent, cacheable request that carries a body. The TL;DR What it is: QUERY is a new, IANA-registered HTTP method that is safe and idempotent like GET, but carries a request body like POST. The body defines the query. Why it exists: GET is semantically correct for reads but forces the query into the URL (length limits, encoding pain, logging/bookmarking leakage). POST /search carries a body but lies to the infrastructure — nothing in the protocol signals the request is read-only, so caches, retry logic, and proxies can't treat it as one. QUERY is the missing middle. What's new on the wire: Nothing special. Any existing HTTP/1.1 or HTTP/2 connection carries it today. The friction is at every layer that has opinions about methods. The security headline: "Safe" is a promise about intent, not a guarantee about payloads. QUERY bodies need POST-level inspection, cache keys must include the full body (or you get cache poisoning), CSRF checks still apply to any endpoint with side effects, and method allowlists written before June 2026 don't know QUERY exists. Where support stands (mid-2026): Node.js has parsed QUERY since early 2024; OpenAPI 3.2 documents it; browsers can send it via fetch()/XHR but don't yet cache it; declarative HTML forms fall back to GET and drop the body; Spring hasn't shipped support. Treat it as production-ready for server-to-server, early-stage for browser-facing traffic. What to do: Don't rip out POST /search. QUERY sits alongside GET and POST — migrate gradually, and confirm every infrastructure layer handles it deliberately before real traffic arrives. The two-tool problem For as long as most of us have built APIs, reading data from a server meant choosing between two imperfect tools. GET has exactly the semantics you want for reads: safe (no state change expected), idempotent, and cacheable. The catch is that GET has no generally defined semantics for a request body — core HTTP semantics (RFC 9110 §9.3.1) even warn that a body on a GET can lead implementations to reject the request or treat it as a request-smuggling attempt. So the query has to go in the URL, and that runs into hard walls: URL length limits vary per proxy, load balancer, and server, and you discover the smallest one in the chain at runtime. RFC 9110 only recommends supporting URIs of at least ~8,000 octets, and that's a floor, not a promise. Some data is awkward to encode in a URI at all. Request URIs get logged, bookmarked, and dropped into Referer headers and analytics. And a nested filter object with arrays and boolean logic becomes an unreadable, fragile query string. POST fixes the body problem and creates a semantic one. A POST can create a record, update state, trigger a job, submit a form, or just run a search — and the HTTP layer can't tell which. Your application knows POST /search is read-only, but that's a private agreement between the server and the humans who wrote it. The caches, proxies, retry logic, CORS, gateways, and WAFs in the middle only see "POST," so they treat it as unsafe: not cacheable, not auto-retryable. Even a 200 OK doesn't tell them whether state changed. What QUERY actually does QUERY is the obvious hybrid: body support from POST, safe-and-idempotent semantics from GET. QUERY /users HTTP/1.1 Host: example.org Content-Type: application/json { "role": "admin", "status": "active", "sort": "name", "page": 1 } Because the method is declared safe and idempotent — and IANA-registered as such — the infrastructure can finally reason about it. A dropped QUERY can be automatically retried or restarted without worrying about partial state changes. Responses are cacheable. And the request finally tells the truth about what it's doing. A few spec details worth knowing: No new status codes, no new content types. QUERY reuses the existing vocabulary. A missing media type earns a 400; an unsupported one earns a 415; a syntactically valid query that can't be processed (say, correct SQL against a nonexistent table) earns a 422. Accept-Query for discovery. A response header a resource uses to advertise QUERY support and the media types it accepts, so clients can discover support instead of trial-and-erroring into a 405 Method Not Allowed. Cache key includes the body. This is the whole trick that makes a body-carrying request cacheable — and, as we'll see, the whole security footgun. A URI escape hatch. The server can respond to a QUERY with a Location / Content-Location header, assigning a stable URI to the query and its result, so clients can GET that URI afterward. This restores bookmarking and sharing, which you lose when the condition moves from the URL into the body. The name, for the curious: early drafts used SEARCH, borrowed from the WebDAV family (alongside PROPFIND and REPORT). The working group settled on QUERY because it maps cleanly to the URI's query component and describes a generic safe-read operation rather than implying one specific use case. The security implications most coverage skips Here's the part that matters more than the protocol itself. QUERY is well specified; the surrounding security assumptions are what need a second look. For nearly three decades, developers and security teams have built applications, APIs, WAFs, proxies, and tooling around a fixed set of verbs — GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS. A new one that behaves like a GET/POST hybrid breaks assumptions baked into all of those layers. 1. "Safe" describes intent, not payload This is the single most important thing to internalize. The safe designation means the client is not requesting a state change. It says nothing about whether the body is malicious. A QUERY body can carry SQL injection, XSS, command injection, or an oversized payload just as easily as a POST body can. Any WAF/IDS rule set that inspects POST bodies for these patterns must apply the same coverage to QUERY — SQLi, XSS, and command-injection inspection, plus request size limits. Give QUERY POST-level scrutiny at the body, even while trusting its read-only semantics for caching and retries. Treating "safe" as "harmless" is the mistake that turns a clean protocol upgrade into an open door. 2. Cache poisoning and cache deception QUERY is explicitly cacheable, and RFC 10008's cache model requires the cache key to incorporate the request body. That's non-negotiable, because otherwise two different queries to the same URL would collide. The risk: a cache that hashes or normalizes the body incorrectly — or normalizes it differently than the origin processes it — can return the wrong response on a false-positive key match. That's cache poisoning (an attacker plants a response that later gets served to victims) and cache deception (a victim's sensitive response gets cached under a key an attacker can retrieve) in one bug class. It's the same underlying failure as the GitHub Actions cache-poisoning attacks — the cache key doesn't capture the full request — just at a different layer of the stack. Any cache you enable for QUERY needs an explicit audit of how it derives keys from the body. Worth noting: as of mid-2026, current Chrome and Firefox send QUERY but don't cache repeated identical QUERYs yet. So browser-side caching is unimplemented rather than solved — the poisoning surface today lives in your CDN, reverse proxy, and API gateway. 3. The CSRF trap Because QUERY is labeled "safe," it's tempting to exclude it from CSRF protection the way you might exclude GET. Don't. The safe designation is a semantic promise, not an enforcement mechanism. If any endpoint accepts QUERY and has any side effect — logging that mutates state, a search that also writes an audit record, a "read" that lazily provisions something — it must remain covered by CSRF checks regardless of the method's designation. Middleware that method-matches on POST|PUT|DELETE|PATCH will silently skip QUERY. Extend it explicitly. 4. Method allowlists and request-smuggling flags Most WAFs, API gateways, and load balancers enforce method allowlists written as literal sets — and those written before June 2026 don't mention QUERY. Two failure modes result, and they pull in opposite directions: Reject: strict setups drop QUERY as an unknown verb, and your rollout silently fails at the edge. Pass through uninspected: looser setups forward QUERY but skip the body inspection they apply to POST — the worst outcome, an inspection blind spot. There's also a genuine request-smuggling dimension. Many enterprise WAFs flag non-standard verbs as protocol anomalies or smuggling vectors, precisely because inconsistent method handling across a proxy chain is how desync attacks start. If your CDN, WAF, and origin disagree about whether QUERY is valid — or one preserves the body while another strips it — you've created exactly the kind of parsing inconsistency smuggling exploits. On AWS, for example, CloudFront must be explicitly configured to forward QUERY with its body, and AWS WAF Core Rule Sets need QUERY deliberately whitelisted rather than caught by anomaly rules. The fix everywhere is the same: make QUERY a deliberate decision at every hop, not an accident. For penetration testers, the flip side is a fresh request type worth throwing at filters tuned for the usual suspects. Rules that catch a POST-body payload may not fire on the identical payload sent via QUERY. 5. Content-Type must be enforced, not sniffed RFC 10008 requires rejecting requests whose Content-Type is missing or inconsistent with the body, and explicitly forbids content sniffing — a server may not guess the media type and override a missing or wrong one. If you accept application/json, parse it as JSON; if you use a custom query DSL, define its media type and advertise it via Accept-Query. Leave this vague and you've simply carried the implicit, undocumented conventions of the POST /search era onto a shiny new method — with the added risk that a lenient parser and a strict one in your chain disagree about what the body means. 6. The logging trade-off is real but not free Moving search conditions out of the URL and into the body is a genuine privacy win: URIs persist in access logs, analytics, browser history, Referer headers, and bookmarks, and sensitive selectors don't belong there. But if your API gateway or application logs request bodies — many do, for debugging — those conditions end up recorded anyway, now in a place your log-redaction rules may not cover. You haven't eliminated the leak; you've relocated it. Audit body logging and redaction on QUERY endpoints as deliberately as you'd audit URL logging. 7. CORS preflight is mandatory QUERY is not on the CORS-safelisted method list, so browser JavaScript must send an OPTIONS preflight before any cross-origin QUERY. Test how your actual edge and application stack handles that preflight flow — a misconfigured CORS policy that reflexively allows a new method, or one that blocks the preflight, will either over-permit or silently break browser clients. 8. Observability blind spots Dashboards, log parsers, rate-limit buckets, and SIEM detection rules keyed on method names will bucket QUERY as "unknown" or drop it entirely. During the transition, flag QUERY traffic for visibility — a Sigma-style rule that surfaces QUERY requests so you can confirm they're expected — and tune it to your known-good clients as adoption grows. The goal is deliberate awareness during the transition, not a permanent alert. Where support actually stands A method this fundamental gets adopted layer by layer, and that's normal. The honest picture as of early July 2026: Node.js — parses QUERY at the HTTP layer, and has since early 2024, ahead of standardization. OpenAPI 3.2 — has a place to document QUERY operations. Browsers — fetch(url, { method: 'QUERY', body }) and XHR work (QUERY is neither forbidden nor normalized away), but neither Chrome nor Firefox caches QUERY responses yet, and declarative <form method="query"> falls back to GET and drops the body. Mozilla and WebKit standards positions are in progress. Spring — close, but hasn't shipped support. CDNs — Cloudflare and Akamai co-authored the RFC, so edge support may well arrive before framework integrations. Combined with the cache-key caveat, that means your edge may understand QUERY before your app does — plan accordingly. The practical read: solid for server-to-server APIs and backend services today; early-stage for public browser-facing traffic. A general adoption checklist QUERY is a semantically clean upgrade path, not a replacement. Existing POST /search endpoints keep working; migrate gradually. Before QUERY traffic shows up against your applications, confirm each layer treats it deliberately: Edge / CDN — Confirm your CDN is configured to recognize QUERY and forward it to the origin with its body intact, not discard the payload. WAF / API gateway — Add QUERY to method allowlists explicitly. Apply POST-level body inspection (SQLi, XSS, command injection) and size limits. Make sure anomaly/smuggling rules don't flag it by accident, and that no hop strips the body. Cache layer — Verify cache keys are built from the full request body, not just the URL and headers. Audit body normalization for false-positive collisions before enabling QUERY caching. CSRF middleware — Extend coverage to QUERY on any endpoint with side effects. Don't let a "safe" designation exclude it from protection. Content-Type handling — Enforce a required, consistent Content-Type; reject missing or mismatched types; never content-sniff. Advertise supported types via Accept-Query. Logging & redaction — Confirm request-body logging on QUERY endpoints is covered by the same redaction rules you'd apply to sensitive URL parameters. CORS — If browser clients are in scope, test the OPTIONS preflight flow end to end. Confirm your policy neither over-permits nor blocks the new method. Client tooling — Confirm the SDKs and HTTP libraries your consumers use support QUERY, and plan a POST-fallback path (or the Accept-Query discovery flow) for those that don't. Observability — Update method-keyed dashboards, rate limiters, and SIEM rules to recognize QUERY. Add a detection rule to surface QUERY traffic during rollout, tuned to known-good clients. Get those nine right and QUERY is exactly what the web has been missing for 16 years: a request that finally tells the truth about what it's doing. Skip them, and you've handed every layer of your stack a verb it doesn't understand.383Views1like0CommentsiRules for recreation: HTTP Protocol Parser implemented using BIG-IP iRule(unfinished)
Hi, everyone in devcentral: I am currently using iRules to simulate the basic functions of an http profile. With this set of scripts, you can achieve similar functionality without needing to mount an http profile on Virtual Server. This set of scripts is only for learning iRules, HTTP, TCP, and related knowledge, and must not be used in a production environment. If there is a need for HTTP protocol parsing, please use the http profile. The current functions are not yet complete; additional features will be added later. Anyone interested are welcome to provide suggestions. GitHub - lfptss/http_protocol_parser · GitHub294Views1like3CommentsStrict header Insertion
Howdy! Incredibly new to the F5 world, and trying to learn fast after the last F5 SME left. Here's my issue: Our organization currently has a static page being served up directly on the F5. This is how the former SME implemented the page - when HTTP_REQUEST { switch [HTTP::uri] { "/" { HTTP::respond 200 content [ifile get webpage_ifile] } "/mainpage.png" { HTTP::respond 200 content [ifile get mainpage_ifile] } "/favicon.ico" { HTTP::respond 200 content [ifile get favicon_ifile] } } } It's three files - an html file, the page png, and the fav icon. It was just pinged on a security audit for not having HSTS implemented for this static page. Having read a few of the HSTS implementation guide, I cannot seem to get it to work with this irule. I've tried http_response and http_response_release, and even defining the strict security on the same http::respond line. None of it seems to work. Is there a better way to implement this static page or a way to implement strict security in this situation? Thank you for any help someone can provide! NickSolved648Views0likes11CommentsHTTP Monitor to Check USER-COUNT from Ivanti Node – Regex Issues
Hi everyone, I'm trying to configure an HTTP health monitor on an F5 LTM to check a value returned by an external Ivanti (Pulse Secure) node. The goal is to parse the value of the USER-COUNT field from the HTML response and ensure it's below or equal to 3000 users (based on our license limit). If the value exceeds that threshold, the monitor should mark the node as DOWN. The Ivanti node returns a page that looks like this: <!DOCTYPE html ... > <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US"> <head> <title>Cluster HealthCheck</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> </head> <body> <h1>Health check details:</h1> CPU-UTILIZATION=1; <br>SWAP-UTILIZATION=0; <br>DISK-UTILIZATION=24; <br>SSL-CONNECTION-COUNT=1; <br>PLATFORM-LIMIT=25000; <br>MAXIMUM-LICENSED-USER-COUNT=0; <br>USER-COUNT=200; <br>MAX-LICENSED-USERS-REACHED=NO; <br>CLUSTER-NAME=CARU-LAB; <br>VPN-TUNNEL-COUNT=0; <br> </body> </html> I’m trying to match the USER-COUNT value using the recv string in the monitor, like this: recv "USER-COUNT=([0-9]{1,3}|[1-2][0-9]{3}|3000);" I’ve also tried many others. The issue is: even when the page returns USER-COUNT=5000;, the monitor still reports the node as UP, when it should be DOWN. The regex seems to match incorrectly. What I need: A working recv regex that matches USER-COUNT values from 0 to 3000 (inclusive), but fails if the value exceeds that limit. Has anyone successfully implemented this kind of monitor with a numeric threshold check using recv? Is there a reliable pattern that avoids partial matches within larger numbers? Thanks in advance for any insight or working exampleSolved432Views0likes7CommentsServer reporting requests coming from port 80
I have a site using F5 to provided CAC authentication. It's a PHP server, I get these values from the SERVER data: $_SERVER['SERVER_PROTOCOL'] = HTTP/1.1 $_SERVER['SERVER_PORT] = 80 As a user, when I navigate to the site I type HTTPS into the browser, but the site php server still sees it coming in on port 80. Im assuming the connection between the user and the F5 proxy is over HTTPS, but whats the connection between F5 and my server? Is that supposed to be HTTPS? I guess what I'm wondering is... should I be concerned and looking into this deeper?Solved245Views0likes2CommentsHigh CPU utilization (100%).
I observed high CPU utilization (100%) on F5 device, resource provision ASM nominal. I checked the client-side throughput and server-side throughput both are normal but found management interface throughput is very high and what i noticed this is happening in same time period for last 30 days. What could be the reason for this spike. Many thanks in advanced for your time and consideration.2.2KViews0likes14CommentsHSTS is not working.
Hi there, We have one irule is configured on VIP which is redirecting to maintenance page if user access the wrong url on that page HSTS is not working but if we access the right url then HSTS is working. We have enabled HSTS in http profile and that is attached to the same VIP with irule. Is there any way to enable HSTS on maintenance page or any remediation to fix that issue. if { $DEBUG } { log local0. "TEST - Source IP address: [IP::client_addr]" } switch -glob $uri_ext { "/httpfoo*" {set uri_int [string map {"/httpfoo" "/adapter_plain"} $uri_ext]} "/httptest*" {set uri_int [string map {"/httptest" "/adapter_plain"} $uri_ext]} default { HTTP::respond 200 content [ifile get ifile_service_unavailable_html] set OK 0 } } Many thanks in advance.Solved366Views0likes1CommentTelemetry Streaming: getting HTTP statistics via SNMP
Hi F5 community, I am looking to get HTTP statistics (total count, and broken by response code) metrics from Telemetry Streaming via SNMP (seems to be the most viable option). F5-BIGIP-LOCAL-MIB::ltmHttpProfileStat oid: .1.3.6.1.4.1.3375.2.2.6.7.6 However, the stats don't seem to come out correct at all: I do see deltas happening, but they don't match at all the traffic rate I expect to see. Furthermore, I have done some tests where I would start a load testing tool (vegeta) to fire concurrent HTTP requests, for which I do see the logs from the virtual server, but no matching increment in the above SNMP OID entries on none of the profiles configured. What am I doing wrong? does something need to be enabled on the HTTP profile in use to collect those stats? Best, Owayss204Views0likes0Comments(HTTP) Redirection via Arbitrary Host Header
Does that title sound familiar to you? It is something we see through in support cases; quite often when a customer has had a PCI audit or penetration test conducted against their web properties. It sounds alarming, but often has a very simple cause, and protecting against it is often also quite simple! What is the Host header? If we go way back to the earliest webservers and HTTP/1.0, RFC1945 didn’t include a specification for a Host header. Instead, it was assumed that the host (IP address) receiving the request was the only intended destination, and that the server was only serving a single website. Obviously, it became apparent to the architects of the modern world-wide web (Tim Berners-Lee and all the others named in the HTTP RFCs) that more flexibility was required, specifically, the ability for a single target IP address to host more than one website under more than one domain (OK, there’s more to it than that – the role of Proxies is also important here, but irrelevant to our current discussion.) To enable that, the “Host:” header was added to RFC2616, the HTTP/1.1 specification document, which would allow a single server to understand which “virtual host” an incoming request was destined for and, through that, serve multiple domains on one system. There are two ways to satisfy that requirement of HTTP/1.1: By sending a “Host:” header along with the request, specifying the desired target (see fig. 1.1) By sending an “Absolute URI” rather than a relative one, with the URI containing the hostname (see fig. 1.2) (See Section 19.6.1.1 of RFC2616 for more information) GET /index.html HTTP/1.1<CRLF> Host: www.example.com<CRLF> <CRLF> Fig 1.1: An example HTTP/1.1 request with Host header GET http://www.example.com/index.html HTTP/1.1<CRLF> <CRLF> Fig 1.2: An example HTTP/1.1 request with Absolute URI What could go wrong? Quite a lot of things, it turns out! There are all sorts of potential problems – many or most of which are now, thankfully, fixed in all of the common webserver and proxy software available today, but still, we must be wary of things like: Host header confusion If a request includes both a Host: header and an Absolute URI, which is used (the RFC is clear here) and do all systems in the request path agree? Server-Side Request Forgery (SSRF) attacks By including special characters (like @) in a URI, can we coerce a proxy to forward on a request which has been modified in an unexpected fashion? Password reset attacks An attacker might be able to abuse the password reset functionality on a legitimate website by manipulating the Host header, causing the website to send a manipulated, malicious password reset link to the victim’s user account contact details, thereby tricking the victim into visiting a phishing website rather than the legitimate site. Web cache poisoning attacks This is a large and complex topic and relates to much more than just the Host header, but a system which trusts a manipulated Host header may make cache poisoning easier for an attacker to perform. Malicious redirects Finally, we arrive at the topic which started this whole article: malicious redirects to an arbitrary destination. Let’s dive into that one more deeply than the others… Redirection via Arbitrary Host Header Let’s be honest for a moment – the real problem here isn’t that you can cause the target system to generate a redirect to an injected host. That’s perhaps not ideal but doesn’t describe any kind of vulnerability; an attacker can’t manipulate the host header on a victim’s system (without having already compromised the victim’s system in some way) and can’t have the reflected, malicious, host header sent to anyone but themselves… ...Unless they can. In the real world, utilizing such a flaw means carrying out one of the other kinds of attack I mentioned earlier; perhaps you can trigger the server to send a redirect (a 302 response with a Location: header) to your arbitrary malicious destination and cause that response to be cached by an intermediate proxy to be subsequently served to other users? Now you’ve poisoned a web cache and anyone you send to the legitimate site via a phishing attack will ultimately be redirected to your malicious domain. Alternatively, the over-trust in the Host header, shown by its use in the responses Location header, might just be a pointer to an attacker, letting the attacker know that they should try to get the vulnerable system to emit the malicious host in other content, like a password reset email. So, what am I saying? I’m saying that the “Redirection via Arbitrary Host Header Manipulation” result we commonly see in vulnerability scans is not, in and of itself, necessarily something to be alarmed about. An attacker being able to send a manipulated redirect back to themselves is next to useless, but it’s a pointer indicating a system might be vulnerable to other attacks that a scanner can’t easily determine in an automated fashion. Unfortunately for us, it’s also often a PCI audit failure, even if the application architecture isn’t vulnerable in a meaningful way. How do we fix it? In part, that depends on why you’re seeing the problem in the first place, so let’s examine some common scenarios: iRules It’s quite common to redirect from HTTP to HTTPS using an iRule – there’s even a built-in iRule on BIG-IP called _sys_https_redirect for that purpose – and without any other checks, the following kind of rule will result in a redirect being generated for whatever host name was received (in other words, you’ll get dinged for “Redirection via Arbitrary Host Header Manipulation” on your audit): when HTTP_REQUEST { HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::uri] } You could fix this by hard-coding the redirect response, of course, and having a single iRule per target application, and that is the most secure option assuming each virtual server only handles traffic for one application; something like this: when HTTP_REQUEST { HTTP::redirect https://www.example.com/[HTTP::uri] } If you need to support multiple applications per virtual server, then your next-best option would be to use a Data Group to define the valid allowed hostnames and then only redirect if the incoming Host header matches one of the hosts in the data group. There’s an excellent answer for this by Kai Wilke, here: https://community.f5.com/discussions/technicalforum/handling-www-with-host-name-redirects-in-irule/27048/replies/27050 BIG-IP Local Traffic Policies It is also quite common to use Local Traffic Policies to redirect HTTP requests, for example to perform an HTTP-to-HTTPS redirect in a more performant way than an iRule. You can still achieve safety here by using the same techniques as for iRules; define the redirect rule to only act when expected host names are received and to drop all other traffic, e.g.: BIG-IP Advanced WAF (ASM) To make preventing this kind of vulnerability incredibly easy, BIG-IP Advanced WAF has a feature called “HTTP redirection protection” which can be configured and enabled on any ASM policy. Configuring it is quite straightforward and is described in K04211103: Configuring HTTP redirection protection; just remember to make sure you have enabled blocking for the policy and enabled Block for the “Illegal redirection attempt” violation under Policy Building->Learning and Blocking Settings! NGINX For NGINX, you just need to be careful when setting up any redirects and use a hard-coded host element rather than taking the resulting hostname from the incoming (potentially attacker-supplied) host header. In other words, don’t do this: location / { return 302 https://$host$request_uri; } Do this instead: location / { return 302 https://example.com$request_uri; } Something else to point out here – it’s very common for administrators to use ‘$uri’ when constructing redirects, but doing so can open you up to header injection and/or response splitting; be sure to use ‘$request_uri’ instead, whenever possible. That’s all for now! That’s all I’m going to cover in this article – there are other ways you can be vulnerable to open redirects (for example if you take an HTTP parameter and use that to construct a subsequent redirect) which aren’t covered here and are a much broader topic. For this article, I chose to concentrate only on the exact report we see across so many PCI audits and vulnerability scans. I will say, though, that BIG-IP Advanced WAF’s HTTP redirect protection will protect you against many, if not all, of the other ways you can be vulnerable because that protection applies to the redirect itself, i.e., to the HTTP response, rather than the request. For that reason (and many, many others), I’d strongly recommend investigating BIG-IP Advanced WAF if you don’t already use it! As always, feel free to leave any comments or questions below and I’ll try to get back to everyone, and thanks for reading this far!1.1KViews1like0Comments