Como usar o AWS WAF para mitigar as vulnerabilidades RCE do PHP2Shell (CVE-2026-109618 e CVE-2026-109619)

PHP2Shell: o que aconteceu

Em 21 de outubro de 2026, o projeto PHP divulgou correções emergenciais para duas vulnerabilidades críticas de execução remota de código (RCE — Remote Code Execution) no núcleo do PHP, identificadas como CVE-2026-109618 e CVE-2026-109619 — batizadas coletivamente de PHP2Shell. Ambas receberam nota 9.2 (Crítica) pelo CVSS v4.0 e permitem que um atacante não autenticado execute código arbitrário em servidores vulneráveis.

As versões corrigidas são: PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35. A atualização do PHP é a única correção completa e deve ser a primeira prioridade de qualquer equipe afetada.

Dito isso, atualizar toda uma frota de servidores não acontece da noite para o dia — é preciso inventariar onde o PHP está em execução, agendar janelas de manutenção e testar as aplicações contra as novas versões. É justamente nesse intervalo que o AWS WAF (Firewall de Aplicação Web) entra como controle de defesa em profundidade.

Para entender como a inteligência de ameaças da Amazon detectou a exploração do PHP2Shell antes da divulgação pública, consulte o post Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot. Para o status dos serviços AWS e a regra WAF recomendada pela AWS, veja o AWS Security Bulletin 2026-143-AWS.

Entendendo as vulnerabilidades

Ambas as falhas do PHP2Shell são problemas de RCE não autenticado enraizados na forma como o PHP processa requisições multipart/form-data — o formato utilizado por navegadores em uploads de arquivos — antes mesmo que o código da sua aplicação seja executado. Por isso, as regras de WAF descritas aqui focam em tráfego multipart, tamanho do corpo da requisição e no campo de progresso de upload de sessão.

  • CVE-2026-109618 (corrupção por falta de memória): corrompe a memória quando o PHP fica sem memória no meio de uma requisição. Veja o advisory PHP GHSA-w8hw-w9fx-j79w.
  • CVE-2026-109619 (estado global obsoleto): permite que uma requisição deixe dados obsoletos que uma requisição posterior, no mesmo processo worker, reutiliza. Veja o advisory PHP GHSA-6wmf-4rv5-p3rp.

Para análise completa das causas raiz, versões afetadas e orientações do próprio PHP, consulte o anúncio oficial de segurança do PHP, de 21 de outubro de 2026.

Onde o AWS WAF se encaixa na resposta

O AWS WAF é um controle de defesa em profundidade nessa situação — não um substituto para a atualização do PHP. Os advisories do PHP são explícitos: atualizar para uma versão corrigida é a única mitigação completa. Uma das duas vulnerabilidades está, em grande parte, fora do alcance de qualquer firewall de aplicação web.

Trate as regras descritas aqui como controles mitigadores que ajudam a reduzir a exposição enquanto você aplica o patch. Após a atualização, você pode removê-las ou mantê-las como controles de suporte.

O AWS WAF inspeciona requisições HTTP na borda. Ele não analisa a estrutura interna de um corpo multipart e não tem visibilidade sobre a memória dos workers PHP ou configurações do lado do servidor. A tabela abaixo mapeia cada elemento de ataque à cobertura possível pelo WAF:

  • Campo de progresso de upload de sessão em um POST multipart (PHP_SESSION_UPLOAD_PROGRESS): Sim — uma regra direcionada pode bloquear requisições que contenham esse campo.
  • Caminho de upload multipart (multipart/form-data): Sim, se a aplicação não tiver uploads legítimos. Bloqueie multipart/form-data.
  • Condição de falta de memória por corpo muito grande: Parcial — limite o tamanho do corpo da requisição. Não captura amplificação de cabeçalhos que ficam abaixo do limite.
  • Tentativas repetidas contra o mesmo worker: Sim — uma regra baseada em taxa reduz o volume necessário para exploração.
  • Produtor fatal_error_backtraces (configuração do PHP 8.5): Não — é uma configuração de servidor (fatal_error_backtraces=0).
  • Diagnósticos INI inválidos como consumidor: Não — esse caminho roda no lado do servidor, não via HTTP do cliente.

Implementando as regras no AWS WAF

As regras abaixo são escritas em JSON para o AWFv2 e devem ser implantadas na ACL Web (Web ACL — Lista de Controle de Acesso Web) associada à distribuição do Amazon CloudFront, ao Application Load Balancer ou ao estágio do Amazon API Gateway à frente das suas aplicações PHP.

Importante: antes de qualquer alteração, certifique-se de que o logging do WAFv2 está configurado. Inicie cada regra no modo Count (Contagem), confirme que ela não afeta tráfego legítimo e só então mude para Block (Bloqueio).

Limites de inspeção do corpo da requisição

O AWS WAF inspeciona uma porção limitada do corpo da requisição. No Application Load Balancer e no AWS AppSync, o limite fixo é de 8 KB. Para serviços como CloudFront e API Gateway, o padrão é 16 KB, podendo ser elevado para 32, 48 ou 64 KB via AssociationConfig da Web ACL:

aws wafv2 update-web-acl ... --association-config \
'RequestBody={CLOUDFRONT={DefaultSizeInspectionLimit=KB_16}}'

Regra principal: PHP2Shell

Essa regra bloqueia uma requisição somente quando as três condições do AndStatement são verdadeiras simultaneamente: o método é exatamente POST; um identificador de sessão PHP está presente (via cookie ou corpo da requisição); e o corpo contém PHP_SESSION_UPLOAD_PROGRESS. Combine essa regra com session.upload_progress.enabled=0 no servidor.

{
  "Name": "PHP2Shell",
  "Priority": 0,
  "Statement": {
    "AndStatement": {
      "Statements": [
        {
          "ByteMatchStatement": {
            "SearchString": "POST",
            "FieldToMatch": {
              "Method": {}
            },
            "TextTransformations": [
              {
                "Priority": 0,
                "Type": "NONE"
              }
            ],
            "PositionalConstraint": "EXACTLY"
          }
        },
        {
          "OrStatement": {
            "Statements": [
              {
                "ByteMatchStatement": {
                  "SearchString": "PHPSESSID",
                  "FieldToMatch": {
                    "Cookies": {
                      "MatchPattern": {
                        "All": {}
                      },
                      "MatchScope": "KEY",
                      "OversizeHandling": "CONTINUE"
                    }
                  },
                  "TextTransformations": [
                    {
                      "Priority": 0,
                      "Type": "NONE"
                    }
                  ],
                  "PositionalConstraint": "EXACTLY"
                }
              },
              {
                "ByteMatchStatement": {
                  "SearchString": "PHPSESSID",
                  "FieldToMatch": {
                    "Body": {
                      "OversizeHandling": "CONTINUE"
                    }
                  },
                  "TextTransformations": [
                    {
                      "Priority": 0,
                      "Type": "NONE"
                    }
                  ],
                  "PositionalConstraint": "CONTAINS"
                }
              }
            ]
          }
        },
        {
          "ByteMatchStatement": {
            "SearchString": "PHP_SESSION_UPLOAD_PROGRESS",
            "FieldToMatch": {
              "Body": {
                "OversizeHandling": "CONTINUE"
              }
            },
            "TextTransformations": [
              {
                "Priority": 0,
                "Type": "NONE"
              }
            ],
            "PositionalConstraint": "CONTAINS"
          }
        }
      ]
    }
  },
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "PHP2Shell"
  }
}

Regras adicionais recomendadas

Bloquear requisições multipart quando a aplicação não usa uploads

Atenção: se implementada no modo Block, essa regra vai quebrar aplicações que precisam de upload de arquivos. Se a sua aplicação não precisa de uploads, bloquear multipart/form-data remove o caminho de ataque de falta de memória para ambos os CVEs.

{
  "Name": "Block-Multipart-FormData",
  "Priority": 1,
  "Action": {
    "Count": {}
  },
  "Statement": {
    "ByteMatchStatement": {
      "FieldToMatch": {
        "SingleHeader": {
          "Name": "content-type"
        }
      },
      "PositionalConstraint": "CONTAINS",
      "SearchString": "multipart/form-data",
      "TextTransformations": [
        {
          "Priority": 0,
          "Type": "LOWERCASE"
        }
      ]
    }
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "PHP2ShellBlockMultipart"
  }
}

Limitar o tamanho do corpo da requisição

Limitar o tamanho do corpo reduz a condição de falta de memória por trás do CVE-2026-109618. Use OversizeHandling: MATCH para que qualquer corpo maior que o limite seja bloqueado. Se a sua aplicação tem uploads legítimos grandes, aplique essa regra apenas em rotas específicas via AndStatement no caminho URI.

{
  "Name": "Block-Oversize-Body",
  "Priority": 3,
  "Action": {
    "Count": {}
  },
  "Statement": {
    "SizeConstraintStatement": {
      "FieldToMatch": {
        "Body": {
          "OversizeHandling": "MATCH"
        }
      },
      "ComparisonOperator": "GT",
      "Size": 8192,
      "TextTransformations": [
        {
          "Priority": 0,
          "Type": "NONE"
        }
      ]
    }
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "PHP2ShellBlockOversizeBody"
  }
}

Nota: se você já utiliza o grupo de regras gerenciadas AWSManagedRulesCommonRuleSet, a regra SizeRestrictions_BODY já bloqueia corpos maiores que 8 KB por padrão.

Limitar a taxa de requisições POST repetidas

Uma regra baseada em taxa para requisições POST reduz o volume que um atacante consegue enviar. Essa regra complementa a configuração de servidor pm.max_requests=1, que recicla o worker a cada requisição.

{
  "Name": "RateLimit-Posts",
  "Priority": 4,
  "Action": {
    "Count": {}
  },
  "Statement": {
    "RateBasedStatement": {
      "Limit": 100,
      "EvaluationWindowSec": 60,
      "AggregateKeyType": "IP",
      "ScopeDownStatement": {
        "ByteMatchStatement": {
          "FieldToMatch": {
            "Method": {}
          },
          "PositionalConstraint": "EXACTLY",
          "SearchString": "POST",
          "TextTransformations": [
            {
              "Priority": 0,
              "Type": "NONE"
            }
          ]
        }
      }
    }
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "PHP2ShellRateLimitPosts"
  }
}

Mitigações no lado do servidor que complementam o AWS WAF

As mudanças abaixo endereçam partes do CVE-2026-109619 que ficam abaixo da camada HTTP inspecionada pelo WAF. Aplique-as em paralelo às regras de WAF:

  • Atualize o PHP para 8.5.12, 8.4.27, 8.3.36 ou 8.2.35. Esta é a única correção completa. O PHP 8.1 e anteriores não têm mais suporte upstream — verifique com seu fornecedor de distribuição ou suporte de longo prazo.
  • Para o CVE-2026-109618: defina memory_limit=-1 para que aplicações não possam sobrescrever esse valor, e mantenha post_max_size baixo (8M onde não há uploads, 32M onde há). Aplique limites de memória via container ou cgroup — nunca via RLIMIT_AS ou RLIMIT_DATA, pois esses disparam o caminho vulnerável.
  • Defina fatal_error_backtraces=0 no PHP 8.5 e reinicie todos os workers. Isso desabilita o armazenamento de estado de rastreamento de falhas entre requisições.
  • Defina session.upload_progress.enabled=0 e reinicie todos os workers. Isso desativa o recurso de rastreamento de upload — e é prudente mantê-lo desativado mesmo após o patch.
  • Prefira configurações via php.ini, pool FPM ou inicialização do servidor em vez de sobrescritas de INI por requisição (via .htaccess, php_value ou PHP_VALUE do FastCGI). Remova diretivas obsoletas para evitar avisos de diagnóstico.
  • Elimine erros fatais e timeouts de execução em rotas acessíveis por atacantes — incluindo caminhos de upload, importação, página de erro, shutdown, serialização e extensões.
  • Defina pm.max_requests=1 se a performance permitir. Isso recicla o processo worker após cada requisição, quebrando o vínculo entre a requisição que planta dados obsoletos e a que os reutilizaria.
  • Ative o log de erros (log_errors=On, um error_log funcional, error_reporting=E_ALL) e monitore os logs do Apache, FPM ou proxy em busca de avisos repetidos, deprecações, erros fatais e timeouts em rotas controladas por atacantes. A ausência de erros não é prova de segurança.

Como começar

  1. Faça o inventário de onde o PHP está em execução e quais versões e APIs de servidor (mod_php, FPM, FrankenPHP, LSAPI) estão em uso.
  2. Identifique todos os endpoints públicos que aceitam corpo de requisição.
  3. Decida quais aplicações utilizam uploads multipart — isso determina se você pode bloquear requisições multipart na borda.
  4. Crie ou atualize a Web ACL à frente de cada workload PHP e adicione as regras aplicáveis no modo Count.
  5. Eleve o limite de inspeção do corpo no CloudFront ou API Gateway se uma regra precisar disso.
  6. Monitore as requisições amostradas e as métricas do Amazon CloudWatch para cada regra. Confirme que uploads legítimos e POSTs JSON grandes não estão sendo capturados.
  7. Mude as regras para Block após as métricas estarem limpas. Ordene as prioridades para que as regras de progresso de upload de sessão e multipart rodem antes das regras de tamanho e taxa.
  8. Teste com um POST multipart/form-data benigno, um corpo excessivamente grande e uma requisição contendo PHP_SESSION_UPLOAD_PROGRESS. Espere uma resposta 403 e a métrica da regra correspondente.
  9. Em paralelo, aplique a atualização do PHP e as mitigações de configuração no servidor.
  10. Remova ou mantenha as regras do AWS WAF como controles de suporte após a atualização de toda a frota.

Conclusão

As vulnerabilidades PHP2Shell — CVE-2026-109618 e CVE-2026-109619 — são falhas de RCE não autenticado que atingem o PHP antes mesmo que o código da sua aplicação seja executado. O AWS WAF oferece uma forma de reduzir a superfície de ataque durante a janela de patch: bloqueie o campo de progresso de upload de sessão, bloqueie requisições multipart onde não há uploads esperados, limite o tamanho do corpo e aplique controle de taxa em tentativas repetidas.

Esses controles mitigadores ajudam a reduzir a exposição, mas não fecham as vulnerabilidades. Atualize o PHP para uma versão corrigida, aplique as mudanças de configuração no servidor e trate as regras do AWS WAF como a camada de borda que suporta essas correções — não como a correção em si.

Para saber mais sobre os tipos de regras utilizados aqui, consulte a documentação do AWS WAF sobre limite de inspeção do corpo da Web ACL, tratamento de componentes de requisição com tamanho excessivo e como lidar com corpos HTTP excessivamente grandes. Para os detalhes das vulnerabilidades, consulte os advisories PHP GHSA-w8hw-w9fx-j79w e GHSA-6wmf-4rv5-p3rp, além do manual de progresso de upload de sessão do PHP.

Fonte

Using AWS WAF to apply mitigations for PHP2Shell RCE vulnerabilities (CVE-2026-109618 and CVE-2026-109619) (https://aws.amazon.com/blogs/security/using-aws-waf-to-apply-mitigations-for-php2shell-rce-vulnerabilities-cve-2026-109618-and-cve-2026-109619/)

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *