Предостережение: это потенциально откроет ваш код для вставки HTML и/или скриптов. Фильтр строго.
Мне недавно пришлось сделать что-то подобное для проекта, на котором я был заключен контракт. Как и другие, я использовал хэш-часть URL-адреса для передачи функций и параметров JavaScript. Однако основное отличие заключалось в том, что я не делал простой eval
всей строки. Я установил конкретный формат до 1) сузить количество функций, которые могут быть выполнены, и 2) дезинфицировать любой входной сигнал, что метод требуемой
Формат, в полном объеме, выглядит следующим образом:
http://somedomain.tld/path/?query=blah#specific.controller.object/method/['array', 'of', {json: 'arguments'}]
Так , в основном, вы получаете следующую строку:
specific.controller.object/method/['array', 'of', {json: 'arguments'}]
Затем я написал парсер для обработки этой строки. Ограничения, в которых требовалось, какие объекты могут быть вызваны путем добавления с помощью своего объекта «пространства имен», другими словами, называя его частью члена существующего, предопределенного статического объекта. Например, specific.controller.object
, будет называться new com.project.specific.controller.object();
.Вот что-то похожее на мой парсер:
var data = location.hash.substr(1).split('/'),
controller = ("my.namespace." + data[0]).split("."),
// You can provide a default method if you want, my framework used `show`
method = data[1] || "show",
// must be an array for use with `apply`
params = data[2] || "[]";
// Parse the controller to find the appropriate object to instantiate.
// All objects are in reference to the global window object. Break
// them apart by their dot composition and step down through the object
// tree starting at window.
var composition = window;
for (var i=0; i<controller.length; i++) {
composition = composition[ controller[i] ];
}
var obj = new composition;
// Handle the parameters. It may be the case that there "/" is present
// in the last argument. If so, add anything that was left out.
if (data.length > 3) {
for (var i=3; i<data.length; i++) {
params += '/' + data[i];
}
}
// Convert params from a string to an array.
// ***Possible injection point here***
params = dojo.fromJson(params);
// Make sure that the method runs in the proper context and
// pass it all of the parameters
obj[method].apply(obj, params);
Так как анализатор работает, вы должны предоставить параметры, если никто не нужны, а в некоторых случаях, если вы выбираете, чтобы стандартные методы, как я, вы не» t должен указать, какой член на вызываемом объекте, что значительно упрощает построение этих URL.
Вместо использования объекта статического пространства имен для ограничения того, какие объекты могут быть созданы, было бы тривиально использовать белый список безопасных объектов и методов.
Превосходный номер. Это ужасная реализация для любого приложения. В идеале JavaScript должен быть ненавязчивым. Кроме того, пока нет прямого сопоставления, существует множество способов достижения этой функциональности. –