Bagaimana cara saya menulis Json yang tidak di-enkripsi ke View saya menggunakan Razor?

153

Saya mencoba untuk menulis objek sebagai JSON ke Asp.Net MVC View saya menggunakan Razor, seperti:

<script type="text/javascript">
  var potentialAttendees = @Json.Encode(Model.PotentialAttendees);
</script>

Masalahnya adalah bahwa dalam output JSON dikodekan, dan browser saya tidak menyukainya. Sebagai contoh:

<script type="text/javascript">
    var potentialAttendees = [{&quot;Name&quot;:&quot;Samuel Jack&quot;},];
</script>

Bagaimana cara membuat Razor memancarkan JSON yang tidak dilodekan?

Samuel Jack
sumber

Jawaban:

190

Anda melakukannya:

@Html.Raw(Json.Encode(Model.PotentialAttendees))

Dalam rilis yang lebih awal dari Beta 2 Anda suka:

@(new HtmlString(Json.Encode(Model.PotentialAttendees)))
Lorenzo
sumber
3
Apa yang dapat saya lakukan jika saya ingin beberapa teks yang disandikan di properti objek saya? \, {\ "UrlPart \": \ "TjcolklFX5c \", \ "Title \": \ "Ketika Mama Isn \ u0027t Home \"}, {\ "Sebagai contoh. Ini akan merusak beacause js berpikir bahwa 'melarikan diri dari decalration string asli dari var a = '' hal yang sama berlaku untuk "". anny idea?
SomeRandomName
@BeberapaRandomName dapat Anda gunakan javascriptserializeruntuk itu seperti @Html.Raw(javascriptSerializerObjecct.Serialize(myObject))
vikscool
Kami berada di 2017, menggunakan MVC 5 dan jawaban ini masih sempurna!
Gabriel Espinoza
Jawaban ini adalah satu-satunya yang bekerja dengan sempurna. Terima kasih!
Jean-Paul
43

Newtonsoft JsonConvert.SerializeObjecttidak berperilaku sama dengan Json.Encodedan melakukan apa yang disarankan oleh @ david-k-egghead akan membuka Anda terhadap serangan XSS .

Masukkan kode ini ke tampilan Razor untuk memastikan bahwa penggunaan Json.Encodeaman, dan Newtonsoft dapat dibuat aman dalam konteks JavaScript tetapi bukan tanpa kerja ekstra.

<script>
    var jsonEncodePotentialAttendees = @Html.Raw(Json.Encode(
        new[] { new { Name = "Samuel Jack</script><script>alert('jsonEncodePotentialAttendees failed XSS test')</script>" } }
    ));
    alert('jsonEncodePotentialAttendees passed XSS test: ' + jsonEncodePotentialAttendees[0].Name);
</script>
<script>
    var safeNewtonsoftPotentialAttendees = JSON.parse(@Html.Raw(HttpUtility.JavaScriptStringEncode(JsonConvert.SerializeObject(
        new[] { new { Name = "Samuel Jack</script><script>alert('safeNewtonsoftPotentialAttendees failed XSS test')</script>" } }), addDoubleQuotes: true)));
    alert('safeNewtonsoftPotentialAttendees passed XSS test: ' + safeNewtonsoftPotentialAttendees[0].Name);
</script>
<script>
    var unsafeNewtonsoftPotentialAttendees = @Html.Raw(JsonConvert.SerializeObject(
        new[] { new { Name = "Samuel Jack</script><script>alert('unsafeNewtonsoftPotentialAttendees failed XSS test')</script>" } }));
    alert('unsafeNewtonsoftPotentialAttendees passed XSS test: ' + unsafeNewtonsoftPotentialAttendees[0].Name);
</script>

Lihat juga:

Jeremy Cook
sumber
Apakah Anda tahu ketika mereka menambahkan Json.Encode? Saya tidak tahu sebenarnya ada cara yang aman untuk memasukkan json di halaman dan saya tahu saya sudah banyak melakukan penelitian di masa lalu.
Chris Marisic
1
Json.Encodetelah ada selama yang saya ingat, tetapi downside adalah bahwa ia menggunakan implementasi Microsoft yang menghasilkan tanggal yang tidak standar (dan dapat melakukan hal-hal mengganggu lainnya). Saya menggunakan dan mendorong penggunaan Newtonsoft yang JsonConvert.SerializeObjectdikombinasikan dengan pelarian yang tepat karena memiliki keluaran yang lebih baik.
Jeremy Cook
2
Senang saya menggulir ke bawah. Segera saya melihat jawaban yang diterima, saya berharap ada cara yang aman untuk melakukan ini.
dingin
Versi HttpUtility.JavaScriptStringEncode juga menyandikan tanda kutip di JSON, menjadikannya tidak valid jika digunakan langsung dalam skrip [type = 'application / json'], yang sangat disayangkan.
Pete Kirkham
1
Catatan untuk diri sendiri di masa depan: Yang ingin Anda gunakan adalah ini: @ Html.Raw (Json.Encode ())
Pangamma
12

Menggunakan Newtonsoft

<script type="text/jscript">
  var potentialAttendees  = @(Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.PotentialAttendees)))
</script>
Ravi Ram
sumber
1
Ini berpotensi rentan terhadap kerentanan XSS yang diperbaiki oleh Json.Encode, tetapi Anda dapat mengesampingkannya JsonSerializerSettings.StringEscapeHandlinguntuk mengaktifkan penyandian. stackoverflow.com/a/50336590/6950124
Kevin Secrist