Skip to content

Commit 5076197

Browse files
committed
refactor: enhance ttMatch directive with $parse and improve modal handling for security
1 parent 767d357 commit 5076197

2 files changed

Lines changed: 86 additions & 12 deletions

File tree

src/IdentityManager2/Assets/Scripts/App/ttIdmUI.js

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,17 @@
7474
ttFocus.$inject = [];
7575
app.directive("ttFocus", ttFocus);
7676

77-
function ttMatch($timeout) {
77+
function ttMatch($timeout, $parse) {
7878
return {
7979
restrict: 'A',
8080
require: 'ngModel',
8181
link: function (scope, elem, attrs, ctrl) {
82+
var matchGetter = $parse(attrs.ttMatch);
83+
8284
function check() {
8385
if (ctrl.$dirty) {
8486
var thisVal = elem.val();
85-
var otherVal = scope.$eval(attrs.ttMatch);
87+
var otherVal = matchGetter(scope);
8688
if (!thisVal || thisVal === otherVal) {
8789
ctrl.$setValidity('ttMatch', true);
8890
}
@@ -102,7 +104,7 @@
102104
}
103105
};
104106
}
105-
ttMatch.$inject = ["$timeout"];
107+
ttMatch.$inject = ["$timeout", "$parse"];
106108
app.directive("ttMatch", ttMatch);
107109

108110
function ttPropertyEditor(PathBase){
@@ -172,9 +174,32 @@
172174
app.directive("ttPagerSummary", ttPagerSummary);
173175

174176
function idmPager($sce) {
177+
function escapeHtml(value) {
178+
return String(value)
179+
.replace(/&/g, "&")
180+
.replace(/</g, "&lt;")
181+
.replace(/>/g, "&gt;")
182+
.replace(/\"/g, "&quot;")
183+
.replace(/'/g, "&#39;");
184+
}
185+
186+
var allowedPagerHtml = {
187+
"<strong>&lt;&lt;</strong>": true,
188+
"<strong>&lt;</strong>": true,
189+
"<strong>&gt;</strong>": true,
190+
"<strong>&gt;&gt;</strong>": true
191+
};
192+
193+
function trustPagerText(text) {
194+
if (allowedPagerHtml[text]) {
195+
return $sce.trustAsHtml(text);
196+
}
197+
return $sce.trustAsHtml(escapeHtml(text));
198+
}
199+
175200
function Pager(result, pageSize) {
176201
function PagerButton(text, page, enabled, current) {
177-
this.text = $sce.trustAsHtml(text + "");
202+
this.text = trustPagerText(text);
178203
this.page = page;
179204
this.enabled = enabled;
180205
this.current = current;
@@ -235,14 +260,26 @@
235260
elem.on("click", function (e) {
236261
if (prevent) {
237262
e.preventDefault();
238-
$(attrs.ttConfirmClick).modal('show');
263+
var selector = attrs.ttConfirmClick || "";
264+
if (selector.indexOf("#") !== 0) {
265+
return;
266+
}
267+
var id = selector.substring(1);
268+
if (!/^[A-Za-z][\w\-:.]*$/.test(id)) {
269+
return;
270+
}
271+
var modalElem = document.getElementById(id);
272+
if (!modalElem) {
273+
return;
274+
}
275+
$(modalElem).modal('show');
239276
if (!cb) {
240277
cb = function () {
241278
$(this).off("confirm");
242279
prevent = false;
243280
elem.trigger("click");
244281
};
245-
$(attrs.ttConfirmClick).on("confirm", cb);
282+
$(modalElem).on("confirm", cb);
246283
}
247284
}
248285
});

src/IdentityManager2/Assets/Scripts/Bundle.js

Lines changed: 43 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)