API de sécurité pour les développeurs de Building Blocks
Blackboard a intégré une bibliothèque de sécurité open source basée sur les meilleures pratiques issue de l'API de sécurité d'entreprise (ESAPI) de l'Open Web Application Project (OWASP). Cette bibliothèque de sécurité est fournie par défaut et installée sur Blackboard via un Building Block appelé « Module de sécurité interface de programmation d'application » et est requise pour le fonctionnement du système. Blackboard recommande vivement à tous les développeurs de Building Block de tirer parti de cette nouvelle API de sécurité basée sur OWASP ESAPI pour Java et ESAPI pour JavaScript. Ces modifications de l'interface de programmation d'application de sécurité incluent non seulement la mise en œuvre des meilleures pratiques, mais facilitent également l'utilisation des méthodes grâce à une nomenclature cohérente.
Note
Dans les versions ultérieures, l'interface de programmation d'application Building Block du module de sécurité ESAPI fait partie du code de base de Blackboard et est disponible par défaut.
Dans le cadre des pratiques de codage sécurisé, les entrées susceptibles d'être influencées par les utilisateurs, qu'elles soient fiables ou non, doivent être validées côté serveur avant le traitement (validation des entrées) ainsi qu'avant l'affichage (validation des sorties ou échappement). Cela permet de garantir la résilience du système et d'éviter les problèmes de sécurité tels que les scripts intersites.
Validation des entrées
Lorsque vous recevez des informations provenant de la demande, validez toujours et validez toujours côté serveur. Blackboard a implémenté plusieurs cas d'utilisation courants nécessitant une validation. Quelques exemples sont fournis ci-dessous.
Blackboard.Platform.Security.ValidationUtility.IsValidDirectoryPath (chaîne)
Blackboard.Platform.Security.ValidationUtility.IsValidGUID (chaîne)
Blackboard.Platform.Security.ValidationUtility.IsValidEnumeratedType (Enum, String)
Validation/codage/échappement de sortie
Lorsque vous affichez une entrée, assurez-vous toujours qu'elle est affichée dans le contexte correct dans lequel elle sera intégrée :
Méthodes Java
Blackboard.Platform.Security.EscapeUtility.EscapeForHtml (chaîne de caractères)
Blackboard.Platform.Security.EscapeUtility.EscapeForHtmlAttribute (chaîne)
Blackboard.Platform.Security.EscapeUtility.EscapeForJavaScript (chaîne)
Blackboard.Platform.Security.EscapeUtility.EscapeForUrl (chaîne)
Blackboard.Platform.Security.EscapeUtility.EscapeForCSS (chaîne)
Blackboard.Platform.Security.EscapeUtility.EscapeForXML (chaîne)
Blackboard.Platform.Security.EscapeUtility.EscapeForXmlAttribute (chaîne)
Méthodes JSP
${bbNG:EscapeForHTML( String )}
${bbNG:EscapeForJavascript( String )}
${bbNG:EscapeForURL( String )}
${bbNG:EscapeForCSS( String )}
${bbNG:EscapeForXML( String )}
${bbNG:EscapeForXMLAttribute( String )}
méthodes JavaScript
Toutes les méthodes ESAPI pour JavaScript peuvent être utilisées. Liste des méthodes les plus couramment utilisées :
$ESAPI.encoder().canonicalize( String )
$ESAPI.encoder().encodeForHTML( String )
$ESAPI.encoder().encodeForHTMLAttribute( String )
$ESAPI.encoder().encodeForCSS( String )
$ESAPI.encoder().encodeForJavaScript( String )
$ESAPI.encoder().encodeForURL( String )
Déchiffrez le texte crypté
Déchiffrer le contexte chiffré
Pour chiffrer les données lors de la transmission de contexte, Blackboard et l'URL externe doivent avoir accès à la même clé de chiffrement du contexte. La clé doit être créée à partir de la fonctionnalité Gérer la clé de chiffrement contextuelle disponible dans le panneau de configuration de l'administrateur. Une fois la clé créée, elle doit être téléchargée et distribuée à des serveurs externes qui accepteront le contexte.
Exemple de code
Après avoir téléchargé une clé de chiffrement du contexte, celle-ci doit être mise à la disposition de l'URL qui recevra les données chiffrées par transmission de contexte. L'exemple de code ci-dessous montre comment déchiffrer par programmation les données contextuelles chiffrées sur l'URL externe lorsqu'elle est transmise.
L'objet indiqué par l'URL cible (dans ce cas, index.jsp) pourrait déchiffrer le contexte comme suit (importation de blackboard.client.decryption). *) :
String context = Request.getParameter (« context ») ; //si IsEncryptionEnabled = false, le codage en base 64 sera utilisé à la place //of encryptionboolean IsEncryptionEnabled = true ; ContextDecryptor bfd = ContextDecryptorFactory.getContextDecryptor (IsEncryptionEnabled) ;//récupère la clé de cryptage Blackboard sous forme de fichier ou InputStream File key = new File (StrKeyLocation) ;//ou InputStream key =//détail de l'implémentation...//pour simplement déchiffrer la chaîne de contexte String DecryptedContext = bfd.decrypt (context, key) ;//ou, pour obtenir un HashMap de toutes les paires clé-valeur. ShashMap mapper = bfd.parseEncryptedContext (context, key) ;//recherchez ensuite dans HashMap une valeur attendue, et continue.if (mapper.containsKey (« user ») {//execute...}
Résolution de plusieurs clés
L'exemple de code ci-dessus est utile lorsqu'il existe une relation biunivoque entre l'URL externe et Blackboard. Dans les cas où une URL externe prend en charge un Building Block pour plusieurs instances de Blackboard, le nom d'hôte de l'instance peut être utilisé pour gérer plusieurs clés.
Dans l'exemple ci-dessous, la clé est trouvée en l'associant au nom d'hôte de l'instance ou de l'installation virtuelle de Blackboard. Dans ce cas, le nom d'hôte est physics.votreétablissement.com. Comme le code de déchiffrement du client peut transmettre une clé de déchiffrement à l'objet ContextDecryptor, le serveur client doit être en mesure de mapper un nom d'hôte à la clé appropriée (généralement accessible sous forme de fichier, mais il peut s'agir d'un flux).
Les développeurs de serveurs Building Block peuvent écrire un wrapper simple qui :
Extrait le nom d'hôte de la demande.
Recherche le fichier de clé de chiffrement dans le mapper HostName-EncryptionKey.
Transmet la clé de chiffrement à la méthode
decrypt ().
Enveloppe de pseudocode implémentée par un objet utilitaire client-serveur :
/**
* Pseudocode utilitaire
*/
DecryptByHostName (requête HttpServletRequest)
{
//Récupère le paramètre de contexte de la requête
Contexte de chaîne = Request.getParameter (« contexte ») ;
//détermine si le contexte est chiffré
String StrEncryptInd = Request.getParameter (« chiffrer ») ;
if ((StrEncryptInd ! = null) && (StrEncryptInd.EqualsIgnoreCase (« y »)))
{
IsEncrypted = vrai ;
}
//si IsEncrypted, recherchez la clé
clé = nulle ;
si (est crypté)
{
//Récupère le nom d'hôte depuis HttpUtils.getRequestURL () .getHost () ;
//obtient la carte des clés, éventuellement stockée sous forme de fichier de propriétés au format
// physics.yourinstitution.com= /key/file/location/physics_yourinstitution_com/key.sec
//obtient la clé de cryptage du mapper sous forme de fichier ou de flux d'entrée,
//en fonction des détails de l'implémentation du client (la clé est passée comme nulle si
//IsEncrypted= false, et Base64Encoding est utilisé à la place)
}
Décrypteur ContextDecryptor =
ContextDecryptorFactory.getContextDecryptor (IsEncrypted) ;
//puis renvoie les valeurs transmises dans le contexte sous la forme
//un HashMapper de paires clé-valeur
valeurs Mapper = Decryptor.ParseEncryptedContext (contexte, clé) ;
//ou une chaîne
Valeurs de chaîne = decryptor.decrypt (contexte, clé) ;
valeurs de retour ;
}