
Ataki XSS, polegają najczęściej na przekazaniu skryptu JavaScript, którego zadaniem jest zaszkodzić. Bronić się przed nimi można na wiele sposobów. W tym wpisie wykorzystuje ASP WebForms, ale wszystko co zostanie opisane można zastosować w aplikacjach ASP MVC.
Domyślnie strony ASP są chronione przed atakami XSS. Możemy się o tym przekonać budując prosty formularz z polem tekstowym w który można wpisać skrypt:
Przy próbie przesłania takiego formularza, serwer zwróci błąd:
Jest to spowodowane pewnym wpisem, lub jego brakiem (domyśla wartość true) w pliku web.config:
Niekiedy istnieje potrzeba wyłączenia tego mechanizmu (najczęściej na pojedynczych stronach w obrębie aplikacji), np. kiedy chcemy umożliwić użytkowniki formatowanie wpisów przy pomocy znacznik HTML.
Mam prosty formularz:
1 2 3 4 5 6 7 8 |
<form id="form1" runat="server"> <div> <asp:Label runat="server">Wpis</asp:Label><br /> <asp:TextBox TextMode="multiline" Columns="30" Rows="3" runat="server" ID="textBoxXss"></asp:TextBox><br /> <asp:Button runat="server" OnClick="buttonSaveClick" Text="Zapisz" /><br /> <asp:Literal runat="server" ID="literalXss" /> </div> </form> |
Jego obsługa:
1 2 3 4 5 6 7 |
protected void buttonSaveClick(Object sender, EventArgs e) { if(!string.IsNullOrEmpty(textBoxXss.Text)) { literalXss.Text = "Twój wpis to: " + textBoxXss.Text; } } |
Całość po wpisaniu skryptu JavaScript wygląda tak:
Jak się bronić? Jest wiele sposobów. Jednym z nich jest użycie funkcji Server.HtmlEncode:
1 |
literalXss.Text = "Twój wpis to: " + Server.HtmlEncode(textBoxXss.Text); |
Jak widać działa, ale co zrobić gdy chcemy formatować tekst np. przy pomocy znaczników „<b>” czy „<i>”? Można zrobić taki trik:
1 2 3 4 5 6 7 8 |
StringBuilder sb = new StringBuilder(HttpUtility.HtmlEncode(textBoxXss.Text)); sb.Replace("<b>", "<b>"); sb.Replace("</b>", "</b>"); sb.Replace("<i>", "<i>"); sb.Replace("</i>", "</i>"); literalXss.Text = "Twój wpis to: " + sb.ToString(); |
Wybiórcze dodawanie dozwolonych tagów, może być nieco kłopotliwe, w miarę zwiększania ich ilości. Żeby temu zaradzić można napisać metodę RemoveXss, która wykorzystuje wyrażenia regularne:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public string RemoveXss(string input) { string result = RemoveXssHtmlTags(input); result = RemoveOnXssAttribute(result); return result; } public string RemoveXssHtmlTags(string input) { string result = Regex.Replace( input, @"</?(?i:applet|body|embed|frame|script|frameset|html|iframe|img|style|layer|link|ilayer|meta|object)(.|\n|\s)*?>", string.Empty, RegexOptions.Singleline | RegexOptions.IgnoreCase ); return result; } public string RemoveOnXssAttribute(string input) { string result = Regex.Replace( input, @"(<[\s\S]*?) on.*?\=(['""])[\s\S]*?\2([\s\S]*?>)", delegate(Match match) { return String.Concat(match.Groups[1].Value, match.Groups[3].Value); }, RegexOptions.Compiled | RegexOptions.IgnoreCase); return result; } |
Jej użycie jest bardzo proste:
1 |
literalXss.Text = "Twój wpis to: " + RemoveXss(textBoxXss.Text); |
Najnowsze komentarze