Scripts personnalisés
Les scripts personnalisés peuvent dynamiser votre examen DAST. Vous pouvez ajouter des JavaScripts pour manipuler les requêtes ou les réponses HTTP au cours d'un examen. Cette manipulation peut être effectuée avant l'envoi d'une requête au serveur ou après la réception d'une réponse.
Activer des scripts personnalisés pour AppScan
Les scripts personnalisés sont activés par défaut (le paramètre CustomScripts.Enable est défini sur True).
Pour désactiver les scripts :
- Allez dans Outils > Options > onglet Avancé.
- Réglez le paramètre CustomScripts.Enable sur « False ».
Ajouter et activer des scripts personnalisés pour les examens DAST
- Accédez à l'option Scripts personnalisés dans la section Avancé des paramètres de configuration.
- Cliquez sur le bouton + Ajouter.
- Le champ Nom est prérempli avec la date et l'heure de création du script. Vous pouvez modifier le nom si nécessaire.
- Dans la liste déroulante Contexte d'exécution, sélectionnez Avant la requête ou Après la réponse en fonction du moment où vous souhaitez que le script s'exécute.
- Dans le champ JavaScript, saisissez votre code
JavaScript. Pour recevoir des suggestions de code JavaScript dans
l'environnement AppScan, appuyez sur Ctrl+Espace.
Assurez-vous que votre code ne contient pas d'erreurs de syntaxe et qu'il est compatible avec la version de JavaScript prise en charge par AppScan. Pour plus d'informations sur les règles et la façon d'écrire le code, voir Code JavaScript.
Exemple 1 : ajoutez automatiquement des détails de connexion à vos requêtes (sans utiliser la configuration de la gestion des connexions).
// Before each request if(request.method == "POST") { request.body = JSON.stringify({ "username": "jsmith", "password": "demo1234" }) }
Exemple 2 : vérifiez si la réponse inclut une clé API et stockez-la dans les variables globales.
// After each response try { var result = JSON.parse(response.body) log(`parsing: ${JSON.parse(response.body).Authorization}`) if(result.Authorization) { environment.globalVariables.addOrUpdate("Authorization", result.Authorization) log(`key = ${result.Authorization}`) } } catch (error) { log(error) }Exemple 3 : définissez la clé d'API d'autorisation sur l'en-tête s'il existe.
// Before each request var authorization = environment.globalVariables.get("Authorization") if(authorization) { request.headers.set("Authorization", authorization) log(`authorization is ${authorization}`) }
- Cliquez sur Ajouter pour enregistrer votre script. Le script est ajouté à la liste et activé par défaut.Remarque : Les scripts que vous ajoutez sont exécutés pour chaque requête ou réponse HTTP au cours de l'examen DAST.Utilisez cette fonction à bon escient pour améliorer l'efficacité de vos examens. Testez toujours vos scripts dans un environnement contrôlé avant de les déployer dans un examen réel afin d'éviter tout comportement ou résultat inattendu.
- 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.
- Vous pouvez modifier, supprimer ou changer l'ordre d'exécution des scripts. Dans le coin droit du script, cliquez sur
et sélectionnez l'option comme suit :- Modifier
- Supprimer
- Déplacer vers le haut
- Déplacer vers le bas
- 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.Remarque : Lorsque vous exportez des scripts personnalisés dans un modèle, ils sont cryptés par défaut. Pour désactiver manuellement ce chiffrement, dans les paramètres de configuration des examens, accédez à Configuration avancée et définissez le champ Général : Chiffrer les données sensibles sur False.
Code JavaScript
Contexte
Requête : Vous pouvez lire ou modifier les données de la requête avant qu'elles ne soient envoyées au serveur. Chaque requête est représentée par un objet requête, qui possède les propriétés suivantes :- En-têtes : Contient tous les en-têtes de la requête. Vous pouvez ajouter, supprimer ou modifier n'importe quel en-tête, à l'exception des en-têtes par défaut.
// Add header request.headers.add(key, value)
// Override header if exist request.headers.set(key, value)
Remarque : L'utilisation de « Ajouter » au lieu de « Définir » peut entraîner plusieurs instances de l'en-tête dans la requête. Par conséquent, « Définir » est préférable à « Ajouter ».// Remove header request.headers.remove(key)
// Modify header request.headers[key]
// Examples request.headers.add("Authorization", "MyCoolApiKey") request.headers.set("Authorization", "SecondApiKey") request.headers.remove("Authorization") request.headers['Authorization'] = "myapikey3"
En-têtes par défaut (non sensibles à la casse) : elles sont en lecture seule et ne peuvent pas être modifées.- Hôte : Identifie l'hôte auquel la requête est envoyée.
- Content-Length : Calcule la taille de la requête et envoie cette information au serveur.
- Corps : Contient des informations sur le corps de la requête. Le corps est de type « string ».
// Access body request.body
// Example request.body = "{ "username":"user" }"
- Chemin : Contient des informations sur le nœud final auquel la requête est destinée. Le format du nœud final exclut l'URL de base (par exemple :
/api/v1/test). Cette propriété est en lecture seule ; elle reste la même que lorsqu'elle a été définie pour la première fois, même si vous tentez de la modifier avant d'exécuter le script.// Access url path request.path
// Example if (request.path.startsWith("api/v1/test")) - Requête : Contient la chaîne de requête et les paramètres (s'il y en a) pour la requête en cours. Vous pouvez ajouter ou supprimer des paramètres de requête de cet objet. Chaque valeur est traitée comme un objet unique, comme « key=value ». Lorsque vous utilisez « getQueryString », vous obtenez une chaîne dont tous les éléments sont concaténés par un signe « & ». Cette chaîne est une copie des éléments, donc si vous changez la chaîne, vous ne changez qu'une copie de la requête.Remarque : Si le paramètre de requête est vide, AppScan n'enverra pas le délimiteur de requête (« ? »)
// Retrieve the current query string request.query.getQueryString()
// Example // Add new value (or update existing one) request.query.addOrUpdate("appscan","appscanvalue")
// Check if value exist request.query.contains("appscan") // for key only check request.query.contains("appscan=appscanvalue") // for key and value check
// Remove an item request.query.remove("appscan") // for key only check request.query.remove("appscan=appscanvalue") // for key and value check request.query.clear() // remove all values
- Méthode : Méthode de la requête (par exemple GET/POST/etc). Cette propriété est en lecture seule ; elle reste la même que lorsqu'elle a été définie pour la première fois, même si vous tentez de la modifier avant d'exécuter le script.
// Access to the method request.method
// Example if (request.method == "GET")
- Corps : Contient le corps de la réponse à la requête. La réponse est au format chaîne, vous devez donc la convertir manuellement si nécessaire (en JSON par exemple).
// Access body response.body
// Example let json = JSON.parse(config.response)
- Chemin : Contient des informations sur le nœud final de la réponse.
// Access to the relative url response.path
// Example if (response.path.startsWith("api/v1/test")) - Statut : Stocke des détails sur l'état de la réponse. L'état est un objet doté des propriétés suivantes :
// Access status response.status.statusCode // A numeric representation of the status response.status.statusDescription // The description of the status code response.status.statusLine //the whole status line including the http version
// Example if (response.status.statusCode == 200) // check only the number if (response.status.statusDescription == "OK") // Check only the description if (response.status.statusLine == "HTTP1.1 200 OK") // Full line
- En-têtes : Contient tous les en-têtes de la réponse. Vous pouvez ajouter, supprimer ou modifier n'importe quel en-tête, à l'exception des en-têtes par défaut.
// Add header response.headers.add(key, value)
// Override header if exist response.headers.set(key, value)
// Remove header response.headers.remove(key)
// Modify header response.headers[key]
// Examples response.headers.add("Authorization", "MyCoolApiKey") response.headers.set("Authorization", "SecondApiKey") response.headers.remove("Authorization") response.headers['Authorization'] = "myapikey3"
- ParentRequest : Objet contenant la requête envoyée avant la réponse. Les données de requête sont en lecture seule. La requête possède toutes les propriétés de l'objet requête défini précédemment.
// Example response.request.path //- access to the path from the request
Données d'environnement
Un objet de données à court terme stocke des informations importantes 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 exécutez un test manuel.
- 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.
Ces données sont effacées à chaque fois qu'un nouvel examen ou un réexamen est effectué.
// Add data to the globals or update existing one environment.globalVariables.addOrUpdate(key, value)
// Remove key data from the globals environment.globalVariables.remove(key)
// Read data - retrieves the value for the current key (without removing it) environment.globalVariables.get(key)
- Statut de l'examen : Contient des informations sur l'examen en cours.
// determine if the current phase is explore phase environment.status.isInExplore()
// determine if the current phase is test phase environment.status.isInTest()
Logging
Active les fonctions de journalisation dans le script pour aider au débogage et à l'identification des problèmes. La commande « console.log » ne fonctionne pas ici. Utilisez plutôt le mot « log » suivi d'un message entre guillemets. De plus, s'il y a une erreur pendant le fonctionnement du moteur qui n'est pas liée à la syntaxe ou à l'utilisation de JavaScript, cette erreur est enregistrée dans le journal de suivi du moteur.
// Log message to file log("my cool logging") // Log message with custom source log("message", "my-cool-source")
Contraintes
- eval
- Fonction (constructeur)
- setTimeout
- setInterval
Gestion des erreurs
Si le script utilise des fonctions restreintes et rencontre une erreur ou une exception, il cesse de fonctionner. Cet échec interrompt l'examen en cours et les détails de l'erreur sont enregistrés dans le fichier « UserScript.log » pour un examen plus approfondi.
Chargement d'un modèle configuré avec des scripts
Vous pouvez lancer un examen en chargeant un modèle configuré avec des scripts activés. Un modèle type, préconfiguré avec des scripts pour le fichier de description demo.testfire, est disponible à l'adresse Program Files (x86)\HCL\AppScan Standard\Templates.
Versions JavaScript prises en charge par AppScan
- ES6 (2015)
- Générateurs
- Appels résiduels
- ES8 (2017)
- Mémoire partagée et opérations atomiques
- ES15 (2024)
- Atomics.waitAsync
- Balise d'expression régulière \v