Scripts personnalisés
Les scripts personnalisés dynamisent vos examens DAST. Vous pouvez ajouter du JavaScript pour manipuler les requêtes et les réponses HTTP pendant un examen, soit avant l'envoi d'un requête au serveur, soit après la réception d'une réponse.
Présentation
Les scripts personnalisés s'exécutent dans AppScan et fonctionnent sur des modèles de demande et de réponse en mémoire, ce qui vous permet d'ajuster les demandes par programmation et d'inspecter les réponses sans créer d'extension ou utiliser de proxy.
En un coup d'œil :
Avant la requête : Exécute un script pour modifier une requête HTTP avant de l'envoyer à votre application (ajout/suppression d'en-têtes, chiffrement de données, gestion des jetons, etc.).
Après la réponse : Traitez la réponse HTTP après qu'elle a été reçue de votre application (déchiffrer le contenu, extraire les valeurs, etc.).
Paramètre : Générez des valeurs pour les Opérations en plusieurs étapes et le Remplissage de formulaire en utilisant JavaScript uniquement.
Utilisez cette fonction à bon escient pour améliorer l'efficacité de vos examens. Testez vos scripts dans un environnement contrôlé avant tout déploiement dans l'environnement actif pour vous assurer qu'ils fonctionnent comme prévu.
Exemple de chemin de modèle : C:\Program Files (x86)\HCL\AppScan Standard\Templates.
Exemples de scripts personnalisés : Référentiel GitHub.
Ajout de scripts personnalisés
- Sélectionnez Scripts personnalisés dans la section Avancé des paramètres de configuration.
- Cliquez sur le bouton + Ajouter.
- Modifiez le champ Nom prérempli si nécessaire.
- Choisissez le Contexte d'exécution approprié pour votre script : :
- Avant la requête pour que les scripts soient exécutés avant l'envoi des requêtes.
- Après la réponse pour que les scripts soient exécutés après la réception des réponses.
- Paramètre pour les tâches qui impliquent plusieurs étapes ou le remplissage de formulaires. Vous pouvez utiliser ce contexte en conjonction avec la méthode
setResultValuepour permettre aux scripts de renvoyer les résultats à AppScan.
- Saisissez votre JavaScript dans le champ JavaScript (éditeur de code) et utilisez Ctrl+espace pour obtenir des suggestions automatiques dans l'environnement AppScan.
- Cliquez sur Ajouter pour enregistrer votre script. Le script est ajouté à la liste et activé par défaut.
- Vous pouvez choisir d'activer ou de désactiver un script de la liste des scripts personnalisés à l'aide de la case à cocher Activer.
- Gérez vos scripts en utilisant la case à cocher Activer ou en modifiant, en supprimant ou en réorganisant les scripts dans la liste de scripts.

- Cliquez sur Démarrer un examen complet pour démarrer l'examen.
- Résultat : Les scripts activés sont exécutés pour chaque requête ou réponse. Vous pouvez consulter les détails des scripts dans Données > onglet Requêtes > Requête/Réponse.
Vérifiez l'exactitude syntaxique et la compatibilité de votre script avec la version JavaScript prise en charge dans AppScan. Pour obtenir des instructions détaillées, reportez-vous à la section Code JavaScript.
Remarque :- Les scripts personnalisés sont enregistrés dans le fichier de configuration des examens et peuvent être exportés avec un modèle. Ils ne sont pas inclus dans les résultats de l'examen.
- Par défaut, les scripts personnalisés sont chiffrés lorsqu'ils sont exportés dans un modèle. Pour désactiver le chiffrement, définissez le paramètre Général : Chiffrer les données sensibles sur False dans la configuration des examens.
Activation des scripts personnalisés
Les scripts personnalisés sont activés par défaut et s'exécutent avec chaque requête et réponse HTTP pendant l'enregistrement et l'examen.
Pour désactiver l'exécution du script, accédez à Outils > Options > onglet Avancé et définissez le paramètre CustomScripts.Enable sur « False ».
Contextes d'exécution
Avant la requête
But : Mutez les requêtes HTTP sortantes.
// Attach Authorization from stored global variable var token = environment.globalVariables.get("Authorization"); if (token) request.headers.set("Authorization", token);
Après la réponse
But : Inspectez les réponses et les valeurs persistantes.
// Capture token from JSON response and store it for reuse
try {
var result = JSON.parse(response.body);
if (result && result.Authorization) {
environment.globalVariables.addOrUpdate("Authorization", result.Authorization);
}
} catch(e) { log(e); }Paramètre
- Aucun objet de données (requête ou réponse) n'est disponible dans ce contexte ; leur utilisation renvoie une valeur nulle.
- Renvoie les valeurs avec setResultValue(value).
Dans le remplissage de formulaire, lorsque vous sélectionnez Source de valeur > Script personnalisé, la liste affiche uniquement les scripts dont le contexte d'exécution est Paramètre.
// Example: Return a unique email for registration flows
function random(n) { return Math.random().toString(36).slice(2, 2+n); }
var email = "test_" + Date.now() + "_" + random(6) + "@example.test";
setResultValue(email);Référence d'API
// Examples: // Handle headers request.headers.set("Authorization", "Bearer"); request.headers.add("X-Trace", "abc"); // Manipulate body request.body = JSON.stringify( { user:"admin" }); if(request.body.includes("admin") { ... } // Read path if (request.path.startsWith("/api/v1")) { ... } // Edit query request.query.addOrUpdate("lang","en") request.query.remove("debug") request.query.getQueryString() // Read method if (request.method == "GET") { ... }
// Examples: // Handle headers response.headers.set("Authorization", "Bearer"); response.headers.add("X-Trace", "abc"); // Read body (since it's read only) var j = JSON.parse(response.body); // Read path if (response.path.startsWith("/api/v1")) { ... } // Read response if (response.status.statusCode == 200) { ... } // Read parent request if (response.request.path.startsWith("/api/v1")) { ... }Contexte Paramètre - API complète
// Update the result back to AppScan
setResultValue("ABC-" + Date.now());Données d'environnement
Les données à court terme sont disponibles uniquement jusqu'à la fin de la tâche, par exemple lorsque vous mettez en pause, arrêtez ou terminez un examen, que vous vous connectez ou que vous terminez un test manuel. Elles sont effacées au début de chaque nouvel examen ou réexamen.
- Variable globale : Les données des variables globales sont une structure de données clé-valeur conçue pour stocker des paires de données spécifiques à l'utilisateur. Les clés sont uniques (c'est-à-dire que deux éléments ne peuvent pas avoir la même clé, bien que plusieurs éléments puissent partager la même valeur), ce qui est utile pour partager des données entre des scripts en cours d'exécution.
- Statut de l'examen : Contient des informations sur l'examen en cours.
// Check the status of the scan environment.status.isInExplore(); environment.status.isInTest();
Journalisation - API complète
Active la journalisation dans votre script pour aider au débogage et au dépannage. La commande console.log standard n'est pas prise en charge dans cet environnement. Utilisez plutôt la fonction log avec un message entre guillemets, par exemple : log("Your message here"). Si une erreur d'exécution se produit pendant le fonctionnement du moteur qui n'est pas liée à la syntaxe ou à l'utilisation de JavaScript, elle est enregistrée dans le journal de suivi du moteur pour une analyse plus approfondie.
Les journaux sont écrits dans le fichier UserScript.log du dossier de journalisation AppScan.
Par défaut, il s'agit du dossier [UserDataFolder]\AppData\Roaming\HCL\AppScan Standard\logs.
Contraintes et limites d'exécution
- Fonctions restreintes :
eval, Function (constructor), setTimeout, setlnterval. Si l'une d'entre elles est utilisée, le script échoue. - Limites : Durée d'exécution maximale : 5 secondes ; limite de mémoire : 64 Mo. Le dépassement de ces limites entraîne l'échec du script.
En cas d'échec, l'examen s'interrompt et les détails sont enregistrés dans UserScript.log.
Versions JavaScript prises en charge
- ES6 : Générateurs, appels résiduels
- ES8 : Mémoire partagée et opérations atomiques
- ES15 : Atomics.waitAsync, indicateur d'expressions régulières \v
Objets disponibles dans la saisie semi-automatique
Ces objets apparaissent dans les suggestions de saisie semi-automatique de l'éditeur de script, ce qui facilite leur recherche et leur utilisation :
- Mot-clé
- Tableau
- Date
- Objet
- Chaîne
- RegExp
- JSON
- Map
- Math
Ces objets sont entièrement pris en charge par le moteur de script, mais n'apparaissent pas dans les listes de saisie semi-automatique. Vous pouvez toujours les utiliser en saisissant leur nom directement dans l'éditeur :
- ArrayBuffer
- BigInt
- Booléen
- DataView
- Erreur
- Iterator
- Nombre
- Promise
- Proxy
- Reflect
- SharedArrayBuffer
- Symbole
-
TypedArray
-
WeakMap
-
WeakRef
-
WeakSet
Remarque : « Pas dans la saisie semi-automatique » signifie que l'éditeur ne suggère pas ces éléments automatiquement. Cependant, les objets sont implémentés et se comportent exactement comme dans JavaScript standard.
Résolution des problèmes
- Échecs de script : Vérifiez le dossier des journaux (par défaut : [UserDataFolder]\AppData\Roaming\HCL\AppScan Standard\logs) pour plus de détails sur l'erreur. Si vous rencontrez une exception non gérée, entourez votre code d'un bloc try...catch pour la gérer de manière appropriée.
- Script non exécuté : Assurez-vous que le script est activé dans les paramètres de configuration.
Si le problème est lié à la connexion/l'autorisation, envisagez de supprimer la valeur de négociation dans Configuration→ Configuration avancée → Ordre du package de sécurité pour empêcher AppScan de gérer ces authentifications automatiquement.
API Requête complète
| Membre | Type | Description | Exemple |
|---|---|---|---|
| en-têtes | objet | Un objet encapsulant les en-têtes de la requête HTTP en cours, fournissant des méthodes pour ajouter, mettre à jour, récupérer ou supprimer des en-têtes de manière dynamique, ce qui permet un contrôle précis des métadonnées de la requête. | request.headers.set("Authorization","Bearer ...") |
| corps | chaîne | Le corps de la requête HTTP en cours. | request.body = JSON.stringify({ user:"jsmith" }) |
| chemin | chaîne |
Lecture seule🔒 Le chemin relatif de la requête HTTP en cours. |
if (request.path.startsWith("/api/v1/")) { ... } |
| query | objet | Un objet qui contient différentes méthodes pour ajouter, mettre à jour ou supprimer des paramètres de requête dans la requête HTTP en cours, ce qui permet une manipulation dynamique de la chaîne de requête. | request.query.addOrUpdate("lang","en") request.query.remove("debug") |
| méthode | chaîne |
Lecture seule🔒 La méthode de la requête HTTP actuelle. |
if (request.method == "GET") {{ ... }} |
| Membre | Type | Description | Exemple |
|---|---|---|---|
|
(nom : chaîne, valeur : chaîne) |
vide | Ajoute une nouvelle valeur à la chaîne de requête ou met à jour une valeur existante. | request.query.addOrUpdate("appscan","appscanvalue") |
getQueryString() |
chaîne |
Renvoie la chaîne de requête complète de la requête HTTP en cours, y compris tous les paramètres et leurs valeurs. |
request.query.getQueryString() |
|
(nom : chaîne) |
booléen |
Vérifie si un paramètre de requête spécifique existe dans la requête HTTP en cours. Renvoie true si le paramètre existe, false sinon. |
request.query.contains("lang") |
|
(nom : chaîne) |
booléen |
Supprime un paramètre de requête spécifique de la requête HTTP en cours. Renvoie true si le paramètre a été supprimé, false si ce n'est pas le cas. |
request.query.remove("lang") |
clear() |
vide |
Supprime tous les paramètres de requête de la requête HTTP en cours. |
request.query.clear() |
API Réponse complète
| Membre | Type | Description | Exemple |
|---|---|---|---|
| en-têtes | objet | Un objet encapsulant les en-têtes de la réponse HTTP en cours, fournissant des méthodes pour ajouter, mettre à jour, récupérer ou supprimer des en-têtes de manière dynamique, permettant un contrôle précis des métadonnées de la réponse. | response.headers.set("Authorization","Bearer ...") |
| corps | chaîne | Le corps de la réponse HTTP en cours. | response.body = JSON.stringify({ user:"jsmith" }) |
| chemin | chaîne |
Lecture seule🔒 Le chemin relatif de la réponse HTTP en cours. |
if (response.path.startsWith("/api/v1/")) { ... } |
| status | objet | Un objet représentant l'état de la réponse HTTP en cours, y compris les propriétés du code d'état et du message d'état. | if (response.status.code == 200) { ... } |
| demande | objet | Un objet représentant la requête à l'origine de la réponse. Les données de requête sont en lecture seule et incluent toutes les propriétés définies dans l'objet de requête décrit précédemment. | if (response.request.path) { ... } |
| Membre | Type | Description | Exemple |
|---|---|---|---|
| statusCode | nombre |
Lecture seule🔒 Le code de statut HTTP de la réponse en cours. |
response.status.statusCode = 200 |
| statusDescription | chaîne |
Lecture seule🔒 Le message de statut HTTP de la réponse en cours. |
response.status.statusDescription = "OK" |
| statusLine | chaîne |
Lecture seule🔒 La ligne de statut HTTP de la réponse en cours. |
response.status.statusLine = "HTTP/1.1 200 OK" |
API Paramètre complète
| Membre | Type | Description | Exemple |
|---|---|---|---|
|
(valeur : chaîne) |
vide | Définit la valeur de résultat pour le script de contexte de paramètre en cours. | setResultValue("ABC-" + Date.now()) |
Objets communs
| Membre | Type | Description | Exemple |
|---|---|---|---|
| éléments | tableau |
Lecture seule🔒 Un tableau de tous les en-têtes de la requête HTTP en cours. |
|
| Membre | Type | Description | Exemple |
|---|---|---|---|
add(nom : chaîne, valeur : chaîne) |
vide |
Ajoute un nouvel en-tête à la requête HTTP en cours. Si un en-tête avec le même nom et la même valeur existe déjà, il ne sera pas ajouté à nouveau. |
|
set(nom : chaîne, valeur : chaîne) |
vide | Définit un en-tête dans la requête HTTP en cours. Si l'en-tête existe déjà, sa valeur est remplacée. |
|
|
(nom : chaîne) |
vide | Supprime un en-tête de la requête HTTP en cours. | request.headers.remove("Authorization")response.headers.remove("Authorization") |
| [nom : chaîne] | chaîne | Récupère la valeur d'un en-tête spécifique par son nom. Renvoie une valeur nulle si l'en-tête n'existe pas. |
|
Données d'environnement
| Membre | Type | Description | Exemple |
|---|---|---|---|
| globalVariables | objet | Une structure de données clé-valeur pour le stockage de paires de données spécifiques à l'utilisateur. Les clés doivent être uniques, ce qui garantit l'absence de doublons, tandis que les valeurs peuvent être partagées entre plusieurs clés. Cette structure facilite le partage des données entre les scripts en cours d'exécution. | environment.globalVariables.addOrUpdate(key, value) |
| status | objet | Informations sur le statut actuel de l'examen. | environment.status.isInExplore() |
| Membre | Type | Description | Exemple |
|---|---|---|---|
|
(clé : chaîne, valeur : chaîne) |
vide | Ajoute une nouvelle paire clé-valeur aux variables globales ou met à jour la valeur d'une clé existante. | environment.globalVariables.addOrUpdate("mycoolkey", "testValue") |
|
(clé : chaîne) |
booléen | Supprime une paire clé-valeur des variables globales. Renvoie true si la clé a été trouvée et supprimée, sinon false. | environment.globalVariables.remove("mycoolkey") |
get(clé : chaîne) |
chaîne | Récupère la valeur d'une clé spécifique à partir des variables globales. Renvoie une chaîne vide si la clé n'existe pas. | environment.globalVariables.get("mycoolkey") |
| Méthode | Type | Description | Exemple |
|---|---|---|---|
isInExplore() |
booléen | Vérifie si l'examen est actuellement en phase d'exploration. | environment.status.isInExplore() |
isInTest() |
booléen | Vérifie si l'examen est actuellement en phase de test. | environment.status.isInTest() |
Journalisation
| Membre | Type | Description | Exemple |
|---|---|---|---|
log(message: string) log(message: string, source: string) |
vide | Ajoute une nouvelle entrée de journal avec le message spécifié et la source facultative. | log("This is a log message")
|