年末にこの記事を読んで、早速WindowsのWebサーバーにパッチを適用しておいた。
ASP.NET Security Update Shipping Thursday, Dec 29th - ScottGu's Blog
対処されている脆弱性の詳細な説明はこちら。
徳丸浩の日記: Webアプリケーションに対する広範なDoS攻撃手法(hashdos)の影響と対策
ところが今日になってある業務アプリケーションで「エラーが起きる」との連絡があった。
エラーの内容は、
「Operation is not valid due to the current state of the object」
「The URL-encoded form data is not valid.」
というもの。
いろいろテストして見ると、どうやら年末に適用したセキュリティパッチが原因らしい。
ASP.NET MS11-100: how can I change the limit on the maximum number of posted form values? - Stack Overflow
An ASP.NET request that has lots of form keys, files, or JSON payload fails with an exception and returns a 500 HTTP status code
上のページに解決方法が書かれていたので、何とかエラーは解消した。
web.config の appSettings セクション内に次の設定を追加すれば良い。
<!-- Post Backで処理可能な最大フィールド数(Defaultは1000) -->
<add key="aspnet:MaxHttpCollectionKeys" value="5000"/>
設定する値が大きくなるほどPostBackで処理出来るフィールド数に余裕が出来る。
でも、増やしすぎるとセキュリティパッチの意味が無くなるのであまり良くないと思う。
そもそも1000以上ものフィールドをPostBackする様な画面を作るのがおかしい。
とは思うけれども、とりあえず以前動いていたものは動く様にしないと行けないので、当面はこれで回避するしかなさそうだ。
とは思うけれども、とりあえず以前動いていたものは動く様にしないと行けないので、当面はこれで回避するしかなさそうだ。
ちなみにエラーが起きたページは、GridViewの各行の中にCheckboxやDropdownが複数配置されていて、ボタンが押された時にグリッド内の全行に対して何らかの処理をするという作りになっていた。それで大体250行以上表示している場合に1000フィールドの制限に引っかかっていた模様。
もちろんページングして一度に表示される行数を少なくしておけば問題は起きないのだけれど、「1トランザクションで全データを対象に処理する」という要件があったためにあえてページングしない様になっていたらしい。
ASP.NETだと一つのFormタグの中に全部の画面要素が入るので、何も考えずに一昔前のVBの延長的な感覚で作ってしまうとすぐにこんな事になってしまう、という良くない例だ。
でも、クライアント・サーバー型システムから移植した様な業務アプリケーションでこういうケースって、実際には結構あるんだろうなあ。
もちろんページングして一度に表示される行数を少なくしておけば問題は起きないのだけれど、「1トランザクションで全データを対象に処理する」という要件があったためにあえてページングしない様になっていたらしい。
ASP.NETだと一つのFormタグの中に全部の画面要素が入るので、何も考えずに一昔前のVBの延長的な感覚で作ってしまうとすぐにこんな事になってしまう、という良くない例だ。
でも、クライアント・サーバー型システムから移植した様な業務アプリケーションでこういうケースって、実際には結構あるんだろうなあ。