Regex для удаления атрибутов onclick = "" из элементов HTML в ASP.NET C # (на стороне сервера) - PullRequest
2 голосов
/ 07 октября 2009

Я пытаюсь написать функцию регулярного выражения для удаления атрибутов onclick (также onload, onmouseover и т. Д.) Из элементов HTML. Я хочу сделать это на стороне сервера перед отправкой HTML-кода клиенту.

У меня есть контент, исходящий из редактора Rich Text и отображаемый на экране в div, и я хочу защитить от XSS (межсайтового скриптинга). Очевидно, что я не могу HTML кодировать его с помощью Server.HtmlEncode (), потому что форматированный текст хранит текст как разметку HTML, поэтому я использую черный список, ища определенные элементы, такие как <script> и <style>. Сейчас я пытаюсь найти атрибуты onclick, onmouseover и т. Д., Пока у меня есть следующее:

returnVal = Regex.Replace(returnVal, @"\<(.*?)(\ on[a-z]+\=\""?.*?\""?)*(.*?)\>",
               "<$1 $3>", RegexOptions.Singleline | RegexOptions.IgnoreCase);

... что не работает, и я попробовал несколько вариантов. В принципе, я хочу, чтобы ...

<p style="font-style: italic" onclick="alert('hacked!!');">Hello World</p>

превращается в ...

<p style="font-style: italic">Hello World</p>

Есть идеи? Ура!

Ответы [ 4 ]

2 голосов
/ 07 октября 2009

Попробуйте это регулярное выражение:


returnValue = 
    Regex.Replace(
        returnValue,
        @"(<[\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);

НТН

1 голос
/ 05 апреля 2011

Вы можете сохранить старое возвращаемое значение, а затем выполнить проверку в цикле while, чтобы увидеть, не изменилось ли ничего, если так вышло из цикла

if(oldContent.Equals(newContent)) { break; }
0 голосов
/ 15 июля 2015

вот так.

if (!String.prototype.replaceAll) {
  (function() {
    String.prototype.replaceAll = function(target, replacement) {
      return this.split(target).join(replacement);
    };
  })();
};

html = html.replaceAll(/onclick.*?\=(['""])[\s\S]*(['""])/ig,"");
console.log(html);

результат: <p style="font-style: italic">Hello World</p>

0 голосов
/ 07 октября 2009

Это ответ на 'Rubens Farias' с примером кода, который я придумал. Я использовал цикл while так ...

while (Regex.IsMatch(returnVal, @"(<[\s\S]*?) on.*?\=(['""])[\s\S]*?\2([\s\S]*?>)", RegexOptions.Compiled | RegexOptions.IgnoreCase))
{
    returnVal = Regex.Replace(returnVal, @"(<[\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);
}

Для тех, кто заинтересован, вот весь метод, который я использую для защиты от XSS ...

/// <summary>
///     'Helps' protect against XSS (Cross Site Scripting attacks) by stripping out known evil HTML elements
///     such as script and style. Used for outputing text generated by a Rich Text Editor. Doesn't HTML encode!
/// </summary>
/// <param name="input">Input string to strip bad HTML elements from</param>
public static string XSSProtect(string input)
{
    string returnVal = input ?? "";

    returnVal = Regex.Replace(returnVal, @"\<script(.*?)\>(.*?)\<\/script(.*?)\>", "", RegexOptions.Singleline | RegexOptions.IgnoreCase);
    returnVal = Regex.Replace(returnVal, @"\<style(.*?)\>(.*?)\<\/style(.*?)\>", "", RegexOptions.Singleline | RegexOptions.IgnoreCase);

    while (Regex.IsMatch(returnVal, @"(<[\s\S]*?) on.*?\=(['""])[\s\S]*?\2([\s\S]*?>)", RegexOptions.Compiled | RegexOptions.IgnoreCase))
    {
        returnVal = Regex.Replace(returnVal, @"(<[\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 returnVal;
}
...