2012年3月13日 星期二

雖然你已經沒了,但我還是會難過

走在大賣場的餅乾區,隨手一拿,幾乎大部分的零食所標示的反式脂肪酸都寫 0,就連泡麵也都以顯著的標語寫著:『本產品絕不含防腐劑』,人家都已經做得這麼有誠意,只差沒跪在你面前發誓,難道你不給台灣廠商一個機會嗎?

我還特別挑了一盒孔雀餅乾。它不僅反式脂肪酸是 0 ,而且還是台灣製造,重點是它還增重 45 公克,就這樣,它上了我的推車,入了我家冰箱,也進了我的肚子。



在偶然的機會裡,說真的,機會不高。我拿起塵封已久的康健雜誌,翻到第 158 期的一篇:『零反式脂肪酸,真的嗎?』它裡面有提到:

自政府於 2008 年規定,如果產品原料未使用氫化加工工序,且含量在 0.3 克/ 100 克以下,反式脂肪酸一欄即可標示為「」。

0  +  0  +  0  ≠   0


這數學式還真的走入了你我的日常生活當中,你會對這完美的數據感到高興,還是更顯不安呢?往好處想,世界衛生組織建議每人每天的攝取量以不超過 2 公克為限,0 與 2 之間,似乎還有著一些些的距離...

但是切記,別買「樂天小熊餅乾」給你們家寶貝吃,因為在康健雜誌於 2011年11月8日 ~11月11日 所抽查的報告中,它的反式脂肪酸是 4.09 。



參考:
01:康健雜誌 158 期
02:零反式脂肪,真的嗎?
03:小心隱形的油脂殺手-反式脂肪!

不會吧!又掛了

[InvalidOperationException: 由於該物件目前的狀態,導致作業無效。]
   System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded() +2692482
   System.Web.HttpValueCollection.FillFromEncodedBytes(Byte[] bytes, Encoding encoding) +61
   System.Web.HttpRequest.FillInFormCollection() +148

[HttpException (0x80004005): URL 編碼型式資料無效。]
   System.Web.HttpRequest.FillInFormCollection() +206
   System.Web.HttpRequest.get_Form() +68
   System.Web.HttpRequest.get_HasForm() +8743911
   System.Web.UI.Page.GetCollectionBasedOnMethod(Boolean dontReturnNull) +97
   System.Web.UI.Page.DeterminePostBackMode() +63
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +133


出現上面錯誤訊息時,正想要設個中斷點來看看到底哪邊發生錯誤,沒想到,連 Page_Load 事件都還沒進去,且遺言也還沒交待清楚,畫面就已經死掉了。

原來,在 2011 年12月,於德國的 Chaos Communication Congress 會議中,有人展示了透過少量的 Http Request 就可以讓網頁站台變得很忙碌,沒多久就可以讓網站忙到無法再回應新的 Http Reguest 請求而達到阻斷服務攻擊(Denial of Service)的效果。

隨後,在保哥的文章中找到一篇相關文章,於其技術摘要說明裡指出:


我們在開發 ASP.NET 網站時通常都會使用 Request.Form 物件來取得透過瀏覽器 POST 過來的資料,而此物件型別為 NameValueCollection 類別,該類別儲存 Key 的方式是透過雜湊運算的方式計算出來的 (hash-table data-structures),主要目的就是為了用極快的速度找到該 Key 的對應資料,不過此類別自行實做了有別於 .NET Framework 內建的雜湊演算法,它會將所有傳入的 Key 都先轉換為大寫,並使用名為 DJBX33X (Dan Bernstein's times 33, XOR) 的雜湊演算法進行計算,這將導致此演算法有機會遭到 Meet-in-the-middle 攻擊。

駭客能利用這個弱點實做出輕易可達成的 雜湊碰撞攻擊 (Hash collision attacks),此類攻擊可透過傳入大量的 POST 資料並且夾帶許多特別計算過的 Key 值,讓這些 Key 值在這些 Hash-table 中產生出相同的雜湊值,如此一來在這個 Hash-table 中就會出現許多擁有相同雜湊值的 Key,這便是「雜湊碰撞」的由來。而這類雜湊碰撞的情況正是 DJBX33X 演算法的致命傷,當一個 NameValueCollection 中存在著過多的「雜湊碰撞」就會導致電腦花上許多時間對該 Hash-table 進行運算,所以會讓 ASP.NET 執行緒花上數十分鐘到數小時的時間來操作相對應的 Key 值,如此一來便會耗盡網站伺服器的 CPU 資源,進而達到阻斷服務的目的。


就在 Chaos Communication Congress 會議之後,微軟很迅速的將這弱點進行了補強,也提供了 windows update 的服務,基本上,只要你的電腦有乖乖接受每個微軟的安全更新,理論上都已經可以避免如上所說的攻擊手法了,只是,微軟做了甚麼補強?

微軟開始重訂了一個遊戲規則。要求大家 Post 到後台的物件項目不可以超過 1000 個。包括以下:


1.<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
2.<input type="hidden" id="h_field" runat="server">
3.有已挑選值的 DropDownList (如果下拉清單裡面沒有任何資料,則不算)
4.有已挑選值的RadioButton(如果 RadioButton 裡面沒有任何被選取的資料,則不算)
5.有已挑選值的CheckBox(如果 CheckBox 裡面沒有任何被選取的資料,則不算)
6.有已挑選值的ListBox(如果 ListBox 裡面沒有任何被選取的資料,則不算)

自己詳細檢查了一下出錯的那一頁程式,上面的輸入控制項的確玲郎滿目啊!!

不過,剛開始對於微軟這種補強方法,還真的有點失落,心裡滴咕著,這算甚麼補強嘛,是補弱吧~那真的有需要使用到這麼多欄位需求時,難道得跟客戶說:


事實並非如此的。雖然微軟預設只提供上限 1000 ,但如果有更大的需求時,可以在 web.config 裡的 <appSettings> 加上 :

<add key="aspnet:MaxHttpCollectionKeys" value="2500" />

數值 value 可依實際你所想要允許的最大數量來決定。

Denial of Service 攻擊,的確是一種很難克服的難題。就算你的程式本身沒有問題,還是很有機會被攻擊,更何況被有心人士找到漏洞呢。相信日後這種攻擊手法,會越來越常見。這次微軟非常迅速的發佈更新,讓所有的 .Net 網站可以降低被攻擊的機率,真的值得讚賞。只是,我並沒有因此而得到特別的喜悅。因為我是接到來電說:「paladin,快來看,你的系統當掉了!」。


參考:

01:ASP.NET 發現重大資安弱點影響範圍涵蓋 ASP.NET 1.1 ~ 4.0
02:具有大量表單金鑰、檔案或 JSON 裝載成員的 ASP.NET 請求失敗,並產生例外狀況
03:ASP.NET Security Update Shipping Thursday, Dec 29th

2012年3月7日 星期三

自動調整 iframe 高度


以前使用 iframe 時,總是無可避免當 iframe 裡的資料過長時,就得透過 scroll bar 來捲動,如果刻意將 iframe 的高度設很高,則又擔心有些時候會太浪費網頁版面,如果能夠讓 iframe 依據內容而調整高度,似乎是個比較有彈性的作法。


關於這個想法,在網路上找到兩種類似的作法。


一、Lost-In-Code
在這個網站,提供了一個方便你外掛的 javascript,jquery.autoheight.js。日後只需要將 iframe 的 class 設定為 『autoHeight』,就能夠自動調整 iframe 的高度了。雖然他取名為 jquery,但仔細去觀察 jquery.autoheight.js 這隻程式,裡面並沒有用到 jquery 的語法。作者雖然在他的網頁上註明要引用 jquery 函式庫,但我發現,不引用也是可以的。但實際操作上,自己有遇到一個問題,就是去點選瀏覽器右上方的「最大化/往下還原」時,因為不會重算父親的高度而因此破功。所以自己再加上 $(window).resize() 去重算就可以解決。也因為如此,我還是把 jquery 引用進去好了。


    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery.autoheight.js" type="text/javascript"></script>
    <script>
        $(function () {
            //攔 resize 事件,並呼叫 jquery.autoheight.js 的 doIframe() 方法
            $(window).resize(function () {               
                doIframe();                
            });
        });
    </script>

<body>
    <form id="form1" runat="server">
    <div>
    <div class="dean_ch">這是父親頁面</div>
    以下是 iframe <br />
    <iframe width="100%" src="FrameA.aspx"  scrolling="auto" frameborder="0"  class="autoHeight" id="ifA"></iframe>    
    </div>
    </form>
</body>

另外 『91』與 『梅問題』 也針對這方法做了介紹,可以參考。


二、Phine Solutions
這個方式適用於每個 iframe,自己去控制呼叫者(父親)所設定的高度。此外,為了處理「最大化/往下還原」的問題,也加上 $(window).resize() 的處理。

    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script>
        function DoAdjHeight() {
            var theFrame = $("iframe", parent.document.body);
            theFrame.each(function () {
                $(this).height($(document.body).height() + 35);
            });
        }
        $(function () {

            DoAdjHeight();

            $(window).resize(function () {
                DoAdjHeight();
            });


        });
    </script>



以上兩種方法,發現它們都會在程式裡面加上一個特別數字 35,似乎是一種最適切的高度位置吧!自己曾經刻意將瀏覽器的縮放比例任意變大變小,的確在有些情況,上述的兩種方式也會突然冒出 scroll bar ,但這種特殊的操作行為,或許可以當成例外,畢竟會這樣使用的人不多;但果真要去處理的話,可能就要去調整這特別的數字。目前,我將他設定為100,幾乎任何縮放比例都可以顯示正常。所以這地方,如果有需要時才去調整這參數會比較適當。

測試程式下載 】
於測試程式中,TestA.aspx 是使用 Lost-In-Code 的方法,而 TestB.aspx 則是使用 Phine Solutions。



參考:
01:http://www.lost-in-code.com/programming/jquery-auto-iframe-height/ (lost-in-code)
02:http://www.dotblogs.com.tw/hatelove/archive/2010/08/12/javascript-iframe-autoheight.aspx (91)
03:http://www.phinesolutions.com/use-jquery-to-adjust-the-iframe-height.html (Phine Solutions)
04:http://www.minwt.com/?p=2425