Rédigez des scripts Lua personnalisés pour intercepter et modifier le traitement des requêtes web. Cette fonctionnalité permet d'appliquer une logique de sécurité allant au-delà des règles intégrées de WAF. Grâce à des scripts et des paramètres configurables, vous répondez avec plus de flexibilité aux exigences métier complexes et spécifiques.
Activer la fonctionnalité Extensions
Pour utiliser les extensions, suivez les étapes d'activation ci-dessous :
Éditions applicables : Seules les éditions WAF Enterprise Edition, Ultimate Edition (abonnement) et Pay-As-You-Go Edition prennent en charge cette fonctionnalité.
Facturation : Ce service est payant. Le mode de facturation est le suivant :
Pay-As-You-Go Edition : L'utilisation est immédiate, sans achat préalable. Des frais supplémentaires s'appliquent en fonction de la consommation réelle.
Subscription Edition : Vous devez acquérir la fonctionnalité avant de pouvoir l'utiliser.
Connectez-vous à la console Web Application Firewall 3.0. Dans la barre de menu supérieure, sélectionnez le groupe de ressources et la région (Chinese Mainland ou Outside Chinese Mainland) correspondant à votre instance WAF.
Dans le volet de navigation de gauche, choisissez .
Cliquez sur Buy Now et suivez les instructions à l'écran pour activer la fonctionnalité.
Créer une extension
Sur la page Extensions, cliquez sur Create Extension, puis configurez les paramètres suivants.
Basic Info : Saisissez un explicite ainsi qu'une Plugin Description.
-
Plugin Code : Rédigez ici le script Lua implémentant votre logique de sécurité personnalisée. Exemple : Pour plus d'informations sur l'API, consultez la section Annexe : Référence de l'API des scripts Lua personnalisés.
-- 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() endImportantAfin de garantir la stabilité du système WAF, le temps d'exécution d'un script Lua par requête est limité à 2 ms. Lors de la phase de Debug and Test, tout dépassement de cette limite entraîne l'échec du test et bloque la création. En production, si l'exécution d'un script excède 2 ms pour une requête donnée, le système ignore cette exécution.
Évitez d'inclure en dur des informations sensibles (telles que des clés) dans votre code. Utilisez plutôt la fonctionnalité Parameter Definition décrite ci-dessous.
-
Parameter Definition : Extrayez les valeurs codées en dur des scripts vers des paramètres configurables afin de découpler la logique des données. Cela permet d'ajuster dynamiquement les politiques sans modifier le code et de gérer les clés de manière sécurisée. Cliquez sur Add Parameter et complétez la configuration suivante :
Parameter Name : Nom de la variable référencée dans le script (par exemple,
secret_key).Parameter Type : Les types pris en charge incluent String, Number, Boolean, JSON Object et JSON Array. Assurez-vous que le type correspond à la logique de traitement de votre script.
Parameter Description : Décrit l'objectif du paramètre.
-
Parameter Value : Deux modes sont disponibles :
Manual Input : Saisissez la valeur directement.
-
Use KMS Credential : Référencez un identifiant déjà créé dans Key Management Service pour stocker les données sensibles en toute sécurité. Pour que WAF puisse référencer correctement cet identifiant, vous devez lui attacher le tag suivant :
Tag Key :
waf:access:enableTag Value :
true
-
Debug and Test :
Plugin Action Parameters : Seul le mode Block est actuellement pris en charge ; il bloque la requête.
-
Traffic Parameters : Simule un trafic de requête HTTP réel. Cliquez sur Add Parameter, puis saisissez un Parameter Name (tel que
method,uriouargs) ainsi que sa Parameter Value correspondante.Exemple : Définissez
methodsurPOSTeturisur/loginpour tester la logique de protection d'un endpoint de connexion.
Execution Result : Cliquez sur Run and Debug. Le système exécute le script sur le trafic simulé. Consultez ensuite le panneau Execution Result situé à droite. En cas d'échec, corrigez le code en vous basant sur les messages d'erreur spécifiques.
Étapes suivantes
Une fois l'extension créée, vous devez la référencer dans un modèle de protection Custom Rule. Pour plus d'informations, consultez la rubrique Règles personnalisées.
Opérations courantes
La page Extensions permet d'effectuer les opérations suivantes :
Consulter la liste des plugins : Affiche toutes les extensions. Utilisez le champ de recherche pour saisir un nom de plugin et le retrouver rapidement.
Voir les règles de protection associées : Repérez le plugin cible et cliquez sur l'icône
dans la colonne Associated Rules pour afficher les ID des règles de protection associées. Copiez un ID pour le rechercher sur la page Core Web Protection ou Security Reports.Modifier une extension : Localisez le plugin concerné et cliquez sur Edit dans la colonne Actions pour ajuster sa configuration.
Supprimer une extension : Identifiez le plugin souhaité et cliquez sur Delete dans la colonne Actions pour retirer l'extension.
Annexe : Référence de l'API des scripts Lua personnalisés
Interfaces principales pour les scripts Lua personnalisés, couvrant la lecture des données de requête, le chiffrement et le déchiffrement, ainsi que le contrôle du flux de requêtes.
Exemple de requête 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=
Lecture des données de requête
Toutes les interfaces renvoient une chaîne de caractères. Si un champ n'existe pas, une chaîne vide est retournée.
Lire la méthode
|
Item |
Type |
Description |
|
Parameter |
- |
- |
|
Return value |
string |
Méthode de la requête HTTP, telle que « GET » ou « POST ». |
-- POST --
local method = aliwaf.req.get_method()
Lire l'URI
|
Item |
Type |
Description |
|
Parameter |
- |
- |
|
Return value |
string |
Chemin URI de la requête. |
-- /api/v1/orders --
local uri = aliwaf.req.get_uri()
Lire le domaine
|
Item |
Type |
Description |
|
Parameter |
- |
- |
|
Return value |
string |
Nom de domaine Host de la requête. |
-- shop.example.com --
local domain = aliwaf.req.get_domain()
Lire la chaîne de requête
|
Item |
Type |
Description |
|
Parameter |
- |
- |
|
Return value |
string |
Chaîne de requête complète. |
-- source=web&campaign=spring2024 --
local query = aliwaf.req.get_query()
Lire un paramètre de requête
|
Item |
Type |
Description |
|
Parameter |
string |
Nom du paramètre de requête. |
|
Return value |
string |
Valeur correspondante du paramètre. Renvoie une chaîne vide "" si le paramètre n'existe pas. |
-- web --
local source = aliwaf.req.get_arg('source')
Lire un cookie
|
Item |
Type |
Description |
|
Parameter |
string |
Nom du cookie. |
|
Return value |
string |
Valeur correspondante du cookie. Renvoie une chaîne vide "" si le cookie n'existe pas. |
-- abc123xyz --
local session_id = aliwaf.req.get_cookie('session_id')
Lire un en-tête
|
Item |
Type |
Description |
|
Parameter |
string |
Nom de l'en-tête de requête HTTP. |
|
Return value |
string |
Valeur correspondante de l'en-tête. Renvoie une chaîne vide "" si l'en-tête n'existe pas. |
-- Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx --
local auth = aliwaf.req.get_header('Authorization')
Lire le corps
Vérifier l'état du corps de la requête
-
Réception complète du corps
Item
Type
Description
Parameter
-
-
Return value
boolean
true indique que le corps de la requête a été entièrement reçu. false signifie que des données sont encore en attente.
local last = aliwaf.func.is_last_fragment_arrived() -
Troncature du corps
Item
Type
Description
Parameter
-
-
Return value
boolean
true signale que le corps de la requête a dépassé la limite et a été tronqué. false confirme que le corps est intact.
Par défaut, WAF conserve jusqu'à 128 Ko du corps de la requête. Les requêtes dépassant cette limite sont tronquées (la partie excédentaire est ignorée).
local discard = aliwaf.func.is_request_body_discarded()
Attendre le corps
Les corps de requête arrivent chez WAF en streaming. Il est donc possible que le corps ne soit pas encore totalement reçu lors de l'exécution du script. Pour traiter le corps complet, demandez explicitement au framework d'attendre la réception intégrale avant de réexécuter le script.
|
Item |
Type |
Description |
|
Parameter |
- |
- |
|
Return value |
- |
- |
aliwaf.func.wait_request_body()
Exemple : Lecture du corps de la requête
-- 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 --
Fonctions utilitaires courantes
Encodage et décodage de base
Les interfaces d'encodage et de décodage URL, hexadécimal et Base64 acceptent un paramètre de type chaîne et renvoient une chaîne traitée. En cas d'échec, elles retournent une chaîne vide.
Encodage et décodage URL
-
escape_uri
Item
Type
Description
Parameter
string
Chaîne brute à encoder.
Return value
string
Chaîne encodée.
-
unescape_uri
Item
Type
Description
Parameter
string
Chaîne encodée en URL à décoder.
Return value
string
Chaîne brute décodée.
-- a%20b --
local data1 = aliwaf.util.escape_uri('a b')
-- a b --
local data2 = aliwaf.util.unescape_uri('a%20b')
Encodage et décodage hexadécimal
-
hex_encode
Item
Type
Description
Parameter
string
Chaîne binaire à encoder.
Return value
string
Chaîne encodée en hexadécimal majuscule.
-
hex_decode
Item
Type
Description
Parameter
string
Chaîne hexadécimale à décoder.
Return value
string
Chaîne brute décodée. Renvoie une chaîne vide "" si l'entrée est invalide.
-- DEADBEEF --
local data1 = aliwaf.util.hex_encode(string.char(0xDE, 0xAD, 0xBE, 0xEF))
-- \xDE\xAD\xBE\xEF --
local data2 = aliwaf.util.hex_decode('DEADBEEF')
Encodage et décodage Base64
-
base64_encode
Item
Type
Description
Parameter
string
Chaîne brute à encoder.
Return value
string
Chaîne encodée en Base64.
-
base64_decode
Item
Type
Description
Parameter
string
Chaîne Base64 à décoder.
Return value
string
Chaîne brute décodée. Renvoie une chaîne vide "" si l'entrée est invalide.
-- aGVsbG8= --
local data1 = aliwaf.util.base64_encode('hello')
-- hello --
local data2 = aliwaf.util.base64_decode('aGVsbG8=')
MD5/CRC/SHA
-
md5
Item
Type
Description
Parameter
string
Chaîne brute à hacher.
Return value
string
Empreinte MD5 au format hexadécimal minuscule de 32 caractères.
-
sha256
Item
Type
Description
Parameter
string
Chaîne brute à hacher.
Return value
string
Empreinte SHA-256 au format hexadécimal minuscule de 64 caractères.
-
crc32
Item
Type
Description
Parameter
string
Chaîne brute à traiter.
Return value
integer
Somme de contrôle CRC32 (entier non signé 32 bits).
-- 5d41402abc4b2a76b9719d911017c592 --
local md5 = aliwaf.util.md5('hello')
-- 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 --
local sha = aliwaf.util.sha256('hello')
-- 3287646509 --
local crc = aliwaf.util.crc32('hello')
Chiffrement et déchiffrement (AES/DES)
-
evp_encrypt
Item
Type
Description
Parameter 1
string
Type d'algorithme de chiffrement, par exemple « aes-128-cbc ».
Parameter 2
string
Clé de chiffrement (chaîne sûre pour le binaire).
Parameter 3
string
Vecteur d'initialisation. Peut être une chaîne vide "" si aucun IV n'est utilisé.
Parameter 4
string
Texte en clair à chiffrer.
Return value
string
Texte chiffré résultant. Renvoie une chaîne vide "" si les paramètres sont invalides ou si le chiffrement échoue.
-
evp_decrypt
Item
Type
Description
Parameter 1
string
Type d'algorithme de déchiffrement. Doit correspondre à l'algorithme utilisé pour le chiffrement, par exemple « aes-128-cbc ».
Parameter 2
string
Clé de déchiffrement. Doit être identique à la clé utilisée pour le chiffrement.
Parameter 3
string
Vecteur d'initialisation. Doit correspondre à l'IV utilisé pour le chiffrement. Peut être une chaîne vide "".
Parameter 4
string
Texte chiffré à déchiffrer.
Return value
string
Texte en clair déchiffré. Renvoie une chaîne vide "" si les paramètres sont invalides ou si le déchiffrement échoue.
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)
Signature et vérification (ES256)
-
es256_sign
Item
Type
Description
Parameter 1
string
Clé privée ES256 au format PEM.
Parameter 2
string
Données brutes à signer.
Return value
string
Résultat de la signature (chaîne binaire). Renvoie une chaîne vide "" si les paramètres sont invalides ou si la signature échoue.
-
es256_verify
Item
Type
Description
Parameter 1
string
Clé publique ES256 au format PEM.
Parameter 2
string
Données brutes utilisées pour la signature (doivent correspondre aux données employées lors de la signature).
Parameter 3
string
Valeur de signature à vérifier (générée par es256_sign).
Return value
boolean
true indique que la vérification de la signature a réussi. false signale un échec de la vérification ou des paramètres invalides.
local sign = aliwaf.util.es256_sign('private_key-1234', 'hello')
local result = aliwaf.util.es256_verify('public_key-12345', 'hello', sign)
Temps
|
Item |
Type |
Description |
|
Parameter |
- |
- |
|
Return value |
integer |
Horodatage UNIX actuel en millisecondes. |
-- Current millisecond-level timestamp (integer) --
local timestamp = aliwaf.util.get_current_ms()
Fonctions d'aide métier
Les fonctions d'aide métier assurent la coordination entre les scripts Lua et le framework WAF.
Action
|
Item |
Type |
Description |
|
Parameter |
- |
- |
|
Return value |
- |
- |
-- Take action on the current request based on the pre-selected action --
aliwaf.func.punish()