2013-01-12 8 views
8

Come si rendono sicuri i dati JSON in un'applicazione web django?Uso sicuro di JSON con html all'interno del JSON nei modelli di Django

Sul server in django generato dati JSON e quindi il rendering dei dati JSON in un modello django. Talvolta JSON contiene frammenti di html. La maggior parte delle volte va bene, tuttavia se il tag </script> si trova all'interno dei dati JSON al momento del rendering, distrugge il javascript circostante.

Per esempio ...

Sul server, in python avrò questo:

template_data = { 
    'my_json' : '[{"my_snippet": "<b>Happy HTML</b>"}]' 
} 
# pass the template data to the django template 
return render_to_response('my_template.html', template_data, context_instance = c) 

E poi nel modello:

<script type="text/javascript"> 
var the_json = {{my_json|safe}}; 
</script> 
... some html ... 

Il html risultante funziona correttamente e assomiglia a questo:

<script type="text/javascript"> 
var the_json = [{"my_snippet": "<b>Happy HTML</b>"}]; 
</script> 
... some html ... 

Tuttavia, si esegue in problemi quando, sul server, il JSON è simile al seguente:

template_data = { 
    'my_json' : '[{"my_snippet": "Bad HTML</script>"}]' 
} 
return render_to_response('my_template.html', template_data, context_instance = c) 

Ora, quando è reso, si otterrà:

<script type="text/javascript"> 
var the_json = [{"my_snippet": "Bad HTML</script>"}]; 
</script> 
... some html ... 

Il tag di script di chiusura all'interno del codice JSON viene considerato come la chiusura dell'intero blocco di script. Tutto il tuo javascript si romperà.

Una possibile soluzione è controllare </script> quando si passano i dati del modello al modello, ma mi sembra che ci sia un modo migliore.

+0

Si potrebbe servire come JSON (tramite la tecnologia AJAX) o servirlo come un file javascript (quindi includerlo usando un tag script). – DanielB

risposta

14

inserire in modo sicuro il JSON come una stringa, e quindi chiamare JSON.parse su di esso

Uso escapejs invece che al sicuro. È progettato per l'output su JavaScript.

var the_json = '{{my_json|escapejs}}'; 

per ottenere un oggetto JavaScript è quindi necessario chiamare JSON.parse su quella stringa. Questo è sempre preferibile al dumping di una codifica JSON nel tuo script e alla valutazione diretta, per ragioni di sicurezza.

Un filtro utile per ottenere oggetti Python direttamente al cliente che uso è questo:

@register.filter 
def to_js(value): 
    """ 
    To use a python variable in JS, we call json.dumps to serialize as JSON server-side and reconstruct using 
    JSON.parse. The serialized string must be escaped appropriately before dumping into the client-side code. 
    """ 
    # separators is passed to remove whitespace in output 
    return mark_safe('JSON.parse("%s")' % escapejs(json.dumps(value, separators=(',', ':')))) 

e usarlo come:

var Settings = {{ js_settings|to_js }}; 
+0

Se si esegue questa operazione, "the_json" diventa una stringa, non un oggetto json javascript. – speedplane

+1

Si potrebbe fare 'var the_json = JSON.parse ({{my_json | escapejs}})' – DanielB

+1

Penso che sia necessario citarla, come questa: 'var the_json = JSON.parse ('{{my_json | escapejs}}') ' – speedplane