Проверка регулярного выражения для memo-поля (на стороне клиента и сервера) с несколькими специальными тегами - PullRequest
0 голосов
/ 29 сентября 2018

Два дня безуспешно пытались решить эту проблему.Я использую asp.net webapi2 с jquery ajax на стороне клиента.

У меня есть поле для ввода текста заметки, допустимые символы: ^[©a-zA-Z0-9\u0900-\u097f,\.\s\-\'\"!?\(\)\[\]]+$ и два тега <LineBreak/> и <Link attr="value"/> (может быть парадополнительных атрибутов в теге Link. Проблема в том, что никакие другие теги недопустимы - это означает, что даже простой <br/> следует предотвратить. Эта отрицательная проверка оказывается немного сложной.

Запрос помощи в формулированиирегулярное выражение для javascript на стороне клиента и проверка аннотаций на основе c # на стороне сервера.

Ответы [ 2 ]

0 голосов
/ 30 сентября 2018

Управляется с помощью комбинации аннотаций данных RegularExpression, которая допускает угловые скобки (таким образом, пользовательские теги)

[RegularExpression(@"([©a-zA-Z0-9\u0900-\u097f,\.\s\-\'\""!?\(\)\[\]\<\>\/]*)")]

и класс ValidationAttribute, который проверяет наличие нежелательных тегов (кроме LineBreak и Link)

public class CustomTagValidatorAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        Regex re = new Regex(@"(<(?!(LineBreak\s*|Link\s+[\s\w\'\""\=]*)\/?>))", RegexOptions.Multiline);
        return re.Match(value.ToString()).Length == 0 ? ValidationResult.Success : new ValidationResult(Resources.ErrorStrings.InvalidValuesInRequest);
    }
}

Оба атрибута применяются к свойству класса, как показано ниже -

[CustomTagValidator]
[RegularExpression(@"([©a-zA-Z0-9\u0900-\u097f,\.\s\-\'\""!?\(\)\[\]\<\>\/]*)")]
public string PropertyToValidate { get; set; }

Также добавлен атрибут ActionFilterAttribute для проверки выполнения проверки перед вызовом действия контроллера -

public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ModelState.IsValid == false)
        {
            actionContext.Response = actionContext.Request.CreateErrorResponse(
                HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    }
}

и применил это к соответствующему действию контроллера, как показано ниже -

    [ValidateModel]
    public HttpResponseMessage Post([FromBody] MyModel mm)

Надеюсь, это поможет кому-то застрять в подобных проблемах.

Почти забыл, то же решение было применено на стороне клиента с использованием того жеПроверка подлинности на основе регулярных выражений JavaScript.

0 голосов
/ 29 сентября 2018

То, что вы пытаетесь сделать, - это очистить пользовательский ввод, однако использование JavaScript и Regex - неправильный способ сделать это.

Не беспокойтесь о проверке пользовательского ввода в интерфейсе,по крайней мере пока, фокус должен быть сначала проверен на стороне сервера, и лучший инструмент для работы - HtmlSanitizer .По их словам:

HtmlSanitizer - это библиотека .NET для очистки HTML-фрагментов и документов от конструкций, которые могут привести к атакам XSS.

HtmlSanitizer можно настроить на нескольких уровнях:

  • Настройте разрешенные теги HTML через свойство AllowedTags.
  • Настройте допустимые атрибуты HTML с помощью свойства AllowedAttributes.
  • Настройка разрешенных имен свойств CSS с помощью свойства AllowedCssProperties.
  • Сконфигурируйте разрешенные CSS-at-правила через свойство AllowedAtRules.
  • Настройте разрешенные схемы URI через свойство AllowedSchemes.
  • Настройка атрибутов HTML, содержащих URI (например, «src», «href» и т. Д.)
  • Укажите базовый URI, который будет использоваться для разрешения относительных URI по отношению к.
  • Отменяемые события генерируются до удаления тега, атрибута или стиля.

Я смоделировал демо на dotnetfiddle.net , используя эту библиотеку для васиграть с

void Main()
{
    var allowedTags = new[]{"LineBreak", "Link"};
    var allowedAttributes = new[]{"attr"};
    var sanitizer = new HtmlSanitizer(allowedTags: allowedTags, allowedAttributes: allowedAttributes);
    //sanitizer.
    var html = @"<script>alert('xss')</script><div onload=""alert('xss')""" + @"style=""background-color: test"">Test<img src=""test.gif""" + @"style=""background-image: url(javascript:alert('xss')); margin: 10px""></div>
    <LineBreak></LineBreak>

    <Link attr=""v123""/>";
    var sanitized = sanitizer.Sanitize(html);
    Console.WriteLine(sanitized);
}

Edit

Но хотелось бы знать, почему «регулярное выражение - неправильный способ сделать это».

Regex не предназначен для задач такого типа, вам нужно иметь возможность анализировать html-документ, то есть анализировать его теги, атрибуты и значения внутри этих атрибутов в древовидной структуре, чтобы иметь возможность правильно его дезинфицировать, потому что есть толькослишком много крайних случаев, которые слишком сложно покрыть только с помощью регулярных выражений.Regex лучше использовать для извлечения данных из источника, который уже находится в предсказуемой структуре, пользовательский ввод не является одной из таких вещей.

Несмотря на то, что ваш сценарий использования достаточно прост, вы все равно позволяете пользователямвведите HTML, который будет отображаться другим пользователям в его необработанном формате, чтобы все, что вы пропустили, доставило вам головную боль.

Вот шпаргалка XSS Filter Evasion от OWASP, если бы Regex мог охватить все перечисленное здесь, я бы сказал, хорошо, но добиться такого в Regex так сложно, что он просто неЭто не имеет смысла.

HtmlSanitizer, с другой стороны, охватывает проблемы, перечисленные в этой шпаргалке, он также активно поддерживается и специально создан именно для такого рода приложений, он также не громоздкий, онможет выполнять большие задачи очистки с временем обработки в диапазоне 50-100 мс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...