CryptographicException: заполнение недопустимо и не может быть удалено, а проверка MAC состояния представления завершилась неудачно - PullRequest
9 голосов
/ 30 ноября 2009

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

Примечания об окружающей среде:

IIS 6.0, .NET 3.5 SP1 один сервер ASP.NET-приложение

Шаги уже сделаны:

  <system.web>
    <machineKey validationKey="big encryption key"
      decryptionKey="big decryption key"
      validation="SHA1" decryption="AES" />

В моей базе страниц для всех моих страниц

  protected override void OnInit(EventArgs e)
  {
    const string viewStateKey = "big key value";

    Page.ViewStateUserKey = viewStateKey;
  }

Также в исходном коде страницы видно, что все сгенерированные в ASP.NET скрытые поля правильно расположены вверху страницы.

Ответы [ 3 ]

19 голосов
/ 31 марта 2010

Прежде всего давайте начнем с того, что эта ошибка состояния просмотра происходит на PostBack .

Также я должен сказать , что я сделал все, что каждый из них предлагает , чтобы избежать этой проблемы. И у меня есть одна машина, но 2 пула, которые работают с одинаковыми страницами.

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

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

Я изменяю функцию LoadPageStateFromPersistenceMedium () , которые переводят состояние просмотра и просматривают, регистрируя, что именно было входом, и с каких IP-адресов ... затем я начал отслеживать эти результаты и увидите, что состояние просмотра было изменено вручную - или было полностью пустым.

При ошибке я просто перенаправляю его на ту же страницу ...

Вот что я сделал ...

public abstract class BasePage : System.Web.UI.Page
{
    protected override object LoadPageStateFromPersistenceMedium()
    {
        try
        {
            .. return the base, or make here your decompress, or what ever...
            return base.LoadPageStateFromPersistenceMedium();            
        }
        catch (Exception x)
        {
            string vsString = Request.Form[__VIEWSTATE];
            string cThePage = Request.RawUrl;

            ...log the x.ToString() error...
            ...log the vsString...
            ...log the ip coming from...
            ...log the cThePage...

        // check by your self for local errors
            Debug.Fail("Fail to load view state ! Reason:" + x.ToString());
        }

        // if reach here, then have fail, so I reload the page - maybe here you
        // can place somthing like ?rnd=RandomNumber&ErrorId=1 and show a message
        Responce.Redirect(Request.RawUrl, true);        

        // the return is not used after the redirect
        return string.Empty;
    }    
}

Вторая причина

Теперь есть еще одна причина, по которой это может произойти, и причина в том, что кто-то одним щелчком мыши на вашей странице загружает __EVENTVALIDATION.

Это событие Validation помещается на последнюю кнопку, даже если asp.net обнаружил, и если у вас есть некоторые из них на многих местах на странице или рядом с кнопкой, то это переходит в конец страницы.

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

<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" ... >

Чтобы избежать такого рода проблем, я сделал простой javascript, который не позволяет нажимать кнопку, если этот вход не был загружен !!!.

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

Вот мое окончательное решение с jQuery: (обратите внимание, что я проверяю на PageLoad, существует ли проверка событий!). Я разместил это на своих главных страницах.

<script language="javascript" type="text/javascript">
    function AllowFormToRun()
    {
        var MyEventValidation = $("#__EVENTVALIDATION");

        if(MyEventValidation.length == 0 || MyEventValidation.val() == ""){
            alert("Please wait for the page to fully loaded.");
            return false;
        }

        return true; 
    }       
</script>

protected void Page_Load(object sender, EventArgs e)
{
    // I do not know if Page can be null - just in case I place it.
    if (Page != null && Page.EnableEventValidation)
    {
        Form.Attributes["onsubmit"] = "return AllowFormToRun();";
    }
}

Вы можете проверить, разместив возле кнопки вашей страницы задержку.

<% System.Threading.Thread.Sleep(5000); %>

Обновление

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

Надеюсь, это поможет вам больше.

3 голосов
/ 31 марта 2010

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

Существование множества похожих, но разных ситуаций, вероятно, связано с очень многими различными архитектурами и базовыми конфигурациями, которые могут каким-то образом привести к неспособности криптоуровня утверждать подлинность MAC (кодов аутентификации сообщений) в страницы запроса:

  • Настройка фермы серверов
  • Междоменные / синдицированные страницы
  • сторонние библиотеки виджетов и тому подобное
  • Фактическая логика программы ASP (конечно)

Одним из довольно частых «маркеров» в этих отчетах об ошибках является упоминание запросов ресурсов (например, WebResource.axd ).
Обратите внимание, что такие запросы часто не регистрируются (чтобы они не увеличивали размер файлов журнала с помощью события, представляющего небольшой интерес). Это отсутствие в файле журнала и тот факт, что они часто кэшируются (и, следовательно, относительное случайное и нечастое появление ошибки), может объяснить, как это возможное происхождение ошибки идет «под радаром». Это также говорит о том, что при попытке воссоздать ошибку (при отслеживании в журналах, в режиме реального времени и т. Д.) Может быть полезно предотвратить кэширование в веб-браузере (или, по крайней мере, сначала очистить его кеш).

Вкратце, вот несколько идей и вещей для поиска:

  • начать регистрировать * .axd запросы
  • попытаться связать такие запросы axd с событиями ошибок в журнале исключений
  • поиск страниц со ссылками на ресурсы
  • при настройке фермы убедитесь, что все экземпляры используют один и тот же ключ (очевидно, фрагмент, приведенный в подсказке к вопросу на нескольких серверах IIS)
  • С подозрением относитесь к страницам со сторонними привязками (службы поиска, партнерские программы ...)

Надеюсь, это поможет; -)

1 голос
/ 26 марта 2010

Вы уверены, что ваша проблема связана с криптографией, а не вызвана слишком большим ViewState? Если ViewState является проблемой, вы можете разделить ее на части - измените значение pages / MaxPageStateFieldLength в web.config

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