Création de widgets ThingWorx sécurisés
Lorsque vous créez des widgets personnalisés, assurez-vous qu'ils sont sécurisés. Vous devez tenir compte des vulnérabilités de script de site à site (XSS) et de falsification de requête intersites (CSRF). Pour plus d'informations, consultez la rubrique Mise à jour de la méthode de requête et filtrage du type de contenu pour la protection CSRF.
Les sections suivantes présentent les bonnes pratiques en matière de création de widgets sécurisés.
Utilisation du codage pour les valeurs de sortie HTML dans les widgets
Si vous utilisez des widgets pour afficher des valeurs dans l'interface utilisateur, il est recommandé d'utiliser le codage HTML. Reportez-vous à l'exemple de code suivant :
this.updateProperty = function (updatePropertyInfo) {
if (updatePropertyInfo.TargetProperty === 'Text') {
var labelText = Encoder.htmlEncode(updatePropertyInfo.SinglePropertyValue);
thisWidget.setProperty('Text', labelText);
showLabelText(thisWidget.getProperty('Text'));
}
}
Dans cet exemple :
La fonction updatePropery() est appelée chaque fois que la valeur liée d'une propriété de widget est modifiée.
La valeur du widget est codée en HTML à l'aide de la bibliothèque de codeurs.
Après le codage, utilisez les méthodes Get et Set pour accéder à cette nouvelle valeur.
Cette étape permet de s'assurer que les méthodes Get effectuent un nettoyage supplémentaire des valeurs renvoyées à l'interface utilisateur.
Utilisation du décodage et de jQuery pour les valeurs de sortie HTML dans les widgets
Si vous vous servez de widgets pour afficher des valeurs dans l'interface utilisateur et que vous avez utilisé le codage HTML pour coder les valeurs, employez le décodage HTML pour convertir la valeur codée dans sa valeur d'origine. Reportez-vous à l'exemple de code suivant :
function showLabelText(labelText) {
labelText = Encoder.htmlDecode(labelText);
var spanText = thisWidget.jqElement.find('.label-text');
spanText.text(labelText);
}
Dans cet exemple :
La fonction showLabelText est utilisée pour obtenir l'élément DOM du widget et mettre à jour la valeur.
Décodez la valeur à l'aide de la bibliothèque de codeurs.
Utilisez la méthode text() avec jQuery sur l'élément DOM pour afficher la valeur. Cette méthode intègre une fonction d'échappement qui permet de sécuriser l'application contre les failles XSS.
Utilisation du codage pour la sortie HTML dans JavaServer Pages (JSP)
Si vous utilisez JSP pour afficher des valeurs dans l'interface utilisateur, il est recommandé d'utiliser le codage HTML. Vous pouvez utiliser les utilitaires ESAPI d'OWASP pour gérer le codage sur une base contextuelle. Reportez-vous à l'exemple de code suivant :
<div class="org-info">
<h1 class="orgName">
<%=ESAPIUtilities.getEncoder().encodeForHTML(orgName)%>
</h1>
<p class="orgDescription"><%=ESAPIUtilities.getEncoder().encodeForHTML(loginPrompt)%></p>
</div>
Dans cet exemple :
Les utilisateurs peuvent créer leurs propres pages de connexion pour ThingWorx.
L'utilisateur doit saisir des informations pour les champs suivants d'un écran de connexion :
orgName
loginPrompt
Les données de ces champs ne sont pas fiables, car l'utilisateur peut potentiellement saisir des caractères malveillants dans ces champs. Il est donc nécessaire d'exécuter ces données via les utilitaires ESAPI pour le codage HTML.
Sécurisation des interfaces utilisateur personnalisées
Vous pouvez créer vos propres interfaces utilisateur personnalisées en développant des extensions ou disposer de vos propres applications Web hébergées qui utilisent les API REST ThingWorx. Dans ces scénarios, vous devez vous assurer que les données sont purifiées et codées avant qu'elles ne s'affichent dans le navigateur.
Assurez-vous de bien connaître les infrastructures que vous implémentez et d'utiliser les pratiques recommandées pour ce type d'environnement afin de protéger l'application contre les failles XSS.
Dans l'exemple suivant, une application AngularJS utilise un modèle qui a été importé en tant qu'extension. Vous pouvez utiliser les utilitaires ThingWorx pour générer ce processus.
<div class="node-label-wrap" ng-class="{'graph-node-nonadmin': $parent.$parent.isNonAdminUser}">
<textarea type="text" ng-model="node.label" ng-change="$parent.$parent.setBPUpdatesMade()">
</textarea>
<div class="node-label">{{node.label}}</div>
</div>
Dans cet exemple :
node.label est l'entrée utilisateur non approuvée. Il s'agit d'une chaîne arbitraire. Les utilisateurs fournissent le nom de l'étiquette pour le noeud de processus.
Dans les modèles d'applications AngularJS, le fait d'entourer une entrée non fiable de doubles accolades {{}} ({{node.label}}, par exemple) force une interpolation de chaîne. La valeur est traitée comme une chaîne et n'est pas exécutée dans le contexte d'un script.
Réponses HTML
PTC documente ses réponses HTML dans une classe commune qui filtre toutes les sorties par l'intermédiaire des utilitaires ESAPI.
public void writeTableCell(String value, String id, String sClass, String sStyle) throws Exception {
startTableCell(id, sClass, sStyle);
writeValue(value);
endTableCell();
}

public void writeValue(String value) throws Exception {
write(ESAPIUtilities.getEncoder().encodeForHTML(value));
}