When a broad rule wins before the protected path
A rule with priority 10 is evaluated before one with priority 20. That sounds boring until the broad rule forwards traffic straight to the application and the narrower rule with authenticate-oidc never runs.
A common failure looks like this:
- priority 10: path
/*forwards totg-app - priority 20: path
/admin*runsauthenticate-oidcand forwards totg-app
The /admin rule is there, but it never gets matched if the wildcard rule catches the request first. The result is a protected path that is only protected in theory. The listener still looks tidy in the console, which is part of the problem.
The same mistake shows up with host headers, custom headers, or a rule that is just too broad. If a rule matches the unauthenticated request shape, the auth action is skipped and the request goes on its way.
Priority 10 shadows the authenticate-oidc rule
Listener rule priority is not decoration. Lower numbers win, full stop. If the broad forwarding rule sits above the auth rule, the auth rule is dead code for that request path.
The fix is to make the protected match the earliest one that can catch it. That means the restrictive rule must sit above any catch-all, not underneath it. If the route to tg-app is shared, the auth action has to be on the rule that actually fires.
Match the exact request shape that bypasses auth
Bypass tests should use the exact shape the load balancer sees. That means the ALB DNS name, the right host header if one is used, and the path that slips past the intended rule. A path like /* is rarely the problem by itself. The problem is that it catches more than the protected route.
Do not assume a protected URL is safe because a matching rule exists somewhere lower down the list. The request has to hit that rule first. If it does not, the auth action never fires.
Hardening the routing graph, not just the listener
The listener page is only one entry point. The actual control surface is the routing graph around it, including any other way to reach the same target groups or backend instances. If the app is reachable through more than one path, one locked-down rule does not buy much.
Direct access to an internet-facing origin ALB behind CloudFront is a classic way to side-step front-door controls. WAF rules on CloudFront do nothing if the ALB DNS name is still reachable. The same applies to sibling load balancers in the same VPC, a different port on the same ALB, or an NLB pointing at the same instances.
Check direct ALB access, alternate ports, and sibling load balancers
Test HTTP and HTTPS directly against the ALB DNS name. Then check any alternate listener ports and any other load balancers that register the same target groups or instances. If one path expects auth and another does not, the weaker path becomes the real front door.
This is where source restrictions fall apart as well. A source-ip condition on one listener rule only protects that rule. If the same target group is reachable somewhere else, the restriction does not follow the traffic.
Treat source-ip conditions and X-Forwarded-For as separate controls
source-ip conditions act on the address the load balancer sees. X-Forwarded-For is just a header unless the downstream service makes trust decisions from it. Those two things are not interchangeable.
If routing.http.xff_header_processing.mode is set to preserve, the backend may see a chain of client and proxy addresses. A service that trusts X-Forwarded-For without a strict proxy boundary can end up making access decisions on something the client can influence. That gets messy fast, and messy access control is still access control.
Proving the gap is closed
Closing this kind of bypass needs tests, not hope. A clean console config tells you very little if the unauthenticated route still reaches the target group by another path.
Test the unauthenticated path against the ALB DNS name
Hit the ALB directly without credentials and without the CloudFront layer in front of it. Use the exact host, path, and port that would trigger the bypass if the rule order is wrong. If the request reaches the backend or returns application content, the auth boundary is still open.
Test both the obvious route and the awkward one. A protected /admin path can still be exposed by a broad /* rule, and a supposedly internal API can still be hit if a sibling listener forwards to the same tg-internal-api.
Verify the target group only appears behind the intended rule
A target group should not be reachable through a second listener with weaker conditions. If the same backend is registered behind multiple load balancers, every one of those paths needs the same level of restraint or the same failure comes back through the side door.
Watch for any rule that forwards to a target group before auth, any alternate listener that skips authenticate-oidc, and any direct route that bypasses CloudFront entirely. If the backend is visible from more than one place, the safest rule in the set only protects one of them.




