CryptographicException: заполнение недопустимо и не может быть удалено, а проверка MAC-адреса viewstate не удалась

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

Заметки об окружающей среде:

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

Сделанные шаги:

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

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

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

    Page.ViewStateUserKey = viewStateKey;
  }

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

Ответ 1

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

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

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

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

Я изменяю функцию LoadPageStateFromPersistenceMedium(), которая преобразует viewstate и просматривает, записывая, что именно было входом, и из каких 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.

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

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

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

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

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

Вот мое окончательное решение с jQuery: (обратите внимание, что я проверяю на PageLoad, если существует eventvalidation!). У меня есть это на моих MasterPages.

<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); %>

Update

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

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

Ответ 2

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

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

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

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

Короче говоря, вот несколько идей и вещей, которые нужно искать:

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

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

Ответ 3

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