Modify WAF rules for welsh translations pages - #2272
Conversation
4b2a745 to
7a8341b
Compare
Submissions of this page can have a large request body as it will contain all the Welsh translations for all content in the form. We previously raised the allowed size for the `admin_extended_post_pages` to 500KB allow for larger requests to this page, as we saw a request size of ~250KB. We are likely to see larger requests for big, complex forms, so add a separate rule for this page to allow for request sizes up to 10MB. Co-Authored-By: Claude
7add10d to
acf6dae
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The new rules exceed the rule-group capacity and insufficiently scope the upload exemption.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Updates CloudFront WAF limits for Welsh translation editing and CSV uploads.
Changes:
- Adds dedicated 10 MB and 100 MB Welsh translation rules.
- Reduces other extended admin POST bodies to 100 KB.
File summaries
| File | Description |
|---|---|
waf.tf |
Adds Welsh translation WAF rules. |
variables.tf |
Defines revised request-size limits. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 2
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| rule { | ||
| # Allow larger POST bodies for the welsh translation page | ||
| name = "allow_welsh_translation_post_bodies" | ||
| priority = 3 |
There was a problem hiding this comment.
It's correct about exceeding capacity. When I tried to apply on dev:
Error reason: You exceeded the capacity limit for a rule group or web ACL., field: RULE_GROUP, parameter: 60
I guess we need to increase the capacity. I'm not sure we still need a separate rule for "allow_bulk_options_uploads", though as the allowed size is the same as for "allow_admin_extended_post_bodies"
| statement { | ||
| and_statement { | ||
| statement { | ||
| regex_match_statement { | ||
| field_to_match { |
We had previously raised this from 100KB to 500KB to allow for larger requests to the Welsh translations page. This page now has its own rule, so reduce the maximum allowed size for POST requests to the extended endpoints to 100KB.
acf6dae to
2c43f00
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The rule group exceeds its WCU capacity, and the new limits are not enforceable with the configured body inspection size.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (3)
infra/modules/cloudfront_waf_protection/waf.tf:207
- This terminating
allowturns the new upload endpoint into a WAF bypass: it has no POST/content-type condition and stops evaluation before the common, IP reputation, known-bad-input, anti-DDoS, and rate-limit rules. Scope the exception to the intended POST upload and exempt only the managedSizeRestrictions_BODYcheck so the remaining protections still run.
action {
allow {}
# Stop processing
infra/modules/cloudfront_waf_protection/waf.tf:230
- This does not enforce the stated 100 MB upload maximum. CloudFront WAF inspects only the first 16 KB by default here, so with default oversize handling every body above that limit is evaluated from a prefix that is always
LE100 MB and gets allowed. Enforce the upper bound at the origin or another layer that can observe the complete upload.
size_constraint_statement {
field_to_match {
body {}
}
comparison_operator = "LE"
size = var.welsh_translation_upload_max_size
infra/modules/cloudfront_waf_protection/waf.tf:156
- Adding these two rules raises this rule group's required capacity from 50 to 78 WCUs: the existing rules already consume all 50, and each new regex/LOWERCASE plus size constraint adds 14. AWS WAF rejects an update whose rules exceed the group's fixed capacity, so this change cannot deploy. Provision sufficient capacity and account for the replacement required when changing a rule group's immutable capacity.
rule {
# Allow larger POST bodies for the welsh translation page
name = "allow_welsh_translation_post_bodies"
priority = 3
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Balanced
| size_constraint_statement { | ||
| field_to_match { | ||
| body {} | ||
| } | ||
| comparison_operator = "LE" | ||
| size = var.welsh_translation_post_body_max_size |
There was a problem hiding this comment.
🔵 Needs a closer look
The WAF capacity, terminating exceptions, and ineffective full-body limits create deployment and security issues.
Review details
Suppressed comments (5)
infra/modules/cloudfront_waf_protection/waf.tf:203
- The rule group still declares only 50 WCUs at
waf.tf:56. AWS WAF sums the costs of every nested statement and text transformation, so adding these two regex/size rules pushes this group beyond that capacity and the update will be rejected. Recalculate withCheckCapacityand increase the rule-group capacity before deployment.
rule {
# Allow large POST bodies for the Welsh translation file upload page
name = "allow_welsh_translation_upload_post_bodies"
priority = 4
infra/modules/cloudfront_waf_protection/waf.tf:217
- This terminating exception matches every method and content type on the upload URL. Requests such as GETs or non-upload POSTs therefore bypass all later managed WAF and rate-limit rules; scope it to POST multipart requests, as the existing upload exception does at
waf.tf:402-414.
regex_match_statement {
field_to_match {
uri_path {}
}
regex_string = "^/forms/\\d+/welsh-translation-upload$"
infra/modules/cloudfront_waf_protection/waf.tf:183
- This does not enforce a 10 MB maximum. For CloudFront, WAF body inspection defaults to the first 16 KB (and can only be raised to 64 KB); with the default
oversize_handling = CONTINUE, the inspected prefix satisfiesLE 10 MBeven when the full request exceeds 10 MB, so the terminating allow still applies. Enforce the real limit using a reliable full-request size check rather than this body-prefix comparison.
comparison_operator = "LE"
size = var.welsh_translation_post_body_max_size
infra/modules/cloudfront_waf_protection/waf.tf:230
- This does not enforce the advertised 100 MB upload maximum. CloudFront WAF inspects only the initial body segment (16 KB by default, at most 64 KB), and the default oversize behavior evaluates that prefix; consequently
LE 100 MBalso matches requests whose full body is over 100 MB and terminates WAF processing. Use a full-request size limit at a layer that can observe the complete upload.
comparison_operator = "LE"
size = var.welsh_translation_upload_max_size
infra/modules/cloudfront_waf_protection/waf.tf:170
- This terminating
allowrule is not restricted to POST, despite its stated purpose. A GET or another method with a small/empty body also matches and skips all later managed WAF and rate-limit rules; add a method predicate so only the intended POST submission receives the exception.
regex_match_statement {
field_to_match {
uri_path {}
}
regex_string = "^/forms/\\d+/welsh-translation$"
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
- Review effort level: Balanced
Add a new WAF rule that allows POST request bodies of up to 100MB for file uploads to the Welsh translations upload page. We have server-side validation to allow files of only up to 10MB, but we want the WAF allow larger files so we are able to show a validation error message to the user. This matches the allowed size of file upload requests for forms-runner. We can reduce the allowed size for this if we add client-side browser validation for the file size in the future. Co-Authored-By: Claude
2c43f00 to
8891215
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The rule-group capacity is insufficient, body limits are ineffective above WAF’s inspection ceiling, and the upload exception is overly broad.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (3)
infra/modules/cloudfront_waf_protection/waf.tf:156
- The rule group still declares
capacity = 50, but these two rules add regex, header, and body-size statements while removing only an entry from the existing regex pattern set (which does not reduce that set's WCU cost). This pushes the group's computed WCU above its declared capacity, so AWS will reject the rule-group update. Increase/recreate the group with sufficient capacity or move these rules into a separately sized group.
rule {
# Allow larger POST bodies for the welsh translation page
name = "allow_welsh_translation_post_bodies"
priority = 3
infra/modules/cloudfront_waf_protection/waf.tf:198
- A CloudFront WAF inspects only the configured body prefix (16 KB here because the web ACL has no
association_config). With the default oversize handling, a request larger than that is evaluated using the truncated prefix, which is stillLE 10 MB; therefore this rule also allows bodies far larger than 10 MB. Enforce the actual maximum at the origin/edge using total request length rather than a WAFbodysize constraint.
size_constraint_statement {
field_to_match {
body {}
}
comparison_operator = "LE"
size = var.welsh_translation_post_body_max_size
infra/modules/cloudfront_waf_protection/waf.tf:229
- Unlike the other multipart upload exceptions in this module, this terminating
allowrule does not requireContent-Type: multipart/form-data. Consequently, any request to this path—including non-upload payloads—bypasses all later managed WAF rule groups. Add the same multipart header predicate used by the Welsh translation and brand/file upload rules.
statement {
and_statement {
statement {
regex_match_statement {
field_to_match {
- Files reviewed: 2/2 changed files
- Comments generated: 2
- Review effort level: Balanced
| description = "The maximum allowed request body size in bytes for admin endpoints that require larger payloads than standard operations" | ||
| type = number | ||
| default = 500 * 1024 # 500 KB | ||
| default = 100 * 1024 # 100 KB |
| size_constraint_statement { | ||
| field_to_match { | ||
| body {} | ||
| } | ||
| comparison_operator = "LE" | ||
| size = var.welsh_translation_upload_max_size |
|
Looks like we're changing how we allow these requests in #2269 so this will need to be updated |
What problem does this pull request solve?
Trello card: https://trello.com/c/35HPJgw3/3247-allow-uploading-a-csv-of-welsh-translations
This PR:
allow_admin_extended_post_bodiesrule back to 100KB now this no longer applies to the Welsh translations pageThings to consider when reviewing
Reminders
If you've made changes to the deployer role (files in
modules/deployer-access):make <environment> forms/account applyon the relevant environments (dev,stagingand/orprod)apply-forms-terraform-<environment>pipelines have run successfully