Escreva scripts Lua personalizados para interceptar e modificar o processamento de requisições web e implementar lógicas de segurança além das regras nativas do WAF. Scripts e parâmetros configuráveis permitem atender a requisitos complexos e específicos do negócio com maior flexibilidade.
Ativar o recurso de Extensões
Para usar as Extensões, conclua as etapas de ativação a seguir:
Edições aplicáveis: Apenas o Web Application Firewall (WAF) Enterprise Edition, Ultimate Edition e Pay-As-You-Go Edition com base em assinatura suportam este recurso.
Faturamento: Este é um serviço pago. O faturamento ocorre da seguinte forma:
Pay-As-You-Go Edition: Use diretamente sem compra prévia. Cobranças adicionais são aplicadas conforme o uso real.
Subscription Edition: Adquira o recurso antes de usá-lo.
Faça login no console do Web Application Firewall 3.0. Na barra de menu superior, selecione o grupo de recursos e a região (Chinese Mainland ou Outside Chinese Mainland) da instância do WAF.
No painel de navegação à esquerda, escolha .
Clique em Buy Now e siga as instruções na tela para ativar o recurso.
Criar uma extensão
Na página Extensions, clique em Create Extension e configure os parâmetros a seguir.
Basic Info: Insira um Plugin Name e uma Plugin Description fáceis de identificar.
-
Plugin Code: Escreva aqui o script Lua para implementar sua lógica de segurança personalizada. Exemplo: Para mais informações sobre a API, consulte Apêndice: Referência da API de scripts Lua personalizados.
-- Custom Lua script example: Extract a query parameter and compare it with a custom parameter. Block if they do not match. -- Step 1: Extract the request parameter local token = aliwaf.req.get_arg('token') -- Step 2: Compare with the custom parameter if token ~= params.token then aliwaf.func.punish() endImportantePara garantir a estabilidade do sistema WAF, o tempo de execução de um único script Lua por requisição é limitado a 2 ms. Durante a fase de Debug and Test, se o tempo de execução exceder esse limite, o script falhará no teste e a criação será interrompida. Em tempo de execução real, caso o tempo de execução de um script ultrapasse 2 ms para uma requisição, o sistema ignorará essa execução.
Não codifique informações sensíveis (como chaves) diretamente no código. Em vez disso, use o recurso Parameter Definition descrito abaixo.
-
Parameter Definition: Extraia valores fixos dos scripts para parâmetros configuráveis e desacople a lógica dos dados. Isso permite ajustar políticas dinamicamente sem modificar o código e gerenciar chaves com segurança. Clique em Add Parameter e conclua a configuração a seguir:
Parameter Name: Nome da variável referenciada no script (por exemplo,
secret_key).Parameter Type: Os tipos suportados incluem String, Number, Boolean, JSON Object e JSON Array. Certifique-se de que o tipo corresponda à lógica de tratamento no seu script.
Parameter Description: Descreve a finalidade do parâmetro.
-
Parameter Value: Suporta os dois modos a seguir:
Manual Input: Insira o valor diretamente.
-
Use KMS Credential: Referencie uma credencial já criada no Key Management Service para armazenar dados sensíveis com segurança. Para que o WAF referencie a credencial com sucesso, anexe a ela a tag a seguir:
Tag Key:
waf:access:enableTag Value:
true
-
Debug and Test:
Plugin Action Parameters: Atualmente suporta apenas o modo Block, que bloqueia a requisição.
-
Traffic Parameters: Simula tráfego real de requisições HTTP. Clique em Add Parameter e insira um Parameter Name (como
method,uriouargs) e o respectivo Parameter Value.Exemplo: Defina
methodcomoPOSTeuricomo/loginpara testar a lógica de proteção de um endpoint de login.
Execution Result: Clique em Run and Debug. O sistema executa o script com base no tráfego simulado e exibe o painel Execution Result à direita. Caso o resultado indique falha, corrija o código seguindo as mensagens de erro específicas.
Próximos passos
Após criar uma extensão, referencie-a em um modelo de proteção de Custom Rule. Para mais informações, consulte Regras personalizadas.
Operações diárias
Na página Extensions, execute as operações a seguir:
Visualizar a lista de plugins: Exibe todas as extensões. Use a caixa de pesquisa para inserir o nome do plugin e localizá-lo rapidamente.
Visualizar regras de proteção associadas: Localize o plugin desejado e clique no ícone
na coluna Associated Rules para exibir os IDs das regras de proteção associadas. Copie um ID e pesquise-o na página Core Web Protection ou Security Reports.Editar uma extensão: Localize o plugin desejado e clique em Edit na coluna Actions para modificar a configuração.
Excluir uma extensão: Localize o plugin desejado e clique em Delete na coluna Actions para remover a extensão.
Apêndice: Referência da API de scripts Lua personalizados
Interfaces principais para scripts Lua personalizados, abrangendo leitura de dados de requisição, criptografia e descriptografia, além de controle de fluxo de requisições.
Exemplo de requisição HTTP
POST /api/v1/orders?source=web&campaign=spring2024 HTTP/1.1
Host: shop.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
Cookie: session_id=abc123xyz; user_prefs=lang%3Den%26theme%3Ddark
Content-Type: application/json
Content-Length: 68
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx
Accept: application/json
eyJwcm9kdWN0X2lkIjogNzg5LCAicXVhbnRpdHkiOiAyLCAidXJnZW50IjogdHJ1ZX0=
Ler dados da requisição
Todas as interfaces retornam uma string. Caso um campo não exista, o sistema retorna uma string vazia.
Ler o método
|
Item |
Tipo |
Descrição |
|
Parâmetro |
- |
- |
|
Valor de retorno |
string |
O método da requisição HTTP, como "GET" ou "POST". |
-- POST --
local method = aliwaf.req.get_method()
Ler o URI
|
Item |
Tipo |
Descrição |
|
Parâmetro |
- |
- |
|
Valor de retorno |
string |
O caminho URI da requisição. |
-- /api/v1/orders --
local uri = aliwaf.req.get_uri()
Ler o domínio
|
Item |
Tipo |
Descrição |
|
Parâmetro |
- |
- |
|
Valor de retorno |
string |
O nome de domínio Host da requisição. |
-- shop.example.com --
local domain = aliwaf.req.get_domain()
Ler a query
|
Item |
Tipo |
Descrição |
|
Parâmetro |
- |
- |
|
Valor de retorno |
string |
A string de query completa da requisição. |
-- source=web&campaign=spring2024 --
local query = aliwaf.req.get_query()
Ler um parâmetro de query
|
Item |
Tipo |
Descrição |
|
Parâmetro |
string |
O nome do parâmetro de query. |
|
Valor de retorno |
string |
O valor correspondente ao parâmetro. Retorna uma string vazia "" caso o parâmetro não exista. |
-- web --
local source = aliwaf.req.get_arg('source')
Ler um cookie
|
Item |
Tipo |
Descrição |
|
Parâmetro |
string |
O nome do cookie. |
|
Valor de retorno |
string |
O valor correspondente ao cookie. Retorna uma string vazia "" caso o cookie não exista. |
-- abc123xyz --
local session_id = aliwaf.req.get_cookie('session_id')
Ler um cabeçalho
|
Item |
Tipo |
Descrição |
|
Parâmetro |
string |
O nome do cabeçalho da requisição HTTP. |
|
Valor de retorno |
string |
O valor correspondente ao cabeçalho. Retorna uma string vazia "" caso o cabeçalho não exista. |
-- Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx --
local auth = aliwaf.req.get_header('Authorization')
Ler o corpo
Verificar o status do corpo da requisição
-
Se o corpo foi totalmente recebido
Item
Tipo
Descrição
Parâmetro
-
-
Valor de retorno
boolean
true indica que o corpo da requisição foi totalmente recebido. false indica que ainda há dados pendentes.
local last = aliwaf.func.is_last_fragment_arrived() -
Se o corpo foi truncado
Item
Tipo
Descrição
Parâmetro
-
-
Valor de retorno
boolean
true indica que o corpo da requisição excedeu o limite e foi truncado. false indica que o corpo da requisição está intacto.
Por padrão, o WAF armazena até 128 KB do corpo da requisição. Requisições que ultrapassarem esse limite serão truncadas (a parte excedente é descartada).
local discard = aliwaf.func.is_request_body_discarded()
Aguardar o corpo
Os corpos de requisição chegam ao WAF em streaming, portanto, o corpo pode não estar totalmente recebido quando o script for executado. Para processar o corpo completo, notifique explicitamente o framework para aguardar o recebimento integral antes de reexecutar o script.
|
Item |
Tipo |
Descrição |
|
Parâmetro |
- |
- |
|
Valor de retorno |
- |
- |
aliwaf.func.wait_request_body()
Exemplo: Ler o corpo da requisição
-- Body not fully received; wait for it --
if not aliwaf.func.is_last_fragment_arrived() then
aliwaf.func.wait_request_body()
return
end
-- Body fully received; check if truncated --
if aliwaf.func.is_request_body_discarded() then
return
end
-- eyJwcm9kdWN0X2lkIjogNzg5LCAicXVhbnRpdHkiOiAyLCAidXJnZW50IjogdHJ1ZX0= --
local body = aliwaf.req.get_body()
-- TODO: Apply business logic to the complete body --
Funções utilitárias comuns
Codificação e decodificação básicas
As interfaces de codificação e decodificação URL, hex e base64 aceitam um parâmetro string e retornam uma string processada. Em caso de falha, retornam uma string vazia.
Codificação e decodificação URL
-
escape_uri
Item
Tipo
Descrição
Parâmetro
string
A string original a ser codificada.
Valor de retorno
string
A string codificada.
-
unescape_uri
Item
Tipo
Descrição
Parâmetro
string
A string codificada em URL a ser decodificada.
Valor de retorno
string
A string original decodificada.
-- a%20b --
local data1 = aliwaf.util.escape_uri('a b')
-- a b --
local data2 = aliwaf.util.unescape_uri('a%20b')
Codificação e decodificação Hex
-
hex_encode
Item
Tipo
Descrição
Parâmetro
string
A string binária a ser codificada.
Valor de retorno
string
A string codificada em hexadecimal maiúsculo.
-
hex_decode
Item
Tipo
Descrição
Parâmetro
string
A string hexadecimal a ser decodificada.
Valor de retorno
string
A string original decodificada. Retorna uma string vazia "" se a entrada for inválida.
-- DEADBEEF --
local data1 = aliwaf.util.hex_encode(string.char(0xDE, 0xAD, 0xBE, 0xEF))
-- \xDE\xAD\xBE\xEF --
local data2 = aliwaf.util.hex_decode('DEADBEEF')
Codificação e decodificação Base64
-
base64_encode
Item
Tipo
Descrição
Parâmetro
string
A string original a ser codificada.
Valor de retorno
string
A string codificada em Base64.
-
base64_decode
Item
Tipo
Descrição
Parâmetro
string
A string Base64 a ser decodificada.
Valor de retorno
string
A string original decodificada. Retorna uma string vazia "" se a entrada for inválida.
-- aGVsbG8= --
local data1 = aliwaf.util.base64_encode('hello')
-- hello --
local data2 = aliwaf.util.base64_decode('aGVsbG8=')
MD5/CRC/SHA
-
md5
Item
Tipo
Descrição
Parâmetro
string
A string original para gerar o hash.
Valor de retorno
string
O resumo MD5 em formato hexadecimal minúsculo de 32 caracteres.
-
sha256
Item
Tipo
Descrição
Parâmetro
string
A string original para gerar o hash.
Valor de retorno
string
O resumo SHA-256 em formato hexadecimal minúsculo de 64 caracteres.
-
crc32
Item
Tipo
Descrição
Parâmetro
string
A string original para cálculo.
Valor de retorno
integer
O checksum CRC32 (inteiro de 32 bits sem sinal).
-- 5d41402abc4b2a76b9719d911017c592 --
local md5 = aliwaf.util.md5('hello')
-- 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 --
local sha = aliwaf.util.sha256('hello')
-- 3287646509 --
local crc = aliwaf.util.crc32('hello')
Criptografia e descriptografia (AES/DES)
-
evp_encrypt
Item
Tipo
Descrição
Parâmetro 1
string
O tipo de algoritmo de criptografia, como "aes-128-cbc".
Parâmetro 2
string
A chave de criptografia (string segura para binários).
Parâmetro 3
string
O vetor de inicialização. Pode ser uma string vazia "" se o IV não for utilizado.
Parâmetro 4
string
O texto simples a ser criptografado.
Valor de retorno
string
O texto cifrado criptografado. Retorna uma string vazia "" se os parâmetros forem inválidos ou se a criptografia falhar.
-
evp_decrypt
Item
Tipo
Descrição
Parâmetro 1
string
O tipo de algoritmo de descriptografia. Deve corresponder ao algoritmo usado na criptografia, como "aes-128-cbc".
Parâmetro 2
string
A chave de descriptografia. Deve corresponder à chave usada na criptografia.
Parâmetro 3
string
O vetor de inicialização. Deve corresponder ao IV usado na criptografia. Pode ser uma string vazia "".
Parâmetro 4
string
O texto cifrado a ser descriptografado.
Valor de retorno
string
O texto simples descriptografado. Retorna uma string vazia "" se os parâmetros forem inválidos ou se a descriptografia falhar.
local data1 = aliwaf.util.evp_encrypt('aes-128-cbc', 'key-12345678-key', 'iv-1234567890-iv', 'hello')
local data2 = aliwaf.util.evp_decrypt('aes-128-cbc', 'key-12345678-key', 'iv-1234567890-iv', data1)
Assinatura e verificação (ES256)
-
es256_sign
Item
Tipo
Descrição
Parâmetro 1
string
A chave privada ES256 no formato PEM.
Parâmetro 2
string
Os dados originais a serem assinados.
Valor de retorno
string
O resultado da assinatura (string binária). Retorna uma string vazia "" se os parâmetros forem inválidos ou se a assinatura falhar.
-
es256_verify
Item
Tipo
Descrição
Parâmetro 1
string
A chave pública ES256 no formato PEM.
Parâmetro 2
string
Os dados originais usados para assinatura (devem corresponder aos dados usados durante a assinatura).
Parâmetro 3
string
O valor da assinatura a ser verificado (gerado por es256_sign).
Valor de retorno
boolean
true indica que a verificação da assinatura foi aprovada. false indica falha na verificação ou parâmetros inválidos.
local sign = aliwaf.util.es256_sign('private_key-1234', 'hello')
local result = aliwaf.util.es256_verify('public_key-12345', 'hello', sign)
Tempo
|
Item |
Tipo |
Descrição |
|
Parâmetro |
- |
- |
|
Valor de retorno |
integer |
O timestamp UNIX atual em milissegundos. |
-- Current millisecond-level timestamp (integer) --
local timestamp = aliwaf.util.get_current_ms()
Funções auxiliares de negócio
As funções auxiliares de negócio coordenam a interação entre os scripts Lua e o framework do WAF.
Ação
|
Item |
Tipo |
Descrição |
|
Parâmetro |
- |
- |
|
Valor de retorno |
- |
- |
-- Take action on the current request based on the pre-selected action --
aliwaf.func.punish()