# Primeiros passos com WAF

Este guia orienta você a pontuar a sua primeira requisição contra o [Web Application Firewall (WAF)](/pt-br/documentacao/plataforma/firewall/#waf).

- Crie um rule set que carrega oito famílias de ameaças com sensibilidade `medium`.
- Aplique esse rule set a um firewall com um behavior `Set WAF` em modo blocking.
- Envie uma requisição com forma de injection e leia a recusa.

Quatro objetos colocam uma requisição sob inspeção, e cada um se liga ao seguinte:

1. O **rule set** guarda as famílias de ameaças e a sensibilidade escolhida para cada uma.
2. O **firewall** carrega o módulo WAF, e o **workload** que atende a sua aplicação está vinculado a esse firewall.
3. A **regra do Rules Engine** nesse firewall carrega um behavior `Set WAF`, que nomeia o rule set e o modo.
4. A **requisição** é o que o WAF então pontua contra o rule set.

Um rule set não inspeciona nada por conta própria. Enquanto uma regra do Rules Engine não o nomear, nenhuma requisição é pontuada.

---

Selecione a interface que você vai usar. Os pré-requisitos e todas as etapas abaixo seguem essa escolha.

## Pré-requisitos

- Uma conta Azion. Para criar uma, consulte [Como criar uma conta na Azion](/pt-br/documentacao/fundamentos/criar-uma-conta/).
- Um firewall com o módulo WAF habilitado. O WAF é o único módulo que um firewall não habilita por conta própria. Consulte [Defina as configurações principais de um firewall](/pt-br/documentacao/guias/seguranca-de-aplicacoes/firewall-e-waf/firewall-definir-main-settings/).
- Um workload vinculado a esse firewall, atendendo uma aplicação. Consulte [Vincule um firewall a um workload](/pt-br/documentacao/guias/seguranca-de-aplicacoes/firewall-e-waf/proteja-seu-dominio/).

**Console**

- Acesso ao Azion Console. Para entrar, consulte [Como acessar o Azion Console](/pt-br/documentacao/guias/plataforma/conta-e-billing/como-acessar-o-azion-console/).

**CLI**

- A [Azion CLI](/pt-br/documentacao/devtools/cli/) instalada e autorizada.

**API**

- Um personal token e o `curl`. Para criar um token, consulte [Personal Tokens](/pt-br/documentacao/fundamentos/personal-tokens/).

---

## Crie o WAF rule set

O rule set guarda o que detectar. Ele carrega oito famílias de ameaças, e cada família tem um nível de sensibilidade que fixa o score em que ela bloqueia. Toda família começa em `medium`, que é o nível que este guia usa.

**Console**

Para criar o rule set no Azion Console:

1. **Abra a página WAF Rules**

   Acesse o [Azion Console](https://console.azion.com/) > **Edge Libraries** > **WAF Rules**.

2. **Selecione + WAF Rule**

3. **Nomeie o rule set**

   Na seção **General**, informe um **Name**. Por exemplo: `storefront-waf`.

4. **Deixe todas as famílias na sensibilidade padrão**

   A seção **Threat Type Configuration** lista oito famílias de ameaças. Cada uma abre em *Sensitivity Medium*.

5. **Mantenha o switch Active habilitado**

6. **Salve o rule set**

O rule set aparece em **WAF Rules**, que lista o seu **Threat Type Configuration**, **Status**, **Last Editor** e **Last Modified**.

**CLI**

A Azion CLI cria um rule set completo a partir apenas de um nome. Para criá-lo:

1. **Execute o comando de criação**

   ```bash
   azion create waf --name "storefront-waf"
   ```

2. **Leia a saída**

   O comando imprime o id do novo rule set:

   ```text
   Created WAF with ID 12349
   ```

O rule set está ativo, roda no ruleset `1` e carrega as oito famílias de ameaças em `medium`. Anote o id. Você o passa para a regra.

**API**

O body da requisição carrega as oito famílias de ameaças e a sensibilidade de cada uma.

1. **Envie a requisição de criação**

   Substitua `[TOKEN VALUE]` pelo seu personal token:

   ```bash
   curl --request POST \
     --url https://api.azion.com/v4/workspace/wafs \
     --header 'Accept: application/json' \
     --header 'Authorization: Token [TOKEN VALUE]' \
     --header 'Content-Type: application/json' \
     --data '{
     "name": "storefront-waf",
     "active": true,
     "product_version": "1.0",
     "engine_settings": {
       "engine_version": "2021-Q3",
       "type": "score",
       "attributes": {
         "rulesets": [1],
         "thresholds": [
           { "threat": "cross_site_scripting", "sensitivity": "medium" },
           { "threat": "directory_traversal", "sensitivity": "medium" },
           { "threat": "evading_tricks", "sensitivity": "medium" },
           { "threat": "file_upload", "sensitivity": "medium" },
           { "threat": "identified_attack", "sensitivity": "medium" },
           { "threat": "remote_file_inclusion", "sensitivity": "medium" },
           { "threat": "sql_injection", "sensitivity": "medium" },
           { "threat": "unwanted_access", "sensitivity": "medium" }
         ]
       }
     }
   }'
   ```

2. **Leia a resposta**

   Uma criação responde `202`, não `201`, e `"state": "pending"` significa que a alteração ainda está propagando:

   ```json
   {
     "state": "pending",
     "data": {
       "id": 12349,
       "active": true,
       "name": "storefront-waf",
       "last_editor": "user@example.com",
       "last_modified": "2026-01-01T12:00:00.000000Z",
       "product_version": "1.0",
       "engine_settings": {
         "engine_version": "2021-Q3",
         "type": "score",
         "attributes": {
           "rulesets": [1],
           "thresholds": [
             { "threat": "cross_site_scripting", "sensitivity": "medium" },
             { "threat": "directory_traversal", "sensitivity": "medium" },
             { "threat": "evading_tricks", "sensitivity": "medium" },
             { "threat": "file_upload", "sensitivity": "medium" },
             { "threat": "identified_attack", "sensitivity": "medium" },
             { "threat": "remote_file_inclusion", "sensitivity": "medium" },
             { "threat": "sql_injection", "sensitivity": "medium" },
             { "threat": "unwanted_access", "sensitivity": "medium" }
           ]
         }
       },
       "version_id": null,
       "version_state": null,
       "is_versioned": false,
       "version": null
     }
   }
   ```

Anote o `id`. Você o passa para a regra.

---

## Aplique o rule set com uma regra do Rules Engine

Uma regra do [Rules Engine for Firewall](/pt-br/documentacao/plataforma/firewall/rules-engine/) seleciona requisições pelos seus próprios critérios. O seu behavior `Set WAF` então nomeia um rule set e um modo. A regra abaixo aplica o seu rule set a todas as requisições que o firewall recebe.

O modo é obrigatório, e ele pertence ao behavior, não ao rule set. `Blocking` recusa uma requisição cujo score alcança um limiar. `Logging` registra essa mesma requisição e a entrega. Este guia usa `Blocking`.

> **Atenção**
>
> Baseie o critério na URI da requisição, nunca na query string. Um critério como `${request_args}` `matches` `.*` não corresponde a uma requisição sem query string. Ele ignora silenciosamente todo `POST` cujo payload fica no body.

**Console**

Para aplicar o rule set no Azion Console:

1. **Abra o firewall vinculado ao seu workload**

   Ainda no Azion Console, vá para **Firewalls** e selecione esse firewall.

2. **Selecione a aba Rules Engine**

3. **Selecione + Rule**

4. **Nomeie a regra**

   Informe um nome para a regra. Por exemplo: `Apply storefront-waf`.

5. **Defina o critério**

   Na seção **Criteria**, selecione a variável `Request Uri`, o operador de comparação *starts with* e `/` como argumento.

6. **Adicione o behavior Set WAF**

   Na seção **Behaviors**, selecione **Set WAF** e então selecione o rule set que você criou.

7. **Selecione Blocking como o modo**

8. **Salve a regra**

O firewall agora pontua contra o rule set todas as requisições que recebe. Uma regra carrega no máximo um behavior `Set WAF`.

**CLI**

O `azion create firewall-rule` lê a regra inteira de um arquivo JSON. Ele não tem flag para um behavior nem para um modo.

1. **Escreva a regra em um arquivo**

   Salve o seguinte como `fw-rule.json`, com o id do seu rule set em `waf_id`:

   ```json
   {
     "name": "Apply storefront-waf",
     "active": true,
     "description": "",
     "criteria": [
       [
         {
           "conditional": "if",
           "variable": "${request_uri}",
           "operator": "starts_with",
           "argument": "/"
         }
       ]
     ],
     "behaviors": [
       {
         "type": "set_waf",
         "attributes": {
           "waf_id": 12349,
           "mode": "blocking"
         }
       }
     ]
   }
   ```

2. **Crie a regra**

   Substitua `<firewall-id>` pelo id do seu firewall:

   ```bash
   azion create firewall-rule --firewall-id <firewall-id> --file fw-rule.json
   ```

3. **Leia a saída**

   O comando imprime o id da nova regra:

   ```text
   Created Firewall Rule with ID 123457
   ```

O firewall agora pontua contra o rule set todas as requisições que recebe.

**API**

Os critérios carregam `${request_uri}`, então o body é enviado a partir de um arquivo.

1. **Escreva a regra em um arquivo**

   Salve o seguinte como `rule.json`, com o id do seu rule set em `waf_id`:

   ```json
   {
     "name": "Apply storefront-waf",
     "active": true,
     "criteria": [
       [
         {
           "conditional": "if",
           "variable": "${request_uri}",
           "operator": "starts_with",
           "argument": "/"
         }
       ]
     ],
     "behaviors": [
       {
         "type": "set_waf",
         "attributes": {
           "waf_id": 12349,
           "mode": "blocking"
         }
       }
     ]
   }
   ```

2. **Envie a requisição de criação**

   Substitua `<firewall-id>` pelo id do seu firewall:

   ```bash
   curl --request POST \
     --url https://api.azion.com/v4/workspace/firewalls/<firewall-id>/request_rules \
     --header 'Accept: application/json' \
     --header 'Authorization: Token [TOKEN VALUE]' \
     --header 'Content-Type: application/json' \
     --data @rule.json
   ```

3. **Leia a resposta**

   Um `202` carrega a regra, com a `order` que ela ocupa entre as regras do firewall:

   ```json
   {
     "state": "pending",
     "data": {
       "id": 123456,
       "name": "Apply storefront-waf",
       "last_editor": "user@example.com",
       "last_modified": "2026-01-01T12:00:00.000000Z",
       "created_at": "2026-01-01T12:00:00.000000Z",
       "active": true,
       "criteria": [
         [
           {
             "conditional": "if",
             "variable": "${request_uri}",
             "operator": "starts_with",
             "argument": "/"
           }
         ]
       ],
       "behaviors": [
         {
           "type": "set_waf",
           "attributes": {
             "waf_id": 12349,
             "mode": "blocking"
           }
         }
       ],
       "description": "",
       "order": 1
     }
   }
   ```

Um body que omite `mode` é recusado com `400` e o erro `10059 Required Field`, apontando para `/data/behaviors/0/attributes/mode`.

---

## Verifique que o WAF bloqueia uma requisição

A verificação é a mesma qualquer que seja a interface que construiu a regra. O seu workload responde em um domínio no formato `<id>.map.azionedge.net`.

Um novo vínculo leva tempo para alcançar a infraestrutura distribuída da Azion. Espere perto de seis minutos até a regra entrar em vigor. O domínio então responde de forma inconsistente por vários minutos, enquanto a alteração chega em diferentes lugares. Uma requisição que ainda retorna a resposta anterior não quebrou nada: espere e envie-a de novo.

Envie primeiro uma requisição limpa:

```bash
curl -i https://<your-workload-domain>/
```

A requisição não é pontuada como ameaça e alcança a aplicação, que a responde:

```text
HTTP/2 200
```

A sua própria aplicação decide esse status. O que importa é que a requisição não é recusada.

Agora envie uma requisição com forma de injection, carregando `1' OR '1'='1` na query string:

```bash
curl -i "https://<your-workload-domain>/?q=1%27%20OR%20%271%27%3D%271"
```

O WAF a recusa:

```text
HTTP/2 400
content-type: text/html
x-azion-request-id: 0123456789abcdef0123456789abcdef
```

O body é a página de erro padrão da Azion, encabeçada por **Bad Request**. Nada na resposta nomeia o WAF, a regra que correspondeu ou o score. Anote o `x-azion-request-id`: esse valor encontra a requisição no [Real-Time Events](/pt-br/documentacao/plataforma/real-time-events/).

Essa requisição disparou as regras internas `1009` e `1013`, ambas no argumento `q`. Ela pontuou sob as famílias SQL injection e cross-site scripting. O seu rule set agora está pontuando tráfego.

---

## Próximos passos

- [Score e modos](/pt-br/documentacao/plataforma/firewall/waf/score-e-modos.md): O caminho que uma requisição percorre, o modelo de score e o que cada modo faz.
- [Boas práticas de Firewall](/pt-br/documentacao/plataforma/firewall/boas-praticas.md#waf): Por que produção começa em Logging, e não no Blocking que este guia usou, e o que cada prática custa.
- [Ajuste um WAF rule set](/pt-br/documentacao/guias/seguranca-de-aplicacoes/firewall-e-waf/tune-waf.md): Leia o que um rule set correspondeu e transforme um falso positivo em uma exceção.
- [Isente um parâmetro de query string](/pt-br/documentacao/guias/seguranca-de-aplicacoes/firewall-e-waf/isentar-parametro-query.md): Tire um argumento do score de uma regra interna, na primeira vez que uma requisição legítima for bloqueada.
- [Aplique um rule set a toda requisição](/pt-br/documentacao/guias/seguranca-de-aplicacoes/firewall-e-waf/aplicar-rule-set.md): A regra que vincula um rule set a um firewall, para o próximo firewall que precisar de uma.
- [Limites de Firewall](/pt-br/documentacao/plataforma/firewall/limites.md#waf): Os limites dentro dos quais um rule set opera, e o uso que cada service plan inclui.
