Pergunta

uma solicitação do Ajax me retorna uma matriz JSON padrão preenchido com entradas do meu usuário. A entrada foi higienizado, e usando a função eval (), eu posso facilmente criar meu objeto javascript e atualizar minha página ...

Então aqui está o problema. Não importa o quanto eu tente para higienizar as entradas, eu prefiro não usar a função eval (). Eu verifiquei no google por maneiras de usar "JSON em AJAX sem eval" e corri accross um monte de diferentes métodos ...

Qual deles devo usar? Existe um padrão, comprovada segura maneira de fazer isso?

Foi útil?

Solução

json.org tem um bom biblioteca javascript

uso simples:

JSON.parse('[{"some":"json"}]');
JSON.stringify([{some:'json'}]);

Editar : Como foi salientado nos comentários, isso usa eval se você olhar através de sua fonte (embora pareça ser higienizado primeiro)

para evitá-lo completamente, olhada json_parse ou JSON-sans-eval

json2.js é inseguro, json_parse.js é lento, JSON-sans-eval.js é não-validação

Outras dicas

Existe um padrão, comprovada segura maneira de fazer isso?

Há uma maneira padrão proposto de fazer isso, na próxima versão ECMAScript 3.1 do JavaScript: JSON.parse .

Será apoiado no IE8, Firefox 3.1 / 3.5 e, provavelmente, os outros browsers populares no futuro. Enquanto isso, você pode cair de volta para, ou utilizar exclusivamente, eval (). Mal ele pode ou não ser; certamente será mais lento do que JSON.parse. Mas essa é a maneira usual para analisar JSON hoje.

Se um atacante é capaz de injetar malcious JavaScript no conteúdo que você está cuspindo via JSON, você tem problemas maiores para se preocupar do que eval-é-o mal.

Eu diria que, uma vez que a entrada é higienizado, eval é o melhor caminho a percorrer. Se o servidor for comprometida, as pessoas serão capazes de enviar o que roteiros que eles querem para o cliente de qualquer maneira. Então, colocar um eval não é um grande risco à segurança. Se você está preocupado com as pessoas que manipulam os pacotes antes de chegar ao cliente, em seguida, mais uma vez, os scripts si pode ser modificado.

Não se preocupe com eval. Mas certifique-se de envolvê-lo em um bloco try ... catch para que seus usuários não obter erros JS se o seu JSON fica mutilado.

:)

Para converter com segurança JSON para um JS objeto que você deve usar um analisador JSON como a função JSON.parse () fornecida pelo esta biblioteca .

Compare com o padrão de design de comando: http://en.wikipedia.org/wiki/Command_pattern . Diante disso, você pode definir com precisão as operações de um cliente pode executar e sua aplicação vai ser tão seguro quanto a interpretação subjacente.

Depende do que você está tentando realizar com o saneamento. Eu tive grande sucesso w / a protótipo apoio da estrutura para JSON e avaliação de segurança.

Se você está certo, não há risco de injeção, e você não está eval()ing em um loop, em seguida, usar eval(). Ele vai se comparam favoravelmente com outras opções que certamente será mais lento, pode quebrar, e vai exigir o cliente para baixar o código adicional.

"roubada" do jQuery

// Try to use the native JSON parser first
return window.JSON && window.JSON.parse ?
    window.JSON.parse( data ) :
    (new Function("return " + data))();

Issue: As poses problema eval é que ele executa no escopo global

eval.call(document, "console.log(this)")
eval.call(navigator, "console.log(this)")
eval.call(window, "console.log(this)")
(function(){eval.call(document, "console.log(this)")})()
>Window

Cenário:

Suponha que você está usando atributos individuais no código de marcação de vários documentos-elementos tais como um atributo onvisible

<img src="" onvisible="src='http://www.example.com/myimg.png';">

Você gostaria de obter todos os elementos com este atributo, gire o onvisible-content-string em um fechamento e colocá-lo em uma fila EventHandler. Este é o lugar onde o construtor Função JS entra em jogo.

Function === 0..constructor.constructor
>true

Function('return [this, arguments]').call(window, 1,2,3)
>Window, Arguments[3]]
Function('return [this, arguments]').call(document, 1,2,3)
>Document, Arguments[3]]
Function('return [this, arguments]').call(navigator, 1,2,3)
>Navigator, Arguments[3]]    

Juntando tudo:

var eventQueue = [];
var els = document.querySelectorAll('[onvisible]');

for (var el in els) {
    var jscode = els[el].getAttribute('onvisible');
    eventQueue.push( {el:els[el], cb:Function(jscode)} )
}

//eventQueue[0].cb.call(scope, args);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top