Можно ли выполнить атаку подделки межсайтовых запросов на URL, который возвращает объект JSON? - PullRequest
2 голосов
/ 03 июля 2010

Мне известно, что существует Межсайтовая подделка , которая может быть выполнена по запросу, который возвращает массив, перегружая конструктор Array.Например, предположим, у меня есть сайт с URL:

foo.com/getJson

, который возвращает:

['Puff the Dragon', 'Credit Card #'] 

Обычно это будет Javascript eval 'd для моего собственного сайта после XHRзапрос, но другой сайт может перехватить эти данные, включив что-то вроде:

<script>
function Array() {
  var arr = this;
  var i = 0;
  var next = function(val) {
    arr[i++] setter = next;
    document.write(val);
  };
  this[i++] setter = next;
}
</script>
<script src="http://foo.com/getJson"></script>

Мой вопрос: можно ли сделать то же самое, когда запрос возвращает объект Javascript?то есть

{ name: 'Puff the Dragon', cc: 'Credit Card #' }

Я не мог найти способ сделать это, но, возможно, я что-то упустил.Я знаю, что есть более эффективные решения для защиты моего сайта, такие как использование while (1) хака или требование авторизационного токена в URL, но я пытаюсь выяснить, существует ли такая дыра в безопасности.

Ответы [ 3 ]

2 голосов
/ 03 июля 2010

Источники, которые я видел, такие как Haacked и Hackademix , конкретно указывают, что корневые объекты безопасны (предположительно во всех основных браузерах). Это потому, что скрипт не может начинаться с литерала объекта. По умолчанию ASP.NET упаковывает объекты и массивы с префиксом d , но я думаю, что это просто для упрощения клиентской библиотеки.

1 голос
/ 03 июля 2010

Как видно из спецификации Ecmascript , объект JSON не следует рассматривать как допустимую программу Javascript:

"Обратите внимание, что ExpressionStatement не может начинаться с открытияфигурные скобки, потому что это может сделать его неоднозначным с блоком* и {['Puff the Dragon', 'Credit Card #']} будет.

0 голосов
/ 03 июля 2010

Вы можете использовать ту же технику для Object. Это не повлияет на цепочку прототипов, поэтому не будет наследоваться всеми объектами. Но вы можете, например, регистрировать все новые создаваемые объекты с помощью этого:

function Object() {
    var obj = this;
    if (window.objectarray === undefined) {
        window.objectarray = [];
    }
    window.objectarray.push(this);
    return this;
}

Любой временной код на вашей странице использует new Object(), он будет записан в window.objectarray - , даже если он был создан в частной области. Так, например, посмотрите на этот код:

var Account = function() {
    var createToken = function() {
        var objToken = new Object();
        objToken.timestamp = new Date().getTime();
        objToken.securestring = "abc123";
        return objToken.timestamp + objToken.securestring;
    }
    var objPrivate = new Object();
    objPrivate.bankaccount="123-456789";
    objPrivate.token = createToken();
};
var myAccount = new Account();

В этом случае, если вы создадите новую учетную запись с new Account(), токен будет создан с использованием личных свойств (и, возможно, методов), и ничего о myAccount не останется открытым для публики. Но и objectToken, и objPrivate будут зарегистрированы как window.objectarray.

...