Nilai Request.Form yang berpotensi berbahaya terdeteksi dari klien

1471

Setiap kali pengguna memposting sesuatu yang berisi <atau >dalam halaman di aplikasi web saya, saya mendapatkan pengecualian ini.

Saya tidak ingin membahas tentang kepintaran melempar pengecualian atau menabrak seluruh aplikasi web karena seseorang memasukkan karakter ke dalam kotak teks, tetapi saya mencari cara yang elegan untuk menangani hal ini.

Menjebak pengecualian dan tampil

Terjadi kesalahan, silakan kembali dan ketik ulang seluruh formulir Anda lagi, tapi kali ini jangan gunakan <

bagi saya sepertinya tidak cukup profesional.

Menonaktifkan validasi pos ( validateRequest="false") pasti akan menghindari kesalahan ini, tetapi itu akan membuat halaman rentan terhadap sejumlah serangan.

Idealnya: Ketika suatu posting kembali terjadi yang mengandung karakter-karakter terbatas HTML, nilai yang diposkan dalam koleksi Formulir akan secara otomatis disandikan dengan HTML. Jadi .Textproperti kotak teks saya akan menjadisomething & lt; html & gt;

Apakah ada cara saya bisa melakukan ini dari seorang pawang?

Radu094
sumber
68
Perhatikan bahwa Anda bisa mendapatkan kesalahan ini jika Anda memiliki nama entitas HTML (& amp;) atau nomor entitas (& # 39;) di input Anda juga.
Drew Noakes
18
Yah, karena itu pertanyaan saya, saya merasa saya bisa mendefinisikan apa intinya sebenarnya: menghentikan seluruh proses aplikasi dan mengembalikan pesan kesalahan umum karena seseorang mengetikkan '<' terlalu banyak. Terutama karena Anda tahu kebanyakan orang hanya akan 'validateRequest = false' untuk menyingkirkannya, sehingga membuka kembali kerentanan
Radu094
7
@DrewNoakes: nama entitas (& amp;) tampaknya tidak menjadi masalah menurut pengujian saya (diuji dalam .Net 4.0), meskipun nomor entitas (& # 39;) gagal validasi (seperti yang Anda katakan). Jika Anda membongkar System.Web.CrossSiteScriptingValidation.IsDangerousString menggunakan .Net Reflector, Anda akan melihat bahwa kode tersebut terlihat khusus untuk tag html (dimulai dengan <) dan nomor entitas (dimulai dengan & #)
Gyum Fox
5
Buat situs baru di VS2014 menggunakan proyek MVC default dan jalankan. Klik tautan daftar, tambahkan email apa saja, dan gunakan "<P455-0r [!" sebagai kata sandi. Kesalahan yang sama keluar dari kotak, tidak mencoba melakukan sesuatu yang berbahaya, bidang kata sandi tidak akan ditampilkan sehingga tidak akan menjadi serangan XSS, tetapi satu-satunya cara untuk memperbaikinya adalah dengan sepenuhnya menghapus validasi dengan ValidateInput (false) ? Saran AllowHtml tidak berfungsi dalam situasi ini, masih meledak dengan kesalahan yang sama. Nilai Request.Form yang berpotensi berbahaya terdeteksi dari klien (Kata Sandi = "<P455-0r [!").
stephenbayer
TL; DR dimasukkan <httpRuntime requestValidationMode="2.0" />ke web.config

Jawaban:

1080

Saya pikir Anda menyerang dari sudut yang salah dengan mencoba menyandikan semua data yang diposting.

Perhatikan bahwa " <" juga dapat berasal dari sumber luar lainnya, seperti bidang basis data, konfigurasi, file, umpan, dan sebagainya.

Lebih jauh, " <" secara inheren tidak berbahaya. Ini hanya berbahaya dalam konteks tertentu: ketika menulis string yang belum dikodekan ke output HTML (karena XSS).

Dalam konteks lain, berbagai sub-string berbahaya, misalnya, jika Anda menulis URL yang disediakan pengguna ke dalam tautan, " javascript:" sub-string mungkin berbahaya. Karakter kutip tunggal di sisi lain berbahaya ketika interpolasi string dalam query SQL, tetapi sangat aman jika itu adalah bagian dari nama yang dikirimkan dari formulir atau dibaca dari bidang database.

Intinya adalah: Anda tidak dapat memfilter input acak untuk karakter berbahaya, karena karakter apa pun mungkin berbahaya dalam keadaan yang tepat. Anda harus menyandikan pada titik di mana beberapa karakter tertentu dapat menjadi berbahaya karena mereka masuk ke sub-bahasa yang berbeda di mana mereka memiliki makna khusus. Saat Anda menulis string ke HTML, Anda harus menyandikan karakter yang memiliki arti khusus dalam HTML, menggunakan Server.HtmlEncode. Jika Anda meneruskan string ke pernyataan SQL dinamis, Anda harus menyandikan karakter yang berbeda (atau lebih baik, biarkan kerangka melakukannya untuk Anda dengan menggunakan pernyataan yang disiapkan atau sejenisnya) ..

Ketika Anda yakin Anda meng-encode HTML di mana-mana Anda mengirimkan string ke HTML, lalu atur validateRequest="false"di <%@ Page ... %>direktif dalam .aspxfile Anda .

Di .NET 4 Anda mungkin perlu melakukan sedikit lagi. Terkadang perlu juga menambahkan <httpRuntime requestValidationMode="2.0" />ke web.config ( referensi ).

JacquesB
sumber
74
Bagi mereka yang datang terlambat: validateRequest = "false" ada di direktif Page (baris pertama dari file .aspx Anda)
MGOwen
56
Kiat: Masukkan <httpRuntime requestValidationMode="2.0" />tag lokasi untuk menghindari terbunuhnya perlindungan berguna yang diberikan oleh validasi dari bagian situs Anda yang lain.
Brian
298
Di MVC3, ini ada [AllowHtml]di properti model.
Jeremy Holovacs
2
Untuk menonaktifkannya secara global untuk MVC 3 Anda juga perlu GlobalFilters.Filters.Add(new ValidateInputAttribute(false));di Application_Start().
Alex
15
@MGOwen Anda juga dapat menambahkan arahan halaman ke web.config melalui <pages validateRequest="false" />in <system.web />. Melakukan hal itu akan menerapkan properti ke semua halaman.
oliver-clare
504

Ada solusi berbeda untuk kesalahan ini jika Anda menggunakan ASP.NET MVC:

C # sampel:

[HttpPost, ValidateInput(false)]
public ActionResult Edit(FormCollection collection)
{
    // ...
}

Sampel Visual Basic:

<AcceptVerbs(HttpVerbs.Post), ValidateInput(False)> _
Function Edit(ByVal collection As FormCollection) As ActionResult
    ...
End Function
Zack Peterson
sumber
masalahnya mungkin muncul ketika dibutuhkan pada satu halaman seluruh aplikasi
3
Anda juga dapat menambahkan atribut [ValidateInput (false)] di tingkat kelas. Jika Anda menambahkannya ke kelas pengontrol dasar Anda, itu akan berlaku untuk semua tindakan metode pengontrol.
Shan Plourde
@ Zack Terima kasih atas solusinya. Di sisi lain saya bertanya-tanya apakah [AllowHtml]lebih baik daripada ValidateInput(false), karena [AllowHtml]didefinisikan sekaligus untuk properti yaitu bidang Editor dan setiap kali digunakan tidak perlu menggunakannya untuk beberapa tindakan. Apa yang Anda sarankan?
Jack
@Zack Peterson Apakah aman untuk digunakan? Tidak ada masalah keamanan?
shrey Pav
417

Di ASP.NET MVC (mulai dari versi 3), Anda bisa menambahkan AllowHtmlatribut ke properti di model Anda.

Ini memungkinkan permintaan untuk memasukkan markup HTML selama pengikatan model dengan melewatkan validasi permintaan untuk properti.

[AllowHtml]
public string Description { get; set; }
Anthony Johnston
sumber
12
Jauh lebih baik untuk melakukan ini secara deklaratif daripada di controller!
Andiih
29
Satu-satunya jawaban yang benar! penonaktifan validasi pada tindakan pengontrol adalah hacky. Dan untuk menonaktifkan validasi pada level aplikasi, devs harus digantung!
trailmax
Apakah ini hilang di MVC 4?
granadaCoder
1
Apa perbedaan antara ValidateInput(false)dan AllowHtml? Apa keuntungan satu dari yang lain? Kapan saya ingin menggunakan, AllowHtmlbukan ValidateInput(false)? Ketika saya ingin menggunakan ValidateInput(false)lebih AllowHtml? Kapan saya ingin menggunakan keduanya? Apakah masuk akal untuk menggunakan keduanya?
Ian Boyd
3
ValidateInput ada di dalam metode, AllowHtml ada di properti model - jadi Anda hanya mengizinkan yang Anda harapkan memiliki html - tidak semua
Anthony Johnston
213

Jika Anda menggunakan .NET 4.0 pastikan Anda menambahkan ini di file web.config Anda di dalam <system.web>tag:

<httpRuntime requestValidationMode="2.0" />

Di .NET 2.0, validasi permintaan hanya diterapkan pada aspxpermintaan. Di .NET 4.0 ini diperluas untuk mencakup semua permintaan. Anda dapat kembali ke hanya melakukan validasi XSS saat memproses .aspxdengan menentukan:

requestValidationMode="2.0"

Anda dapat menonaktifkan permintaan untuk memvalidasi sepenuhnya dengan menetapkan:

validateRequest="false"
JordanC
sumber
30
Di dalam <system.web>tag.
Hosam Aly
8
Saya telah meletakkan ini di web.config, tetapi masih ada kesalahan "Permintaan yang berpotensi berbahaya. Nilai formulir"
Filipi
20
Sepertinya <httpRuntime requestValidationMode = "2.0" /> hanya berfungsi ketika kerangka 2.0 diinstal pada mesin. Bagaimana jika 2.0 framework tidak diinstal sama sekali tetapi hanya 4.0 framework diinstal?
Samuel
Ini benar-benar bekerja untuk saya. Tidak ada langkah-langkah dokumen dalam jawaban lain yang diperlukan (termasuk validateRequest = "false")!
tom redfern
112

Untuk ASP.NET 4.0, Anda dapat mengizinkan markup sebagai input untuk halaman tertentu dan bukan keseluruhan situs dengan meletakkan semuanya dalam <location>elemen. Ini akan memastikan semua halaman Anda lainnya aman. Anda TIDAK perlu memasukkan ValidateRequest="false"halaman .aspx Anda.

<configuration>
...
  <location path="MyFolder/.aspx">
    <system.web>
      <pages validateRequest="false" />
      <httpRuntime requestValidationMode="2.0" />
    </system.web>
  </location>
...
</configuration>

Lebih aman untuk mengontrol ini di dalam web.config Anda, karena Anda dapat melihat di tingkat situs mana halaman memungkinkan markup sebagai input.

Anda masih perlu memvalidasi input pada halaman di mana validasi permintaan dinonaktifkan.

Carter Medlin
sumber
Info lebih lanjut tentang requestValidationMode = 2 | 4 di sini: msdn.microsoft.com/en-us/library/…
GlennG
Sayangnya ini tidak akan berfungsi dengan ASP.net 2.0. Hapus garis httpRuntime dan itu akan berhasil.
Fandango68
Saya menambahkan peringatan yang mengingatkan orang untuk memvalidasi input secara manual ketika validasi dinonaktifkan.
Carter Medlin
72

Jawaban sebelumnya sangat bagus, tetapi tidak ada yang mengatakan bagaimana cara mengecualikan satu bidang dari validasi untuk injeksi HTML / JavaScript. Saya tidak tahu tentang versi sebelumnya, tetapi dalam MVC3 Beta Anda dapat melakukan ini:

[HttpPost, ValidateInput(true, Exclude = "YourFieldName")]
public virtual ActionResult Edit(int id, FormCollection collection)
{
    ...
}

Ini masih memvalidasi semua bidang kecuali untuk yang dikecualikan. Yang menyenangkan tentang ini adalah bahwa atribut validasi Anda masih memvalidasi bidang, tetapi Anda tidak mendapatkan "Permintaan yang berpotensi berbahaya. Nilai form terdeteksi dari klien" pengecualian.

Saya telah menggunakan ini untuk memvalidasi ekspresi reguler. Saya telah membuat ValidationAttribute saya sendiri untuk melihat apakah ekspresi reguler itu valid atau tidak. Karena ekspresi reguler dapat berisi sesuatu yang terlihat seperti skrip, saya menerapkan kode di atas - ekspresi reguler masih diperiksa apakah valid atau tidak, tetapi tidak jika itu berisi skrip atau HTML.

gligoran
sumber
10
Sayangnya sepertinya fitur Kecualikan telah dihapus dari MVC 3 RTW :(
Matt Greer
2
Juga tidak termasuk dalam MVC 4
wilsjd
9
Gunakan [AllowHtml]pada properti model alih-alih [ValidateInput]pada Action untuk mencapai hasil akhir yang sama.
Mrchief
2
@ Christof Perhatikan bahwa jawaban saya berusia 5 tahun. Saya belum pernah menemukan masalah ini dalam waktu yang sangat lama, jadi mungkin ada banyak cara yang lebih baik untuk menghadapinya. Mengenai dua opsi ini saya pikir itu tergantung pada situasi Anda. Mungkin Anda mengekspos model itu di lebih dari satu tindakan dan di beberapa tempat HTML diizinkan atau tidak. Dalam kasus seperti [AllowHtml]itu bukanlah suatu pilihan. Saya sarankan memeriksa artikel ini: weblogs.asp.net/imranbaloch/… , tetapi juga agak lama dan mungkin sudah ketinggalan zaman.
gligoran
1
Masih ada cara untuk mengecualikan parameter metode tertentu dari validasi, lihat jawaban saya di sini: stackoverflow.com/a/50796666/56621
Alex
51

Di ASP.NET MVC Anda perlu mengatur requestValidationMode = "2.0" dan validateRequest = "false" di web.config, dan menerapkan atribut ValidateInput ke tindakan controller Anda:

<httpRuntime requestValidationMode="2.0"/>

<configuration>
    <system.web>
        <pages validateRequest="false" />
    </system.web>
</configuration>

dan

[Post, ValidateInput(false)]
public ActionResult Edit(string message) {
    ...
}
ranthonissen
sumber
2
Bagi saya, validateRequest="false"itu tidak perlu, hanyarequestValidationMode="2.0"
tom redfern
requestValidationMode = "2.0" masih menghasilkan kesalahan dengan data HTMLencoded. Tidak ada solusi kecuali untuk base64 menyandikan semuanya, lalu kirimkan bersama.
MC9000
48

Anda dapat menyandikan konten kotak teks HTML , tetapi sayangnya itu tidak akan menghentikan pengecualian terjadi. Dalam pengalaman saya tidak ada jalan keluar, dan Anda harus menonaktifkan validasi halaman. Dengan melakukan itu Anda berkata: "Aku akan berhati-hati, aku janji."

Pavel Chuchuva
sumber
43

Untuk MVC, abaikan validasi input dengan menambahkan

[ValidateInput (false)]

di atas setiap Aksi di Controller.

A.Dara
sumber
Ini tampaknya tidak berfungsi jika ia sampai ke metode pengontrol melalui rute yang dikonfigurasi.
PandaWood
Sebenarnya, penjelasan teknis, adalah ini hanya berfungsi ketika karakter yang menyinggung berada di "string kueri" ... jika itu ada di jalur permintaan, atribut Validasi tidak berfungsi
PandaWood
42

Anda dapat menangkap kesalahan itu di Global.asax. Saya masih ingin memvalidasi, tetapi menunjukkan pesan yang sesuai. Di blog yang tercantum di bawah ini, sampel seperti ini tersedia.

    void Application_Error(object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError();

        if (ex is HttpRequestValidationException)
        {
            Response.Clear();
            Response.StatusCode = 200;
            Response.Write(@"[html]");
            Response.End();
        }
    }

Mengarahkan kembali ke halaman lain juga sepertinya merupakan respons yang masuk akal terhadap pengecualian.

http://www.romsteady.net/blog/2007/06/how-to-catch-httprequestvalidationexcep.html

BenMaddox
sumber
40

Jawaban atas pertanyaan ini sederhana:

var varname = Request.Unvalidated["parameter_name"];

Ini akan menonaktifkan validasi untuk permintaan tertentu.

flakomalo
sumber
1
Hanya berlaku untuk ASP.NET 4.5 (dan, mungkin, apa pun yang akan datang setelah itu.) Pra 4.5 tidak mendukung ini.
Beska
3
Saya berharap saya bisa bertemu dengan cara ini. Saya menggunakan .NET 4.5 dan ini persis apa yang saya butuhkan karena saya tidak menggunakan MVC dan saya tidak dapat mengubah web.config.
Chris Gillum
1
Ya tetapi bagaimana jika Anda menggunakan .Net 2? Beberapa dari kita tidak punya pilihan
Fandango68
ini mendapat parameter POST atau GET?
maksimal4
Apakah Anda mengatakan ini mencegah pengecualian yang sudah dibuang? Atau apakah .net 4.5 menunda pengecualian dan validasi hingga data benar-benar dibaca dari Request?
ebyrob
34

Harap diingat bahwa beberapa kontrol .NET akan secara otomatis menyandikan output HTML. Misalnya, mengatur properti .Text pada kontrol TextBox akan secara otomatis menyandikannya. Itu secara khusus berarti mengubah <menjadi &lt;, >menjadi &gt;dan &ke dalam &amp;. Jadi berhati-hatilah dalam melakukan ini ...

myTextBox.Text = Server.HtmlEncode(myStringFromDatabase); // Pseudo code

Namun, properti .Text untuk HyperLink, Literal, dan Label tidak akan menyandikan hal-hal HTML, jadi bungkus Server.HtmlEncode (); sekitar apa pun yang ditetapkan pada properti ini adalah suatu keharusan jika Anda ingin mencegah <script> window.location = "http://www.google.com"; </script>menjadi output ke halaman Anda dan kemudian dieksekusi.

Lakukan sedikit percobaan untuk melihat apa yang dikodekan dan apa yang tidak.

Peter Mortensen
sumber
29

Dalam file web.config, di dalam tag, masukkan elemen httpRuntime dengan atribut requestValidationMode = "2.0". Juga tambahkan atribut validateRequest = "false" di elemen halaman.

Contoh:

<configuration>
  <system.web>
   <httpRuntime requestValidationMode="2.0" />
  </system.web>
  <pages validateRequest="false">
  </pages>
</configuration>
Mahdi jokar
sumber
1
Bagi saya, validateRequest = "false" tidak diperlukan, hanya requestValidationMode = "2.0"
tom redfern
3
Bagian "halaman" harus berada di dalam bagian "system.web".
Carter Medlin
jawaban berbahaya, sekali lagi.
MC9000
Saya membutuhkan keduanya. Terima kasih
Jack
23

Jika Anda tidak ingin menonaktifkan ValidateRequest, Anda perlu menerapkan fungsi JavaScript untuk menghindari pengecualian. Ini bukan pilihan terbaik, tetapi berhasil.

function AlphanumericValidation(evt)
{
    var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode :
        ((evt.which) ? evt.which : 0));

    // User type Enter key
    if (charCode == 13)
    {
        // Do something, set controls focus or do anything
        return false;
    }

    // User can not type non alphanumeric characters
    if ( (charCode <  48)                     ||
         (charCode > 122)                     ||
         ((charCode > 57) && (charCode < 65)) ||
         ((charCode > 90) && (charCode < 97))
       )
    {
        // Show a message or do something
        return false;
    }
}

Kemudian dalam kode di belakang, pada acara PageLoad, tambahkan atribut ke kontrol Anda dengan kode berikutnya:

Me.TextBox1.Attributes.Add("OnKeyPress", "return AlphanumericValidation(event);")
Peter Mortensen
sumber
4
Ini masih akan membuat aplikasi rentan dari permintaan POST buatan. Seorang pengguna biasa akan mengalami masalah memasukkan karakter seperti,: atau kutipan, tetapi seorang peretas biasa tidak akan mengalami masalah POSTing data cacat ke server. Saya akan membatalkan waaay ini.
Radu094
13
@ Radu094: Solusi ini memungkinkan Anda untuk menjaga ValidateRequest = true, yang berarti peretas masih akan membentur tembok itu. Pilih, karena ini membuat Anda kurang rentan daripada mematikan ValidateRequest.
jbehren
21

Sepertinya belum ada yang menyebutkan di bawah ini, tetapi ini memperbaiki masalah untuk saya. Dan sebelum ada yang bilang ya itu Visual Basic ... huek.

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Example.aspx.vb" Inherits="Example.Example" **ValidateRequest="false"** %>

Saya tidak tahu apakah ada kerugian, tetapi bagi saya ini bekerja luar biasa.

Piercy
sumber
Bekerja untuk formulir web c # atau VB
TheAlbear
19

Solusi lain adalah:

protected void Application_Start()
{
    ...
    RequestValidator.Current = new MyRequestValidator();
}

public class MyRequestValidator: RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        bool result = base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);

        if (!result)
        {
            // Write your validation here
            if (requestValidationSource == RequestValidationSource.Form ||
                requestValidationSource == RequestValidationSource.QueryString)

                return true; // Suppress error message
        }
        return result;
    }
}
Sel
sumber
Bagus! Tidak mengetahui kemampuan untuk mengganti Validator Permintaan. Alih-alih hanya mengatakan "ok" seperti Anda, saya memperluas ide ini untuk tidak memvalidasi bidang yang berakhiran "_NoValidation" sebagai nama mereka. Kode di bawah ini.
Walden Leverich
Walden Leverich, untuk melakukan ini, lihat [AllowHtml] attribure
Sel
Sel, ya di lingkungan MVC yang akan bekerja. Tetapi dalam aplikasi webforms saya tidak memiliki model untuk melakukannya. :-)
Walden Leverich
15

Jika Anda menggunakan framework 4.0 maka entri di web.config (<halaman validateRequest = "false" />)

<configuration>
    <system.web>
        <pages validateRequest="false" />
    </system.web>
</configuration>

Jika Anda menggunakan framework 4.5 maka entri di web.config (requestValidationMode = "2.0")

<system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" requestValidationMode="2.0"/>
</system.web>

Jika Anda hanya menginginkan satu halaman saja, Dalam file aspx Anda, Anda harus meletakkan baris pertama seperti ini:

<%@ Page EnableEventValidation="false" %>

jika Anda sudah memiliki sesuatu seperti <% @ Halaman jadi tambahkan saja sisanya => EnableEventValidation="false"%>

Saya sarankan untuk tidak melakukannya.

Durgesh Pandey
sumber
13

Di ASP.NET, Anda dapat menangkap pengecualian dan melakukan sesuatu tentangnya, seperti menampilkan pesan ramah atau mengalihkan ke halaman lain ... Juga ada kemungkinan Anda dapat menangani validasinya sendiri ...

Tampilkan pesan ramah:

protected override void OnError(EventArgs e)
{
    base.OnError(e);
    var ex = Server.GetLastError().GetBaseException();
    if (ex is System.Web.HttpRequestValidationException)
    {
        Response.Clear();
        Response.Write("Invalid characters."); //  Response.Write(HttpUtility.HtmlEncode(ex.Message));
        Response.StatusCode = 200;
        Response.End();
    }
}
Jaider
sumber
13

Saya kira Anda bisa melakukannya dalam modul; tetapi itu membuka beberapa pertanyaan; bagaimana jika Anda ingin menyimpan input ke database? Tiba-tiba karena Anda menyimpan data yang disandikan ke database Anda akhirnya percaya input dari itu yang mungkin merupakan ide yang buruk. Idealnya Anda menyimpan data mentah tanpa kode di dalam basis data dan penyandian setiap waktu.

Menonaktifkan proteksi pada level per halaman dan kemudian menyandikan setiap waktu adalah pilihan yang lebih baik.

Daripada menggunakan Server.HtmlEncode Anda harus melihat perpustakaan Anti-XSS yang lebih baru dan lebih lengkap dari tim Microsoft ACE.

blowdart
sumber
12

Sebab

ASP.NET secara default memvalidasi semua kontrol input untuk konten yang berpotensi tidak aman yang dapat menyebabkan skrip lintas situs (XSS) dan injeksi SQL . Dengan demikian ia melarang konten tersebut dengan melemparkan pengecualian di atas. Secara default, direkomendasikan untuk memungkinkan pemeriksaan ini terjadi pada setiap postback.

Larutan

Pada banyak kesempatan Anda perlu mengirimkan konten HTML ke halaman Anda melalui Rich TextBoxes atau Rich Text Editor. Dalam hal ini, Anda dapat menghindari pengecualian ini dengan mengatur tag ValidateRequest dalam @Pagearahan ke false.

<%@ Page Language="C#" AutoEventWireup="true" ValidateRequest = "false" %>

Ini akan menonaktifkan validasi permintaan untuk halaman yang telah Anda atur tanda ValidateRequest menjadi false. Jika Anda ingin menonaktifkan ini, periksa seluruh aplikasi web Anda; Anda harus mengaturnya ke false di bagian web.config <system.web> Anda

<pages validateRequest ="false" />

Untuk .NET 4.0 atau kerangka kerja yang lebih tinggi Anda harus menambahkan baris berikut di bagian <system.web> untuk membuat pekerjaan di atas.

<httpRuntime requestValidationMode = "2.0" />

Itu dia. Saya harap ini membantu Anda dalam menyingkirkan masalah di atas.

Referensi oleh: Kesalahan ASP.Net: Nilai Request.Form yang berpotensi berbahaya terdeteksi dari klien

wakil
sumber
10

Saya menemukan solusi yang menggunakan JavaScript untuk menyandikan data, yang diterjemahkan dalam .NET (dan tidak memerlukan jQuery).

  • Jadikan textbox sebagai elemen HTML (seperti textarea) dan bukan ASP.
  • Tambahkan bidang yang tersembunyi.
  • Tambahkan fungsi JavaScript berikut ke tajuk Anda.

    function boo () {targetText = document.getElementById ("HiddenField1"); sourceText = document.getElementById ("userbox"); targetText.value = escape (sourceText.innerText); }

Di dalam textarea Anda, sertakan pertukaran yang memanggil boo ():

<textarea id="userbox"  onchange="boo();"></textarea>

Akhirnya, dalam. NET, gunakan

string val = Server.UrlDecode(HiddenField1.Value);

Saya sadar bahwa ini satu arah - jika Anda perlu dua arah, Anda harus kreatif, tetapi ini memberikan solusi jika Anda tidak dapat mengedit web.config

Berikut ini adalah contoh yang saya (MC9000) buat dan gunakan melalui jQuery:

$(document).ready(function () {

    $("#txtHTML").change(function () {
        var currentText = $("#txtHTML").text();
        currentText = escape(currentText); // Escapes the HTML including quotations, etc
        $("#hidHTML").val(currentText); // Set the hidden field
    });

    // Intercept the postback
    $("#btnMyPostbackButton").click(function () {
        $("#txtHTML").val(""); // Clear the textarea before POSTing
                               // If you don't clear it, it will give you
                               // the error due to the HTML in the textarea.
        return true; // Post back
    });


});

Dan markupnya:

<asp:HiddenField ID="hidHTML" runat="server" />
<textarea id="txtHTML"></textarea>
<asp:Button ID="btnMyPostbackButton" runat="server" Text="Post Form" />

Ini sangat bagus. Jika seorang hacker mencoba memposting melalui melewati JavaScript, mereka hanya akan melihat kesalahannya. Anda dapat menyimpan semua data yang disandikan dalam basis data juga, lalu menghapusnya (di sisi server), dan menguraikan & memeriksa serangan sebelum ditampilkan di tempat lain.

Jason Shuler
sumber
Ini solusi yang bagus. Ini adalah cara manual yang tepat untuk mengendalikannya sendiri dan tidak membatalkan seluruh situs web atau halaman
Fandango68
Pastikan untuk menggunakan markup HTML, bukan kontrol ASP.Net (yaitu tidak ada runat = "server") untuk textarea, lalu gunakan kontrol tersembunyi ASP.Net untuk yang tersembunyi. Ini adalah solusi terbaik yang pernah saya lihat tanpa kompromi apa pun. Tentu saja, Anda ingin mem-parsing data Anda untuk XSS, SQL Injection di sisi server, tetapi setidaknya Anda dapat memposting HTML
MC9000
escape(...)bisa memakan waktu lama. Dalam kasus saya, markup adalah seluruh file XML (2MB). Anda mungkin bertanya, "Mengapa Anda tidak menggunakan saja <input type="file"...dan ... Saya setuju dengan Anda :)
The Red Pea
10

Solusi lain di sini bagus, namun agak menyakitkan di bagian belakang harus menerapkan [AllowHtml] untuk setiap properti Model tunggal, terutama jika Anda memiliki lebih dari 100 model di situs berukuran layak.

Jika seperti saya, Anda ingin mematikan fitur (IMHO ini tidak berguna) di situs Anda dapat mengganti metode Execute () di pengontrol dasar Anda (jika Anda belum memiliki pengontrol basis, saya sarankan Anda membuatnya, mereka dapat cukup berguna untuk menerapkan fungsi umum).

    protected override void Execute(RequestContext requestContext)
    {
        // Disable requestion validation (security) across the whole site
        ValidateRequest = false;
        base.Execute(requestContext);
    }

Pastikan saja Anda meng-encode semua yang dipompa ke tampilan yang berasal dari input pengguna (itu adalah perilaku default dalam ASP.NET MVC 3 dengan Razor, jadi kecuali jika karena alasan aneh Anda menggunakan Html.Raw () Anda seharusnya tidak memerlukan fitur ini.

Magritte
sumber
9

Saya mendapatkan kesalahan ini juga.

Dalam kasus saya, pengguna memasukkan karakter beraksen ádalam Nama Peran (terkait penyedia keanggotaan ASP.NET).

Saya meneruskan nama peran ke metode untuk memberikan Pengguna peran itu dan $.ajaxpermintaan posting gagal total ...

Saya melakukan ini untuk memecahkan masalah:

Dari pada

data: { roleName: '@Model.RoleName', users: users }

Melakukan hal ini

data: { roleName: '@Html.Raw(@Model.RoleName)', users: users }

@Html.Raw melakukan trik.

Saya mendapatkan nama Peran sebagai nilai HTML roleName="Cadastro b&#225;s". Nilai ini dengan entitas HTML &#225;sedang diblokir oleh ASP.NET MVC. Sekarang saya mendapatkan nilai roleNameparameter seperti seharusnya: roleName="Cadastro Básico"dan mesin ASP.NET MVC tidak akan memblokir permintaan lagi.

Leniel Maccaferri
sumber
7

Anda juga dapat menggunakan fungsi pelarian (string) JavaScript untuk mengganti karakter khusus. Kemudian sisi server menggunakan Server. URLDecode (string) untuk mengubahnya kembali.

Dengan cara ini Anda tidak perlu mematikan validasi input dan akan lebih jelas bagi programmer lain bahwa string mungkin memiliki konten HTML.

Berbilah
sumber
7

Saya akhirnya menggunakan JavaScript sebelum setiap postback untuk memeriksa karakter yang tidak Anda inginkan, seperti:

<asp:Button runat="server" ID="saveButton" Text="Save" CssClass="saveButton" OnClientClick="return checkFields()" />

function checkFields() {
    var tbs = new Array();
    tbs = document.getElementsByTagName("input");
    var isValid = true;
    for (i=0; i<tbs.length; i++) {
        if (tbs(i).type == 'text') {
            if (tbs(i).value.indexOf('<') != -1 || tbs(i).value.indexOf('>') != -1) {
                alert('<> symbols not allowed.');
                isValid = false;
            }
        }
    }
    return isValid;
}

Memang halaman saya sebagian besar entri data, dan ada sangat sedikit elemen yang melakukan postback, tetapi setidaknya datanya tetap dipertahankan.

Ryan
sumber
Harus ada kurung besar, bukan kurung kecil. Seperti `if (tbs [i] .type == 'text') {` sebagai pengganti `if (tbs (i) .type == 'text') {`
Shilpa Soni
5

Anda dapat menggunakan sesuatu seperti:

var nvc = Request.Unvalidated().Form;

Nantinya, nvc["yourKey"]harus bekerja.

Ady Levy
sumber
Terima kasih, jawaban Anda menghemat banyak waktu saya
habib
4

Selama ini hanya karakter "<" dan ">" (dan bukan kutipan ganda itu sendiri) dan Anda menggunakannya dalam konteks seperti <input value = " this " />, Anda aman (sedangkan untuk <textarea > yang ini </textarea> Anda tentu saja akan rentan). Itu mungkin menyederhanakan situasi Anda, tetapi untuk hal lain gunakan salah satu solusi diposting lainnya.

Paweł Hajdan
sumber
4

Jika Anda hanya ingin memberi tahu pengguna Anda bahwa <dan> tidak boleh digunakan TETAPI, Anda tidak ingin seluruh formulir diproses / diposting kembali (dan kehilangan semua input) sebelumnya, bisakah Anda tidak dengan mudah memasukkan validator di sekitar lapangan untuk menyaring karakter (dan mungkin karakter berbahaya lainnya) yang lain?

Kapten Toad
sumber
posting mengatakan "validator" tolong
mxmissile
4

Tidak ada saran yang bekerja untuk saya. Saya tidak ingin mematikan fitur ini untuk seluruh situs web karena 99% waktu saya tidak ingin pengguna saya menempatkan HTML di formulir web. Saya baru saja membuat pekerjaan saya sendiri di sekitar metode karena saya satu-satunya yang menggunakan aplikasi khusus ini. Saya mengonversi input ke HTML dalam kode di belakang dan memasukkannya ke database saya.

Mike S.
sumber