Je crée un site qui illustre des vulnérabilités d'applications courantes telles que l'injection SQL. J'utilise AngularJS et highlight.js pour créer des exemples interactifs.
Comment puis-je faire AngularJS et highlight.js mettre à jour mes extraits de code?
Ce Fiddle démontre comment la saisie de ' OR 1=1 --
dans le champ Email peut changer le comportement prévu de la requête si l'entrée de l'utilisateur n'est pas validée ou désinfectée.
SELECT * FROM dbo.Users WHERE Email='{{email}}' AND Password='{{password}}'
Lorsqu'un utilisateur entre une adresse e-mail et un mot de passe, Angular met à jour la requête. Cependant, la mise en surbrillance de la syntaxe ne se met pas à jour.
SELECT * FROM dbo.Users WHERE Email='[email protected]' AND Password=''
J'ai essayé de réinitialiser hljs, mais quand je fais des arrêts angulaires, je met à jour la requête.
hljs.initHighlighting.called = false; hljs.initHighlighting();
<script> var app = angular.module("app", ['hljs']); app.controller("controller", function($scope) { $scope.email = "[email protected]"; $scope.password = ""; }) </script> <div ng-app="app" ng-controller="controller"> <div> <div class="row"> <div class="col-sm-4">Email <input type="text" class="form-control" ng-model="email"> </div> <div class="col-sm-4">Password <input type="text" class="form-control" ng-model="password"> </div> </div> <br> <div hljs include="'compile-me'" compile="true" language="sql"></div> </div> <script type="text/ng-template" id="compile-me"> SELECT * FROM dbo.Users WHERE Email = '{{email}}' AND Password = '{{password}}' </script> </div>
Dans le jsfiddle que vous avez fourni, vous utilisez angular-highlightjs qui, dans votre cas, est fondamentalement:
include
directive s'applique $compile
Par la suite, aucun déréglementement n'a lieu, en particulier même lorsque le contenu interpolé change.
Une façon de le résoudre est d'utiliser la directive source
partir de angular-highlightjs
qui est observée, mais je pense qu'il est plus simple de créer une directive personnalisée.
Le tour consiste ici à interpoler manuellement et à mettre en surbrillance le contenu. J'ai mis à jour votre violon avec une directive simpliste qui présente l'idée:
app.directive('highlight', function($interpolate, $window){ return { restrict: 'EA', scope: true, compile: function (tElem, tAttrs) { var interpolateFn = $interpolate(tElem.html(), true); tElem.html(''); // stop automatic intepolation return function(scope, elem, attrs){ scope.$watch(interpolateFn, function (value) { elem.html(hljs.highlight('sql',value).value); }); } } }; });
Une façon plus simple que je viens de trouver est d'utiliser un filtre:
app.filter('highlight', function($sce) { return function(input, lang) { if (lang && input) return hljs.highlight(lang, input).value; return input; } }).filter('unsafe', function($sce) { return $sce.trustAsHtml; })
Ensuite, vous pouvez dire:
<pre><code ng-bind-html="someScopeVariable | highlight | unsafe"></code></pre>
Le $ sce doit être injecté dans votre application et indique à Angular d'afficher le HTML brut – que vous en faites confiance.