<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>程式設計 遇上 小提琴 &#187; 資訊安全</title>
	<atom:link href="http://blog.ez2learn.com/category/%e8%b3%87%e8%a8%8a%e5%ae%89%e5%85%a8/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ez2learn.com</link>
	<description>Victor&#039;s個人部落格，關於程式設計與小提琴</description>
	<lastBuildDate>Tue, 07 Feb 2012 03:26:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>那些台灣軟體產業所缺少的 &#8211; 自動化測試</title>
		<link>http://blog.ez2learn.com/2011/10/20/taiwan-software-lacking-of-auto-testing/</link>
		<comments>http://blog.ez2learn.com/2011/10/20/taiwan-software-lacking-of-auto-testing/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 13:15:23 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[分享]]></category>
		<category><![CDATA[嘴砲]]></category>
		<category><![CDATA[資訊安全]]></category>
		<category><![CDATA[單元測試]]></category>
		<category><![CDATA[軟體工程]]></category>
		<category><![CDATA[軟體品質]]></category>
		<category><![CDATA[軟體測試]]></category>
		<category><![CDATA[自動化測試]]></category>
		<category><![CDATA[Jenkins]]></category>
		<category><![CDATA[整合測試]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=1619</guid>
		<description><![CDATA[你是否有計算過，你在寫專案的過程中，測試過了多少次的程式? 我想是沒有，我也沒有，但是你是否有曾想過，或是感覺過，隨著專案的膨漲，你要測試的項目也跟著變多了? 這是理所當然的事情，當專案小，測試還算很輕鬆，因為程式的功能不外乎就那幾樣，一轉眼就測完了，常見的寫程式流程會像這樣 撰寫新功能 測試新功能 當然，也有修正bug的情況 修正bug 測試bug 如此一直循環，當你寫了新功能，理所當然地會去測試新功能，看是否如你預期地執行，那舊功能呢? 或許你記憶力不錯，在寫新功能的同時，想到先前某個舊功能是依賴現在改的東西，這麼一改可能會造成舊的功能出問題，於是你也順便測了一下舊的功能，當程式還小 撰寫新功能 測試新功能 測試舊功能 嘿，不怎麼樣吧? 只佔了開發時間的三分之一，好吧那如果有更多的舊功能要測呢? 撰寫新功能 測試新功能 測試舊功能 測試舊功能 測試舊功能 &#8230;. 發現了沒有? 隨著你的專案越來越大，如果要確保整個系統所有的功能都是正常運作的，無可避免地，在你修改程式之後要測試的項目會越來越多 這表示你每寫一行新程式的成本增加了，身為以減低成本為傲的島國 國民: 台灣人&#8230;，你說，簡單! 不要測舊功能不就好了? 是的，我想這可能就是最常見的情況，不要測試舊功能理所當然地，每寫一行的程式成本都保持一樣很低，但這代表著舊程式可能出錯的風險也跟著增加了，當你喜滋滋地覺得你幫公司省了成本，結果在一個月後因為舊程式缺乏測試，因改動了核心的部份造成舊的功能將所有資料外洩，公司損失慘重，這就是不重視軟體品質的後果 舉真實生活上發生過的例子，PTT曾經有過改程式未經好好地測試，造成每個人都能以管理員的權限登入的事情，知名的檔案同步平台Dropbox，也曾經發生過因為認證的程式改版有bug，造成任何人都可以登入別人帳號的事，我也有曾聽聞一些網站因為工程師為了測試方便，把認證的函數暫時改成 function authenticate&#40;user_id, password&#41; &#123; return true; // do authentication here // &#8230; <a href="http://blog.ez2learn.com/2011/10/20/taiwan-software-lacking-of-auto-testing/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>你是否有計算過，你在寫專案的過程中，測試過了多少次的程式? 我想是沒有，我也沒有，但是你是否有曾想過，或是感覺過，隨著專案的膨漲，你要測試的項目也跟著變多了? 這是理所當然的事情，當專案小，測試還算很輕鬆，因為程式的功能不外乎就那幾樣，一轉眼就測完了，常見的寫程式流程會像這樣</p>
<blockquote><p>撰寫新功能</p>
<p>測試新功能</p></blockquote>
<p>當然，也有修正bug的情況</p>
<blockquote><p>修正bug</p>
<p>測試bug</p></blockquote>
<p>如此一直循環，當你寫了新功能，理所當然地會去測試新功能，看是否如你預期地執行，那舊功能呢? 或許你記憶力不錯，在寫新功能的同時，想到先前某個舊功能是依賴現在改的東西，這麼一改可能會造成舊的功能出問題，於是你也順便測了一下舊的功能，當程式還小</p>
<blockquote><p>撰寫新功能</p>
<p>測試新功能</p>
<p>測試舊功能</p></blockquote>
<p>嘿，不怎麼樣吧? 只佔了開發時間的三分之一，好吧那如果有更多的舊功能要測呢?</p>
<blockquote><p>撰寫新功能</p>
<p>測試新功能</p>
<p>測試舊功能</p>
<p>測試舊功能</p>
<p>測試舊功能</p>
<p>&#8230;.</p></blockquote>
<p>發現了沒有? 隨著你的專案越來越大，如果要確保整個系統所有的功能都是正常運作的，無可避免地，在你修改程式之後要測試的項目會越來越多</p>
<p>這表示你每寫一行新程式的成本增加了，身為以減低成本為傲的島國 國民: 台灣人&#8230;，你說，簡單! 不要測舊功能不就好了? 是的，我想這可能就是最常見的情況，不要測試舊功能理所當然地，每寫一行的程式成本都保持一樣很低，但這代表著舊程式可能出錯的風險也跟著增加了，當你喜滋滋地覺得你幫公司省了成本，結果在一個月後因為舊程式缺乏測試，因改動了核心的部份造成舊的功能將所有資料外洩，公司損失慘重，這就是不重視軟體品質的後果</p>
<p>舉真實生活上發生過的例子，PTT曾經有過改程式未經好好地測試，造成每個人都能以管理員的權限登入的事情，知名的檔案同步平台Dropbox，也曾經<a href="http://blog.dropbox.com/?p=821">發生過因為認證的程式改版有bug，造成任何人都可以登入別人帳號的事</a>，我也有曾聽聞一些網站因為工程師為了測試方便，把認證的函數暫時改成</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">function authenticate<span style="color: black;">&#40;</span>user_id, password<span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> true<span style="color: #66cc66;">;</span>
        // do authentication here
        // ....
<span style="color: black;">&#125;</span></pre></div></div>

<p>然後又不小心commit，因此讓任何人都通過認證的事情，但這些都不能只怪工程師本身，誰能無過? 人總會犯錯的，問題出問於工程本身的制度、專案的管理、和工具的使用上</p>
<p>在未來，網路的應用越來越多，而軟體的品質重要程度只會越來越高，所以，要如何維持軟體的品質又同時能不讓測試的成本隨著專案的擴張而跟著無限制地成長呢? 答案就是 &#8211; 自動化測試</p>
<h2>自動化測試</h2>
<p>自動化測試聽起來好像很美妙，讓電腦自動幫你測試程式? 有這麼好的事情嗎? 事實上不是那樣，自動化測試，是透過寫好的規則，自動對於程式進行測試，所以終究還是得需要人力的介入，那你或許會問，結果倒頭來還不是得用人力? 那到底有什麼好處? 答案就跟我們先前提到的一樣，如果你的專案很小，用人力測試其實可能就已足夠，但當你的專案夠大，如果沒有自動化測試，那麼光是在測舊的程式就是相當龐大的成本上</p>
<p>引入了自動化測試不代表程式就不會出錯，它不是萬能的，但是它至少保證了程式一定的品質，只要使用得當，就能降低測試的成本，也能讓大部份有經過自動測試的程式都不會出現太離譜的錯誤，至於要怎麼做，讓我們看下去</p>
<h2>單元測試</h2>
<p>最常見的測試，就是單元測試(Unit test)，通常是針對單一個或是少數類別，確保這些類別單獨運作是正確的，舉個例子，你寫了一個類別，是用來找輸入的地圖的最短路徑，那麼你就得替這類別，寫一個單元測試，餵入你準備好的資料，然後取得輸出的結果，看是否和你準備的預期答案是一樣的，舉一個最簡單的例子，一個用Python來將輸入文字拆解成一行一行的解析器</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> LineParser<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, newline=<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>'</span>, remain=<span style="color: #483d8b;">''</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">newline</span> = newline
        <span style="color: #008000;">self</span>._buffer = <span style="color: black;">&#91;</span>remain<span style="color: black;">&#93;</span>
        <span style="color: #008000;">self</span>._size = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>remain<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> feed<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, data<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>._buffer.<span style="color: black;">append</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>._size += <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> getLine<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        data = <span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._buffer<span style="color: black;">&#41;</span>
        index = data.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">newline</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> index <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span>:
            line = data<span style="color: black;">&#91;</span>:index<span style="color: black;">&#93;</span>
            <span style="color: #008000;">self</span>._buffer = <span style="color: black;">&#91;</span>data<span style="color: black;">&#91;</span>index + <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">newline</span><span style="color: black;">&#41;</span>:<span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">length</span> = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._buffer<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> line
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> iterLines<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        line = <span style="color: #008000;">self</span>.<span style="color: black;">getLine</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">while</span> line <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
            <span style="color: #ff7700;font-weight:bold;">yield</span> line
            line = <span style="color: #008000;">self</span>.<span style="color: black;">getLine</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>它的單元測試就長這樣</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">unittest</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> TestLineParser<span style="color: black;">&#40;</span><span style="color: #dc143c;">unittest</span>.<span style="color: black;">TestCase</span><span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> makeOne<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> LineParser<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> testParser<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        p = <span style="color: #008000;">self</span>.<span style="color: black;">makeOne</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        p.<span style="color: black;">feed</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'abc'</span><span style="color: black;">&#41;</span>
        line = p.<span style="color: black;">getLine</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span>line, <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
&nbsp;
        p.<span style="color: black;">feed</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
        line = p.<span style="color: black;">getLine</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span>line, <span style="color: #483d8b;">'abc'</span><span style="color: black;">&#41;</span>
        line = p.<span style="color: black;">getLine</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span>line, <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># write lots line</span>
        p.<span style="color: black;">feed</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'111<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>222<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>3333'</span><span style="color: black;">&#41;</span>
        lines = <span style="color: #008000;">list</span><span style="color: black;">&#40;</span>p.<span style="color: black;">iterLines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'111'</span>, <span style="color: #483d8b;">'222'</span><span style="color: black;">&#93;</span>, lines<span style="color: black;">&#41;</span>
        line = p.<span style="color: black;">getLine</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span>line, <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
&nbsp;
        p.<span style="color: black;">feed</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>text'</span><span style="color: black;">&#41;</span>
        line = p.<span style="color: black;">getLine</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span>line, <span style="color: #483d8b;">'3333'</span><span style="color: black;">&#41;</span>
        line = p.<span style="color: black;">getLine</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span>line, <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># write nothing</span>
        p.<span style="color: black;">feed</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span><span style="color: black;">&#41;</span>
        line = p.<span style="color: black;">getLine</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span>line, <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
&nbsp;
        p.<span style="color: black;">feed</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
        lines = <span style="color: #008000;">list</span><span style="color: black;">&#40;</span>p.<span style="color: black;">iterLines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span>lines, <span style="color: black;">&#91;</span><span style="color: #483d8b;">'text'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">assertEqual</span><span style="color: black;">&#40;</span><span style="color: #008000;">list</span><span style="color: black;">&#40;</span>p.<span style="color: black;">iterLines</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> suite<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    suite = <span style="color: #dc143c;">unittest</span>.<span style="color: black;">TestSuite</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    suite.<span style="color: black;">addTest</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">unittest</span>.<span style="color: black;">makeSuite</span><span style="color: black;">&#40;</span>TestLineParser<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> suite
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    <span style="color: #dc143c;">unittest</span>.<span style="color: black;">main</span><span style="color: black;">&#40;</span>defaultTest=<span style="color: #483d8b;">'suite'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>很簡單的想法就是列出幾種常見的case，還有你能想到的特例代進去，好的測試資料要能夠測到每一行程式，但是要做到那樣需要花不少心力，其實能夠做到大部份常見的情況和常見的特例，就已經相當足夠</p>
<h2>整合測試</h2>
<p>有些程式，無可避免地會依賴其它程式，如果我們針對這兩個程式同時測試，會無法分出出錯到底是誰的錯，再者，很多依賴的部份可能會牽扯到IO或是其它系統資源，讓測試變得更複雜，例如有個類別是負責輸出文件到印表機的，那你要如何確認印表機印出來的東西是正確的? 答案就是做一個假的 (Mocking)印表機丟給那個類別去做列印的動作，再去讀取裡面的資料，確認跟你預期的一樣</p>
<p>雖然單元測試在相當單純的模擬環境下測過了我們的程式，然而世界並不是那樣的美好，總有些事情沒有經過真槍實彈操演過可能會有差錯，因此有時我們會引入部份受控制的真實環境來測試，例如你想測試網路連線，或許你可以寫一段script在Amazon EC2上建起幾個instance，並上傳程式到那些機器中，自動讓他們連線來確保這些功能是正常的，然而越真實的環境變因就越多，因此測試也就相對困難</p>
<h2>每日建構的好幫手 &#8211; Jenkins</h2>
<p>Joel有說過 <a href="http://chinese.joelonsoftware.com/Articles/DailyBuildsAreYourFriend.html">每日建構是你的朋友</a> (<a href="http://www.joelonsoftware.com/articles/fog0000000023.html">Daily build is your friend</a>)，也有提過 <a href="http://chinese.joelonsoftware.com/Articles/TheJoelTest.html">軟體開發成功的12個法則</a> (<a href="http://www.joelonsoftware.com/articles/fog0000000043.html">The Joel Test: 12 Steps to Better Code</a>)，裡面的daily build是指利用工具每天自動建構整個專案，通常對於編譯式的語言，如C語言寫的大型專案會較需要這類的工具，但是這樣的工具還有一個目的，在於確保程式是可以正常編譯的，並且讓測試員容易拿到最新的程式進行測試，然而自動化測試，同樣的也需要類似的工具，因為通常你在改完程式就會進行測試，那每次一改完程式就得跑一次測試指令，這不是一件很煩的事情嗎?</p>
<p>記得，工具是為我們服務的，不是我們為工具服務，這樣重複的瑣事理所當然也是由工具來幫忙，謝天謝地現今有好用又免費的工具，可以幫你做到這點，那就是<a href="http://jenkins-ci.org/">Jenkins</a>，它是一套基於網頁的自動化測試管理工具，它可以做到什麼呢? 它可以做到幫你定時去版本控制系統取程式回來，用預先設定好的流程進行測試，並且記錄測試的結果，如果有某個測試出錯了，當然也可以發Email通知你，以Now.in的開發為例，因為專案為數眾多，其中又有依賴關係，有了Jenkins的幫忙，程式只要一改送到BitBucket，它就會自動進行測試</p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2011/10/jenkins.png"><img class="aligncenter size-full wp-image-1634" title="jenkins" src="http://blog.ez2learn.com/wp-content/uploads/2011/10/jenkins.png" alt="" width="746" height="470" /></a>如此一來就省下了大量的時間，同時，也可以專心在於開發上</p>
<p>Jenkins除了功能強大以外，他還有一項特色令我驚訝，就是非常簡單易用，從安裝到設定完所有的測試，除了clone hg檔案庫和設置測試環境以外，我從沒因為Jenkins打過一行指令，全部都可以透過它友善的網頁介面完成，同時它也有內建資料庫，也沒因此設定MySQL，在Windows下安裝更是容易，一個安裝檔執行完就是安裝完成，如果你希望有工具幫你自動定時測試或是建構，請不要懷疑，Jenkins是你最佳選擇</p>
<h2>部署前的自動化測試</h2>
<p>執行自動化測試的時機，除了剛改完程式，還有一個重要的時機，那就是在你把程式部署到伺服器以前，讓你的自動化部署的script先跑過一次自動測試，確認測試通過了再進行部署，為什麼要這樣做呢? 還記得先前提到的PTT和Dropbox以及一些網站對於authentication的return true慘劇嗎? 為了不讓那種事情發生，或著至少讓機會降低，在deploy前讓自動化測試跑過一次，確保測試的範圍內都是正確的，可以大大降低那種情況發生的機會，除此之外，也比較不會因為改出bug，自己沒發現，等到使用者來抱怨了才知道問題在哪</p>
<h2>測試的幾項重點</h2>
<p>自動化測試雖然是一項利器，但是得經過正確的使用才會有好的效果，自動化測試有所謂的覆蓋率，也就是你的程式裡以行為單位，有多少行是在跑測試時有執行過的? 這些工具都可以幫你統計出來，但是切記</p>
<blockquote><p><strong>不要為了追求高測試覆蓋率，替foo bar寫測試</strong></p></blockquote>
<p>這只是在浪費時間，如果某段程式已經簡單到沒測試的必要，你寫了也是多餘</p>
<p>除此之外，寫測試事實上也是成本，因此如果時間有限，請</p>
<blockquote><p><strong>優先針對重要的核心、資料模型、商業邏輯測試</strong></p></blockquote>
<p>因為就算你測再多無關緊要的程式，最重要的核心出錯了，可能整個系統就完蛋了，所以盡量以重要的程式做為測試的優先考量</p>
<blockquote><p><strong>優先針對安全性相關、存取權限、身份認證、常見攻擊手法測試</strong></p></blockquote>
<p>雖然身份認證這種事情算不上是核心，但這關係到你的系統會不會被輕易地攻擊，除此之外，如果你的程式是網站應用程式，SQL Injection、XSS、buffer overflow這類攻擊也會很常發生，因此，你也需要優先自行設計一些攻擊，針對這些常見的問題餵一些資料，雖然這無法保證一定不會犯錯，至少確保不會發生太低等級的錯誤，因為常見的case都已經有自動測試過了，搭配先前所提到的，deploy前跑過一次測試，如此一來就能將犯錯的機會降低許多</p>
<p>雖然你的程式可能大多都已經有自動化測試在幫你測試，但即使如此，你還是會發現新的bug，如果說，你直接改了bug，就這樣了事，很有可能在下幾次改版bug又回來了，因此</p>
<blockquote><p><strong>每當你發現你先前沒想到的bug，請加到你的測試中</strong></p></blockquote>
<p>如此一來，隨著你針對的bug測試case越多，你的程式品質就越高，未發現的bug也會越少，在未來確保這些bug不會再出現</p>
<h2>最後</h2>
<p>再一次，自動化測試不是萬能的，除此之外也需要正確的運用，如果台灣軟體業界能夠好好運用自動化測試，軟體的品質可以有所提升，開發者也不會因為除錯除到死加班到天亮，雖然寫測試是額外的負擔，但是對於大形專案長期看來是非常值得的投資</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2011/10/20/taiwan-software-lacking-of-auto-testing/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Now.in 遭受到來自歐洲的殭屍DDOS攻擊</title>
		<link>http://blog.ez2learn.com/2010/07/18/now-in-is-under-attack-from-european-zombies/</link>
		<comments>http://blog.ez2learn.com/2010/07/18/now-in-is-under-attack-from-european-zombies/#comments</comments>
		<pubDate>Sun, 18 Jul 2010 12:47:10 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[資訊安全]]></category>
		<category><![CDATA[WTF]]></category>
		<category><![CDATA[資安]]></category>
		<category><![CDATA[腦殘]]></category>
		<category><![CDATA[殭屍]]></category>
		<category><![CDATA[攻擊]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=1079</guid>
		<description><![CDATA[Now.in這兩天遭到來自歐洲各國的殭屍DDOS攻擊，來源國家有羅馬尼亞、土耳其、捷克共合國、德國、法國 為了讓服務能正常運行，我花了一個晚上寫了一個防火牆，自從掛上去之後對方的攻擊都是無效的 我也不知道明明是無效的攻擊為什麼這位小朋友還要繼續試，從手法來看對方應該只是個script kid，攻擊的Request從一開始全部是這樣 GET /radio/musicfm Host: en.now.in 變成 GET /radio/musicfm Content-Type: text/plain Host: en.now.in 或是 GET /radio/musicfm Connection: keep-alive Host: en.now.in 他大概蠢到以為加了keep-alive之後我的伺服器就會蠢到把連線開著讓他吃免錢的資源? 或是改變request的內容我的防火牆就會認不出來? 在他猜到防火牆設的規則前攻擊都是無效的，說真的，我想不到有什麼無聊的理由可以浪費時間在攻擊別人的網站，這樣一直狂送request就會高潮嗎? 如果有效就算了，還是這種無力的三流攻擊，我統計了一下記錄檔他十幾台殭屍聯合攻擊的request/seconds數量也才200多，連防火牆的1%CPU使用率都撐不起來 不過，網路上神經病何其多，架網站遇到這種莫名奇妙的攻擊也是遲早的事，感謝這位小朋友讓我有機會寫個防火牆，之後還一直有機會遇到神經病的攻擊，也算是經驗的一種，而這防火牆是因為殭屍而生的，所以就把它命名為 Molotov吧。]]></description>
			<content:encoded><![CDATA[<p><a href="http://now.in">Now.in</a>這兩天遭到來自歐洲各國的殭屍DDOS攻擊，來源國家有羅馬尼亞、土耳其、捷克共合國、德國、法國</p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2010/07/l4d_hospital01_apartment0011.jpg"><img class="alignnone size-large wp-image-1080" title="Now.in 遭受到來自歐洲的殭屍攻擊" src="http://blog.ez2learn.com/wp-content/uploads/2010/07/l4d_hospital01_apartment0011-1024x640.jpg" alt="" width="717" height="448" /></a></p>
<p>為了讓服務能正常運行，我花了一個晚上寫了一個防火牆，自從掛上去之後對方的攻擊都是無效的</p>
<p><a href="http://blog.ez2learn.com/wp-content/uploads/2010/07/l4d_hospital02_subway0016.jpg"><img class="alignnone size-large wp-image-1081" title="l4d_hospital02_subway0016" src="http://blog.ez2learn.com/wp-content/uploads/2010/07/l4d_hospital02_subway0016-1024x640.jpg" alt="" width="717" height="448" /></a></p>
<p>我也不知道明明是無效的攻擊為什麼這位小朋友還要繼續試，從手法來看對方應該只是個script kid，攻擊的Request從一開始全部是這樣</p>
<blockquote>
<div id="_mcePaste">GET /radio/musicfm</div>
<div>Host: en.now.in</div>
</blockquote>
<div id="_mcePaste">變成</div>
<blockquote>
<div>
<div>GET /radio/musicfm</div>
<div>Content-Type: text/plain</div>
<div>Host: en.now.in</div>
</div>
</blockquote>
<div>或是</div>
<blockquote>
<div>
<div>GET /radio/musicfm</div>
<div>Connection: keep-alive</div>
<div>Host: en.now.in</div>
</div>
</blockquote>
<div>他大概蠢到以為加了keep-alive之後我的伺服器就會蠢到把連線開著讓他吃免錢的資源? 或是改變request的內容我的防火牆就會認不出來? 在他猜到防火牆設的規則前攻擊都是無效的，說真的，我想不到有什麼無聊的理由可以浪費時間在攻擊別人的網站，這樣一直狂送request就會高潮嗎? 如果有效就算了，還是這種無力的三流攻擊，我統計了一下記錄檔他十幾台殭屍聯合攻擊的request/seconds數量也才200多，連防火牆的1%CPU使用率都撐不起來</div>
<div></div>
<div>不過，網路上神經病何其多，架網站遇到這種莫名奇妙的攻擊也是遲早的事，感謝這位小朋友讓我有機會寫個防火牆，之後還一直有機會遇到神經病的攻擊，也算是經驗的一種，而這防火牆是因為殭屍而生的，所以就把它命名為 Molotov吧。</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2010/07/18/now-in-is-under-attack-from-european-zombies/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>到底是誰賣了你的購物資料</title>
		<link>http://blog.ez2learn.com/2009/09/24/who-sells-your-shopping-information/</link>
		<comments>http://blog.ez2learn.com/2009/09/24/who-sells-your-shopping-information/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 15:16:51 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[分享]]></category>
		<category><![CDATA[資訊安全]]></category>
		<category><![CDATA[詐騙集團]]></category>
		<category><![CDATA[資安]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=792</guid>
		<description><![CDATA[前些天，為了畢業專題，我上網在PCHome的DA量販買了一條USB 轉 RS232的線傳輸線，有趣的是，就在昨天，我接到了詐騙電話，他們很清楚我買了什麼東西，告訴我他們弄錯了帳款，變成了自動分期扣款，我用不屑的口吻說了一句"喔&#8230;"，不知道是從我的口氣感到沒有希望還怎樣，通話過一陣子就斷了，這不是我第一次接到這樣的詐騙電話，每次我接到都覺得很火大，火大不是在於電話本身，而是賣家把我的資料洩漏出去，而更火大的是，通常都沒人想去追究到底是從哪洩漏出去的，每個環節都聲稱他們都有定期掃毒、更換密碼、他們的平台很安全，因為舉證困難，比起找到哪裡流出去的，把責任推給別人比較簡單，這讓我覺得相當火大，於是我就開始想，到底是誰把資料流出去的，做了一些研究和推論 大家都一樣火大 我相信，接到詐騙電話的人，發現自己資料被一清二楚地流出去時，都一樣火大，在評價上肯定不會有什麼好評，於是我找了DA量販的負評來看，果不其然，也有人抱怨接到了詐騙電話，時間也都很接近 評價等級：     待加強　(2009/09/17 20:57:59) (最新一筆) 評價意見：     我上個月買一顆電池, 今天就接到詐騙電話, 為何對方會知道詳細交易內容? 煩請加強你們的交易資料保密, 謝謝! 評價等級：      待加強　(2009/08/29 01:31:54) (最新一筆) 評價意見：     商品品質:產品質量太差太粗糙,買回來一裝,把我上千元的手把控制器整個磨損!! 洞大小根本不對,難放入更難拔出!!太可怕了!! 貪圖東西便宜,到頭來卻是當垃圾丟了!! 而且還造成原來搖控器的損壞,最後實在是虧更大!!! 今晚還莫名其妙接到廠商打來說付款有問題,錢都從我信用卡裡扣了!還有啥問題?!! 麻煩廠商下次自行先查清楚,這年頭詐騙太多,沒事別亂打給顧客說款項有問題,害我差點報警!! 光看這樣似乎是DA量販有意或無意的把資料流出去，但這麼想太過武斷，因為能接觸到個人資料的環節不少，我不清楚他們背後的流程怎麼跑，但是資料經過的環有不少，可能這些環節都會流出去，至於環節有哪些，從使用者的電腦、商家、物流、銀行等等，我們先一項一項來看 使用者 俗話說，懷疑別人前要先懷疑自己，通常，使用者的這一環節是最弱的，不管在安全知識等各方面，都是相當不足容易被侵入的，但是考慮到一個重點，其實就可以發現，資料從使用者這邊流出去的可能是有，但其實非常少，只要站在詐騙集團的立場來看就很清楚，問題就出在於成本，使用者用電腦的作業系統、環境都不相同，做為詐騙集團，如果要從使用者這裡取得資料，例如植入木馬，有如大海撈針一般，如何知道這使用者有在線上購物，並且能夠抓到他購物的資料? 當然也可以使用釣魚的手法寄假的登入頁面，只是比起店家的信箱，買家的資料較難取得，再者，同一個人可以被騙幾次? 所以，再笨的詐騙集團都知道，從使用者個體電腦取得資料一點都不划算，我有見過很多商家都這麼說: 店家回覆：      非常謝謝您的支持！針對此詐騙電話，pchome已做防護，詐騙資料是由客戶端所收到的購買回件做詐騙，並非商店街外洩，請更改您本身的密碼，以防詐騙集團入侵你的信箱！希望以後還能再為您服務喔！^^  (2009/09/22 09:50:34) &#8230; <a href="http://blog.ez2learn.com/2009/09/24/who-sells-your-shopping-information/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>前些天，為了畢業專題，我上網在<a href="http://store.pchome.com.tw/dashop/">PCHome的DA量販</a>買了一條USB 轉 RS232的線傳輸線，有趣的是，就在昨天，我接到了詐騙電話，他們很清楚我買了什麼東西，告訴我他們弄錯了帳款，變成了自動分期扣款，我用不屑的口吻說了一句"喔&#8230;"，不知道是從我的口氣感到沒有希望還怎樣，通話過一陣子就斷了，這不是我第一次接到這樣的詐騙電話，每次我接到都覺得很火大，火大不是在於電話本身，而是賣家把我的資料洩漏出去，而更火大的是，通常都沒人想去追究到底是從哪洩漏出去的，每個環節都聲稱他們都有定期掃毒、更換密碼、他們的平台很安全，因為舉證困難，比起找到哪裡流出去的，把責任推給別人比較簡單，這讓我覺得相當火大，於是我就開始想，到底是誰把資料流出去的，做了一些研究和推論</p>
<h2>大家都一樣火大</h2>
<p>我相信，接到詐騙電話的人，發現自己資料被一清二楚地流出去時，都一樣火大，在評價上肯定不會有什麼好評，於是我找了DA量販的負評來看，果不其然，也有人抱怨接到了詐騙電話，時間也都很接近</p>
<blockquote><p>評價等級：     待加強　(2009/09/17 20:57:59) (最新一筆)<br />
評價意見：     我上個月買一顆電池, 今天就接到詐騙電話, 為何對方會知道詳細交易內容? 煩請加強你們的交易資料保密, 謝謝!</p></blockquote>
<blockquote><p>評價等級：      待加強　(2009/08/29 01:31:54) (最新一筆)<br />
評價意見：     商品品質:產品質量太差太粗糙,買回來一裝,把我上千元的手把控制器整個磨損!! 洞大小根本不對,難放入更難拔出!!太可怕了!! 貪圖東西便宜,到頭來卻是當垃圾丟了!! 而且還造成原來搖控器的損壞,最後實在是虧更大!!! 今晚還莫名其妙接到廠商打來說付款有問題,錢都從我信用卡裡扣了!還有啥問題?!! 麻煩廠商下次自行先查清楚,這年頭詐騙太多,沒事別亂打給顧客說款項有問題,害我差點報警!!</p></blockquote>
<p>光看這樣似乎是DA量販有意或無意的把資料流出去，但這麼想太過武斷，因為能接觸到個人資料的環節不少，我不清楚他們背後的流程怎麼跑，但是資料經過的環有不少，可能這些環節都會流出去，至於環節有哪些，從使用者的電腦、商家、物流、銀行等等，我們先一項一項來看</p>
<h2>使用者</h2>
<p>俗話說，懷疑別人前要先懷疑自己，通常，使用者的這一環節是最弱的，不管在安全知識等各方面，都是相當不足容易被侵入的，但是考慮到一個重點，其實就可以發現，資料從使用者這邊流出去的可能是有，但其實非常少，只要站在詐騙集團的立場來看就很清楚，問題就出在於成本，使用者用電腦的作業系統、環境都不相同，做為詐騙集團，如果要從使用者這裡取得資料，例如植入木馬，<strong>有如大海撈針一般</strong>，如何知道這使用者有在線上購物，並且能夠抓到他購物的資料? 當然也可以使用釣魚的手法寄假的登入頁面，只是比起店家的信箱，買家的資料較難取得，再者，<strong>同一個人可以被騙幾次</strong>? 所以，再笨的詐騙集團都知道，從使用者個體電腦取得資料一點都不划算，我有見過很多商家都這麼說:</p>
<blockquote><p>店家回覆：      非常謝謝您的支持！針對此詐騙電話，pchome已做防護，詐騙資料是由客戶端所收到的購買回件做詐騙，並非商店街外洩，請更改您本身的密碼，以防詐騙集團入侵你的信箱！希望以後還能再為您服務喔！^^  (2009/09/22 09:50:34)</p>
<p><a href="http://store.pchome.com.tw/inenjoy/HM/eval.htm?evalType=B">連結</a></p></blockquote>
<p><strong>像這之類的，根本是鬼扯! </strong>詐騙集團監視你的信箱能撈到多少資料? 而你又能被騙幾次? 所以下次店家要推卸責任請想更好一點的理由</p>
<h2>店家</h2>
<p>店家的安全防護和知識等等，其實就和一般使用者沒兩樣，比起從使用者身上拿到資料，資料一次拿到都是一堆的，店家當然是最好的選擇，因為防護差又好騙，舉個例子，我可能只要寄封信謊稱自己是PCHome的工程師，近來很多人的電腦都被詐騙集團植入木馬，我們免費提供木馬清除程式，又或著釣魚(Phishing)的手法，把假的登入頁面，大量寄給商家，這之中肯定會有人上勾，只要有一個店家上勾，就有一票的資料可以詐騙，<strong>笨蛋才從使用者那邊盜那丁點資料</strong>，當然，店家內有內鬼，這也是有可能的，在我看來，<strong>店家可以說是最弱的環節</strong>，<strong>但通常是死不承認</strong>，<strong>又不認真面對找出漏資料的原因，讓資料一直漏，可以說是詐騙集團的最主要幫兇</strong></p>
<h2>平台</h2>
<p>比起從店家那裡盜資料，要從平台上拿到資料所需要的門檻高了一些，但說高其實也不高，如果平台有漏洞的話，有心人士發現，往往會將資料全倒出來，然後賣給詐騙集團，可能一筆資料只值幾塊錢這樣，大家的購物資料就這樣被以賤價賣給詐騙集團，所以，如果發現收到詐騙電話的人資料遍佈整個平台，就極有可能是平台有洞被撈資料了</p>
<p>除了官方的平台，也很常見到賣家使用外面賣的轉帳資料登入系統，也就是轉帳完買家進入他們的系統登入買了什麼東西，多少錢，然後轉帳時間、金額等等，像是Yahoo!奇摩拍賣就有不少賣家使用那樣的系統，我相信像很可能有相當大比例的資料是從那些系統流出去的，因為那些系統安全性比起Y拍和PCHome等平台，可能大多都很差，畢竟可能是菜鳥寫出來的網站，或許簡單的SQL Injection就能撈出一堆資料來，誰有興趣的話，或許可以抓資料做做看詐騙負評和轉帳資料登入系統的正相關性，我猜應該會相當高</p>
<h2>銀行</h2>
<p>有趣的是，除了把責任推給使用者，也有店家把責任推給銀行</p>
<blockquote><p>評價意見：      貨收到後第二天接到一通詐騙電話,被我識破後還被那女生罵髒話))&amp;^%&amp;*^$*&amp;()&#8230;.貴公司的客戶資料應該加強保護.</p>
<p>店家回覆：      您好：有看到您的評價意見了，現在資訊發達個人資料容易外漏，我本人若接到不明來電一定先詢問「怎麼會有我的電話號碼」,所以我們是非常厭惡不明電話的騷擾～～～我們緹悠樂活只專心致力於我們的本業，顧客的個人資料都是我們的珍藏絕不外漏，這點您絕對可以放心，我想在網路購物或任何的申請都需填寫個人資料，另外銀行或電信業者都可能盜取我們的個人資料外賣，我個人是很少留資料給他人，也常懷疑銀行或電信業者把我個人資料外瀉，甚至公家機關不法人員也有可能，太多太多的可能了，但我們向您保證您的資料絕不是從我們手中流出去的，如果您釋懷的話請給我們好一些些的評價吧！！　　祝您有個美好的一天～～～　　＾╴╴╴＾  (2009/09/03 09:45:57)</p>
<p><a href="http://store.pchome.com.tw/mandyshop/HM/eval.htm?evalType=B">連結</a></p></blockquote>
<p>雖然這裡沒有提到有任何詐騙集團的手法，但通常都是說你買了xxx東西，多少錢，都一清二礎地跟你說，讓你取信他們確實是賣家，接著才開始誆你，如果說銀行把資料流出去，那銀行又是怎樣知道你買了什麼東西? 店家會把商品名稱讓銀行知道嗎?</p>
<blockquote><p>98/ 09/ 04       刷卡消費       $169       &#8211;       xxx       網路家庭國際資</p></blockquote>
<p>以我在DA量販刷卡的記錄，銀行並不會記錄你買了什麼東西，頂多像這樣知道你在PCHome花過錢，所以像這種推卸責任的理由一樣很弱，再者銀行是最重視安全的單位之一，比起隨便請工讀生來處理訂單的店家安全等級要高太多了，不檢討自己居然懷疑到銀行頭上蠻可笑的</p>
<h2>物流</h2>
<p>當然把東西交到客戶手上的就是物流，所以也是推卸責任的好目標，請問大家在收到東西時，有多少店家會蠢到把買什麼東西、多少錢直接就寫在包裝外面? 我確實遇過，這些店家大概一點隱私權的概念都沒有，但是非常少數，所以基本上包裝上是不該寫買了什麼東西的，接著問題就是，店家將商品交給物流業者時，商品到底是包好的，還是沒包好的? 以我自己去郵局寄東西給買家來看，我們都是把東西包好再交給物流的，有人把東西交給物流在由他們包裝嗎? 或許有，但是如果不是的話，把責任推給物流就說不過去，不過或許有些跟物流之間會有商品報值的資料，這樣一來的確也是有可能會外流</p>
<h2>數據會說話</h2>
<p>當然，上面這些光說，沒有數據其實也只是空打嘴砲，為了能夠更清楚的瞭解資料外流的情況，我花了一點時間寫了一個小爬蟲爬了PCHome商店街所有店家的負評第一頁，在那之中找到有"詐騙"字眼的負評，而我發現有些是商品太久沒來，買家抱怨他們是不是被詐騙的留言，為此我手動過濾了一下，挑出確實是有說接到詐騙電話的負評，以下是列表</p>
<p><a href="http://store.pchome.com.tw/dashop/HM/eval.htm?evalType=B">DA 量販店</a></p>
<blockquote><p>評價等級：      待加強　(2009/09/17 20:57:59) (最新一筆)<br />
評價意見：     我上個月買一顆電池, 今天就接到詐騙電話, 為何對方會知道詳細交易內容? 煩請加強你們的交易資料保密, 謝謝!</p></blockquote>
<blockquote><p>評價等級：      待加強　(2009/08/29 01:31:54) (最新一筆)<br />
評價意見：     商品品質:產品質量太差太粗糙,買回來一裝,把我上千元的手把控制器整個磨損!! 洞大小根本不對,難放入更難拔出!!太可怕了!! 貪圖東西便宜,到頭來卻是當垃圾丟了!! 而且還造成原來搖控器的損壞,最後實在是虧更大!!! 今晚還莫名其妙接到廠商打來說付款有問題,錢都從我信用卡裡扣了!還有啥問題?!! 麻煩廠商下次自行先查清楚,這年頭詐騙太多,沒事別亂打給顧客說款項有問題,害我差點報警!!</p></blockquote>
<p><a href="http://store.pchome.com.tw/topoffice/HM/eval.htm?evalType=B">頂尖總務</a></p>
<blockquote><p>評價等級：      待加強　(2009/07/06 05:09:32) (最新一筆)<br />
評價意見：     我本來要寫優良的! 但是很不巧&#8230;我今天接到詐騙集團的電話! 他很清楚告知我買了什麼東西,金額和數量! 當然方式還是&#8230;一樣! 又說你付的方式 變成分期付款! 不處理會被扣很多錢! 我不知道是Pchome還是貴公司的問題! 購買你家的東西&#8230;客戶資料會被洩漏光光! 請其他人要小心此情況!<br />
店家回覆：     您好~真抱歉,因為我們的資料都是留在pchome後台的,會通知pchome加強控管,也會更改我們的後台的帳密及加強電腦掃毒,以查明原因,謝謝您的通知,對於造成您的困擾,深感抱歉!!  (2009/07/06 08:23:30)</p></blockquote>
<p><a href="http://store.pchome.com.tw/mandyshop/HM/eval.htm?evalType=B">緹悠樂活館</a></p>
<blockquote><p>評價等級：      待加強　(2009/09/02 14:45:01) (最新一筆)<br />
評價意見：     接獲詐騙集團電話..嚴重懷疑pchome商店街系統洩漏個人資料往後將會慎重考慮是否繼續在pchome商店街購物謝謝<br />
店家回覆：     您好：有看到您的評價意見了，現在資訊發達個人資料容易外漏，我本人若接到不明來電一定先詢問「怎麼會有我的電話號碼」,所以我們是非常厭惡不明電話的騷擾～～～我們緹悠樂活只專心致力於我們的本業，顧客的個人資料都是我們的珍藏絕不外漏，這點您絕對可以放心，我想在網路購物或任何的申請都需填寫個人資料，另外銀行或電信業者都可能盜取我們的個人資料外賣，我個人是很少留資料給他人，也常懷疑銀行或電信業者把我個人資料外瀉，甚至公家機關不法人員也有可能，太多太多的可能了，但我們向您保證您的資料絕不是從我們手中流出去的，如果您釋懷的話請給我們好一些些的評價吧！！　　祝您有個美好的一天～～～　　＾╴╴╴＾  (2009/09/03 09:45:57)</p></blockquote>
<p><a href="http://store.pchome.com.tw/mandyshop/HM/eval.htm?evalType=B">╭☆°蔓蒂小舖。韓系、日系美型孕婦裝、娃娃裝、中大尺碼</a></p>
<blockquote><p>評價等級：      優良　(2009/08/24 03:10:28)<br />
店家回覆：     您真是一位超級好買家！非常感謝您的光臨╭☆°蔓蒂 小鋪。祝福您事事順心喔～  (2009/08/24 09:54:49)<br />
評價等級：     待加強　(2009/09/01 05:05:00)<br />
評價意見：     客服態度不錯，但我的定安資料卻外流了，還遇到詐騙集團，整個不開心!<br />
店家回覆：     您好，我們在Pchome的這個平台，有使用動態密碼及定期更新密碼、掃毒，不過現在歹徒也越來越厲害，不知道他是怎麼竊取資料的，也有可能是您的電腦在上傳資料時被竊取的，建議您也掃毒一下唷，我們已經立刻更新我們的密碼、掃毒，謝謝您特地來信告知喔！同時我們也已經通知Pchome有此情形！提醒您，並沒有什麼ATM按錯變成分期付款，還會每月扣款，如接到可疑電話，請馬上掛斷！並打165報警！也可來信or來電跟我們確認喔  (2009/09/01 09:19:47)<br />
評價等級：     待加強　(2009/09/01 05:07:04) (最新一筆)<br />
評價意見：     客服態度<br />
店家回覆：     很抱歉～讓您覺得不開心～我們也已經向Pchome反應此情形  (2009/09/01 09:21:59)</p></blockquote>
<p><a href="http://store.pchome.com.tw/epnet/HM/eval.htm?evalType=B">EP NET親子生活館</a></p>
<blockquote><p>評價等級：     待加強　(2009/09/16 01:49:54) (最新一筆)<br />
評價意見：     商品是不錯用!但是已經購買一個多月了.竟還會接到詐騙電話!感受很差!!這是為什麼?請給個合理的理由!!謝謝!!</p></blockquote>
<p><a href="http://store.pchome.com.tw/abcd1119/HM/eval.htm?evalType=B">好吃多國際食品</a></p>
<blockquote><p>評價等級：     待加強　(2009/09/20 21:37:11) (最新一筆)<br />
評價意見：     我跟你們 買牛肉幹乾這事! 為何詐騙集團會知道? 竟然被詐騙集團利用 打電話 給我來行騙! 我想請教! 我的個資為何從你那邊流出去? 我的地址!電話 交易項目 金額 信用卡公司,&#8230;都給詐騙集團知道了! 對我的安全有很大影響! 打電話給你們 卻是推的一甘二淨!! 超級不負責任!!<br />
店家回覆：     非常的感恩PChome商店街在此特別提醒您，商店街的店家與PChome工作人員，均不會要求消費者至.提款機操作任何功能，請小心勿上當。如果接獲不明人士來信或來電，應立即撥打165防詐騙專線查詢或透過 PChome商店街客服中心 https://storessl.pchome.com.tw/adm/appeal.htm 查證。 PChome商店街與您一起努力維護網路交易安全！  (2009/09/20 22:10:11)</p></blockquote>
<p><a href="http://store.pchome.com.tw/tge505/HM/eval.htm?evalType=B">電氣男數位購物城</a></p>
<blockquote><p>評價等級：      待加強　(2007/11/13 11:10:38) (最新一筆)<br />
評價意見：     我這才發現原來我接到的那通電話也是詐騙集團打來的!! 本人在此鄭重表達對貴公司以及PChome商店街的嚴重不滿與抗議!! 我們都是基於信任貴司與PChome商店街交易平台的安全性才在此消費, 現在我們的手機以及其他個人資料全被盜取, 請問貴公司以及PChome商店街要怎麼負責與解決??!<br />
店家回覆：     不好意思 我們已經將此情況反應給pchome了並通知警方處理 造成您的不便請見諒  (2007/11/14 12:09:14)</p>
<p>評價等級：      待加強　(2007/11/12 14:55:15) (最新一筆)<br />
評價意見：     你們公司把我的交易資料外洩,害詐騙集團打來騷擾我, 他們明確說出我在何時,跟你們購買了這組電蚊拍,還問我使用狀況接著騙我說我的交易紀錄出問題,說你們的交易平台異常,還我一次付清的方式變成分期, 要我去ATM取得交易明細表,還有上面的經辦證號與時間,才能做取消分期, 後來我去查證才知道是詐騙, 請大家要小心在這家商店購物時的資料外洩問題!!!!<br />
店家回覆：     我們已經將此情況回應給pchome及警方了 不好意思造成您的困擾 本館絕對不會打電話告知民眾要更改交易方式如有任何問題請來電本館進行確認的動作  (2007/11/12 18:27:51)</p></blockquote>
<p><a href="http://store.pchome.com.tw/inenjoy/HM/eval.htm?evalType=B"><span>美麗家電器購物網</span></a></p>
<blockquote><p>評價等級：      待加強　(2009/09/21 22:01:38) (最新一筆)<br />
評價意見：     今天接到所謂客服來電，表明了解此次購物，但說到後來就成了詐騙電話，說我會被每月扣款…。我想你們系統也太差了，個資馬上外洩。<br />
店家回覆：     非常謝謝您的支持！針對此詐騙電話，pchome已做防護，詐騙資料是由客戶端所收到的購買回件做詐騙，並非商店街外洩，請更改您本身的密碼，以防詐騙集團入侵你的信箱！希望以後還能再為您服務喔！^^  (2009/09/22 09:50:34)</p></blockquote>
<p><a href="http://store.pchome.com.tw/ezbon/HM/eval.htm?evalType=B">電器王國</a></p>
<blockquote><p>評價等級：      待加強　(2008/01/06 23:51:55) (最新一筆)<br />
評價意見：     該商家漠視消費者權益使客戶資料外洩導至接到詐騙電話，告知店家還回覆網路世界無孔不入.很抱歉.讓大家權益受損.只要大家小心別上當.謝謝。如果真的詐騙成功不知道該找誰，跟別的店家買比較安全。<br />
店家回覆：     您好～我們不幸被選作為詐騙跳板，我們也很懊惱、難過；每天擔心顧客不小心上當受騙，而知道顧客在被詐騙集團騷擾後，我們馬上報警處理並通知１65詐騙專線，並沒有漠視消費者權益，但警方說這種網路詐騙事件他們不處理，１65詐騙專線也只是確認他們是詐騙集團，根本無法將他們繩之以法，我們也求助無門。最後我們只好致電跟上百位客戶提醒，並不是沒有在處理，希望您能見諒，謝謝您  (2008/01/07 14:30:13)</p></blockquote>
<p><a href="http://store.pchome.com.tw/pc123456/HM/eval.htm?evalType=B">亞訊e機棒_科技生活館</a></p>
<blockquote><p>評價意見：      貨收到後第二天接到一通詐騙電話,被我識破後還被那女生罵髒話))&amp;^%&amp;*^$*&amp;()&#8230;.貴公司的客戶資料應該加強保護.<br />
店家回覆：     大大 您好看到您的評價意見很驚嚇，網路駭客橫行這是無庸置疑不爭之事實，但是，我們公司從未發生(客戶資料被盜)這種事件，/駭客入侵/有可能是網路伺服器 (PChome主機)及買賣雙方的電腦被駭客值入木馬程式才會造成資料外流，經您反映告知我們公司已立即將管理網站的電腦主機請工程師協助迅速掃毒檢測，惟並無發現任何異常之處，公司同時將您評價意見及發生情況反映PChome相關部門之外，也特別對您發生以上事件表達關心之意。網路駭客真是猖狂橫行，唯有隨時保護好個資之外也建議您隨時為自已的電腦掃毒(請特別注意一般的防毒軟體是無法防止網路駭客的木馬攻擊和入侵竊盜及控制)，避免開啟任何陌生的郵件和連結，發現網路變慢或有異常的情形一定要找電腦專業工程師檢查及維護。對以上的所發生之情事我們一定會再加強個資保護，如還有相關問題也歡迎您隨時反映連絡PChome客服投訴，或來電亞訊e機棒_科技生活館服務中心向服務人員告知。最後 敬祝 平安幸福 亞訊e機棒_科技生活館 經理 林茂森敬上 98/03/20  (2009/03/20 03:00:03)</p></blockquote>
<p><a href="http://store.pchome.com.tw/pc123456/HM/eval.htm?evalType=B">PC流行通訊網</a></p>
<blockquote><p>評價等級：      普通　(2009/08/25 17:00:24)<br />
評價意見：     我今天收到詐騙電話 對方聲稱 我於貴商店購買的耳機付款有問題. 會造成連續扣款. 我想了解貴商店的資料是如何洩漏出去的?<br />
店家回覆：     謝謝您的評價~有您的支持與推薦，我們一定更加努力經營，以後有機會再為您服務囉!!  (2009/08/25 17:38:19)<br />
評價等級：     待加強　(2009/09/12 11:55:29) (最新一筆)<br />
評價意見：     我接到詐騙電話 聲稱我於貴商店購買的 "JABRA BT-530~全新遠寬公司貨~ 原廠[一對二]A2DP 抗燥音藍牙耳機BT530&#8243; 商品,誤辦理為分期.要求我要操作 ATM. 我於兩週前通知貴商店,並請貴商店了解資料是如何外洩的.可貴商店置之不理. 貴商店漠視此一資料外洩事件的態度令人感到匪夷所思. 貴商店既然沒有誠意想改善與了解此個人資料外洩的問題.我也不會再貴商店繼續購物.以免個人資料繼續外流.<br />
店家回覆：     您好：我們十分重視您的購物權益，針對資料外洩一事我們因為跟PCHOME研商原因,且目前PCHOME也已經把購物通知的資料不再顯示,我們也針對公司內部所有電腦進行資安清查,並未發現有病毒侵害及惡意木馬的植入,我們已經於9/10日去函回覆給您~有關PCHPME系統人員的答覆,及我們的處理狀況, 並非置之不理尚請貴客見諒!讓您擔憂在此致上我們的歉意,這一次PCHOME的事件已經有許多商店都有受害,您和我們都並不是唯一的受害者,相信只要我們提高警覺,一定可以打擊犯罪~感恩  (2009/09/12 18:46:58)</p></blockquote>
<h2>以這些資料來看</h2>
<p>DA量販有兩筆負評是收到詐騙電話，加上我自己一筆，不知道是太久沒給還是我給過了所以不能給，總共有三筆，在這麼短的時間內有三筆收到詐騙電話的負評，顯然肯定是從店家或平台流出去的，在我撈到的資料中，店家有六千多家，但是有詐騙反應的，通常都是少數、且在集中時間內，這樣表示，從平台漏出去的機會比較小，而從店家流出去的可能性極高，以DA量販來看，幾乎可以肯定是他們流出去的，至於是有意或無意的這就不知道了，而其它撈到的，像是電氣男購物城，也有短時間內兩筆，這同樣顯示資料是從他們那裡流出去的，為什麼其它店家都不會有這問題，而上列的這些店家都有呢? 當然就是你們自己的問題了，可是令人憤怒的是各種推託的理由都有，把責任推給使用者、推給銀行，就是死不承認資料是從自己身上流出去的，我知道這很難證明，但是數據和各種的可能性推出來都是如此</p>
<h2>不是只有中木馬才會把資料流出去</h2>
<p>很多店家都說，我們都有掃毒，但都沒發現異狀，其實會把資料流出去，通常都是用更簡單的方式，就是用釣魚(Phishing)的方式，是一種比木馬等其它方式取得帳密更簡單卻有效的方式，做法就是，造一個假的商店街登入頁面，看起來和原本的一模一樣，然後以各種理由把網址傳給店家，例如回復訊息、您的帳號疑似被盜用，需要更改帳密等等，店家收到信之後，點開連結要求你登入，於是傻傻的店家就真的把帳號密碼輸入了這個假的登入頁面接著送出，當然就落到了詐騙集團手裡，而且比起木馬會被發現，但是他拿到你的帳密後，偷偷登入看你買家的資料，你可能很難發現，其實平台可以提供登入的記錄，如果這麼做的話，也比較容易發現偷偷的登入，像是如果我明明沒有在昨天早上登入帳號，但是卻有這麼一筆記錄存在，很明顯地肯定是帳號密碼外流了</p>
<h2>外流資料環節偵測系統</h2>
<p>雖然有這些數據，但是其實還是不足以夠精確地找出資料是從哪裡流出去的，為此，我想可以用一套系統，以科學的方法找到並定位資料外流的環節，方法很簡單，就是每發現一次接到詐騙電話的反應，就在那訂單所有可能外洩的環節上，加上1分，在這麼多個環節中，分數遠高於其它環節的，即是外流資料的兇手，為何資料外流積分這麼高，不是你流出去的難到是阿飄流出去的嗎? 可惜的是似乎從來沒有人認真去找出資料是從哪裡流出去的，就任憑資料流阿流的，成為詐騙集團的最大幫兇</p>
<h2>最後</h2>
<p>使用者本身也有責任，接到詐騙電話，資料是從某店家那裡流出去的，請不用客氣給與最差的評價，連客戶資料都管不好，沒什麼好講的，務必讓大家知道這些沒辦法守好資料的商家，或是在其背後的任何一個環節，店家也要養成良好的習慣，不要亂裝來路不明的程式，有人寫信給你，連結最好不要隨便點，即使點開了，也要注意網址正不正確，有些甚至會申請看起來好像很像的域名來魚目混珠，千萬不要傻傻的點了就輸入帳號密碼試著登入，最好是自己從後台的書籤入口登入，避免點信件裡的連結接著登入系統，因為信件裡的連結很可能都是釣魚的連結，不然到時帳號密碼又被偷，不僅賠了商譽，買家也會成為受害者</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2009/09/24/who-sells-your-shopping-information/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Google大暴炸! 這個網站可能會損害您的電腦</title>
		<link>http://blog.ez2learn.com/2009/01/31/google-search-goes-wrong/</link>
		<comments>http://blog.ez2learn.com/2009/01/31/google-search-goes-wrong/#comments</comments>
		<pubDate>Sat, 31 Jan 2009 14:54:06 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[分享]]></category>
		<category><![CDATA[資訊安全]]></category>
		<category><![CDATA[腦殘]]></category>
		<category><![CDATA[WTF]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=511</guid>
		<description><![CDATA[Google大暴炸! 所有網站都出現這個網站可能會損害您的電腦的字樣 <a href="http://blog.ez2learn.com/2009/01/31/google-search-goes-wrong/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>剛剛在Google搜尋資料時突然發現，奇怪，怎麼好多網站都出現</p>
<blockquote><p>這個網站可能會損害您的電腦</p></blockquote>
<p>仔細看看是所有的網站都變成這樣了= =</p>
<div id="attachment_512" class="wp-caption alignnone" style="width: 252px"><a href="http://blog.ez2learn.com/wp-content/uploads/2009/01/googe-bug.png"><img class="size-medium wp-image-512" title="googe出問題" src="http://blog.ez2learn.com/wp-content/uploads/2009/01/googe-bug-242x300.png" alt="googe出問題" width="242" height="300" /></a><p class="wp-caption-text">googe出問題</p></div>
<p>仙人打鼓有時錯，連精明一世的Google也有腦殘出槌的一天阿= =</p>
<p>看來現在所有網站都被認為被植入病毒 XD，這麼一來就分不出到底哪個是有毒，哪個是沒毒了，全世界的電腦都中毒了，看來世界末日不遠了 XD 天網 Sky Net 背叛人類啦~</p>
<p>個人猜測是Google自己內部可能程式有問題放上線的可能比較大，例如測試碼沒清掉就上線= =" PTT上次權限大放送似乎就是這種狀況 至於Google到底會不會犯這種低等錯誤 我也不知道 不過被入侵也是有可能XD 總而言之我好期待Google如何解釋這次事件的原因</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2009/01/31/google-search-goes-wrong/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>資訊安全的策略 : 深度防禦</title>
		<link>http://blog.ez2learn.com/2008/12/15/information-security-strategy-deep-defence/</link>
		<comments>http://blog.ez2learn.com/2008/12/15/information-security-strategy-deep-defence/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 04:48:51 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[資訊安全]]></category>
		<category><![CDATA[理論]]></category>
		<category><![CDATA[Deep defence]]></category>
		<category><![CDATA[Defence in depth]]></category>
		<category><![CDATA[資安]]></category>
		<category><![CDATA[深度防禦]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=410</guid>
		<description><![CDATA[介紹深度防禦，和在資訊安全的應用 <a href="http://blog.ez2learn.com/2008/12/15/information-security-strategy-deep-defence/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>單薄的防禦</h2>
<p>在一般常見的系統中，很常見到只要一個漏洞被發現，然後攻擊，整台電腦就跟著淪陷，為何這麼的容易，原因出在於，防線只有一道，以戰爭來比擬，你的防線可能有十公里，在這十公里中，只要有個洞就可以讓敵人鑽進來，而進來以後就有如入無人之境，以資訊安全來看，假設你的主機是網頁伺服器，你的戰線有OS、SQL Server、Web Server等等各種可能會被攻擊的點，如果你的防線就只有這樣，那麼很可能只要其中一個環節被拿下就等於整台電腦淪陷，不管你再怎麼加強每個層面，世界上沒有不存在漏洞的系統，不存在沒有漏洞的系統，那我們到底能做什麼? 答案就是 : 深度防禦。</p>
<h2>什麼是深度防禦(<a href="http://en.wikipedia.org/wiki/Defence_in_depth">Defence in depth</a>)</h2>
<p>深度防禦最經典的應用，應該要算是<a href="http://vm.nthu.edu.tw/science/shows/nuclear/safety/index2.html">應用在核能發電廠</a>，我們都知道核能發電廠有著一定的風險，不容許有一絲的差錯，因為核能電廠的安全是極度重要的，因此核能電廠採取就是深度防禦的策略，說了半天，到底什麼是深度防禦，所謂的深度防禦，就是一層防線後面還有一層防線，每層防線都是獨立的，多元化的、且有備援的，舉個例子來說，核能發電需要水來冷卻反應爐，如果第一套水冷系統失效，還有第二套完全獨立的系統在一旁待命，立刻可以接著運作，如果不幸的，連第二套系統也失靈了，我們還有另一道防線，將控制棒插入反應爐吸收中子，就算這層失敗了，後面還有許多許多層的防線，在很外面有一層圍阻體，就算用戰機高速衝撞也不會有事，因此核能電廠是世界上最安全的電廠，因為這一連串防線要全部失效的機率比慧星撞地球還低，每次看到一些沒道德的環保團體欺騙民眾說核電廠會像車諾比那樣炸掉來反核就很火大，回到正題，雖然主題不是核電廠，不過講到這裡我們大概就可以了解，深度防禦的策略，其思維，還有帶來的好處，與壞處，我們接著就來看在資訊安全上要如何應用</p>
<ul>
<li>
<h2>多層的防護</h2>
</li>
</ul>
<p style="padding-left: 60px;">一層防禦是不夠的，如你所見只要一層失效了，就等於淪陷，因此深度防禦的理念之一，就是提供多層的保護，一層防火牆不夠? 再加一層，還覺得不夠? 再加一層，不過當然不是加越多防護就越安全，我們繼續看下去</p>
<ul>
<li>
<h2>多樣性的防護</h2>
</li>
</ul>
<p style="padding-left: 60px;">試想你加了100層防火牆來保護你重要的資料，但這100層防火牆全用的是同一套防火牆，只要這防火牆被發現某種漏洞，這100層的防火牆很可能變得跟紙一樣，因此多樣性是必要的，例如三層不同的防火牆，以駭客的角度來看，想要進入到最裡層就需要突破三層不同的防火牆，從此看來要強行突入的可能性就大大減少</p>
<ul>
<li>
<h2>獨立的組件</h2>
</li>
</ul>
<p style="padding-left: 60px;">系統的運作最好要能盡量獨立，假設所有系統的驗證是靠另一個系統，而只要那個系統被攻破，就等於依賴那個驗證系統的所有系統也跟著一起完蛋，因此獨立性也是非常重要的</p>
<ul>
<li>
<h2>備援系統</h2>
</li>
</ul>
<p style="padding-left: 60px;">當你的系統失效時，是否有備援機制? 舉個例子，魔獸世界有通訊鎖，似乎是透過電話來驗證以防止盜帳號，前陣子突然發生通訊鎖失效，玩家抱怨進不了遊戲，於是通訊鎖似乎就因此暫停了小段時間，以攻擊者的角度來看，如果是我要盜取帳號，就可以從這裡下手，首先癱瘓它的通訊鎖，逼他們在玩家的壓力之下把通訊鎖的服務暫時關掉，不必驗證就能登入，如此一來就造成了空檔，之前盜來的帳號本來少了手機驗證這關，無法登入，但是有了這個空檔或許就可以好好利用，從這個例子我們可以看到，重要的系統需要有備援的系統，否則當這個系統失效，就產生了安全性上的問題，而且也可能造成提供攻擊的空檔，駭客可以刻意癱渙該系統以取得攻擊的空檔</p>
<ul>
<li>
<h2>最小化的權限</h2>
</li>
</ul>
<p style="padding-left: 60px;">很常見的問題之一，就是使用過大的權限去執行做一些雞毛蒜皮的事，舉個例子，使用root來執行網頁伺服器，在這種情況下，只要網頁伺服器有什麼漏洞因此被利用了，就等於整台電腦的root被拿走了是一樣的，因此使用過大的權限是危險的行為，盡量將權限限制在能做好該做的任務就好的範圍，如此一來，就算某個帳號被拿下，也難以成大事，必須尋求其它管道</p>
<ul>
<li>
<h2>不要相信內部系統</h2>
</li>
</ul>
<p style="padding-left: 60px;">即使來到系統內部，也不該相信所有資料不是惡意的，考慮一下如果駭客只拿下最外面的系統，接著要往裡面的系統攻擊，如果裡面的系統天真的以為，來自內部系統的都是安全的，那同樣等於內部的系統也被拿下，因為太相信內部系統而不做檢查的後果，因此就算來到了防線的後方，也不該因此而偷懶不用考慮安全的問題，記得假設你的每個系統都可能被攻擊，就算來自內部的系統也可能是攻擊，你怎麼知道你旁邊的電腦是不是變成殭屍了? 你怎麼知道管理員的介面就不會被殖入XSS因此而不用檢查惡意的html? 因此"不要相信任何人"</p>
<h2>現實是&#8230;</h2>
<p>如果都做到了，攻擊你的系統會是一件非常困難的事，一層防禦還有一層，防禦的種類又是多樣性且不盡相同，都有備援，權限被最小化，即使拿到了也只是個沒什麼用的使用者，而系統內部也不相信其它系統，拿下來外圍的系統想藉此攻擊內部也是很困難，是的，理論上來講非常困難，但是真正值得考慮的應該是到底能夠做到多少? 越多越繁複的防禦表示越高的成本，想像一下你會拿這樣的方式來防禦王小明寫給隔壁阿花的情書嗎? 我想不會，除非那個很重要，但是相對的，如果是核子彈發射的系統，這樣做就很值得，你不會想看到核子武器把玩在script kid的手中吧? 因此深度防禦如果真的要達到有深度確實要花不少成本，但是其實不用很深，我們保護的不是核子彈，就算是客戶的資料，我們一樣可以盡量增加防禦的深度，事實上不用太深的深度，當你的資料沒有那個價值讓駭客去花那麼大的力氣取得時，到那樣的深度其實就已經足夠</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2008/12/15/information-security-strategy-deep-defence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>別讓危險成為預設的行為，讓危險的行為比安全的行為更麻煩</title>
		<link>http://blog.ez2learn.com/2008/12/13/dangerous-behavior-should-not-be-default-behavior/</link>
		<comments>http://blog.ez2learn.com/2008/12/13/dangerous-behavior-should-not-be-default-behavior/#comments</comments>
		<pubDate>Sat, 13 Dec 2008 13:56:23 +0000</pubDate>
		<dc:creator>victor</dc:creator>
				<category><![CDATA[中文文章]]></category>
		<category><![CDATA[資訊安全]]></category>
		<category><![CDATA[理論]]></category>
		<category><![CDATA[資安]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[TurboGears]]></category>

		<guid isPermaLink="false">http://blog.ez2learn.com/?p=390</guid>
		<description><![CDATA[危險的行為 對於寫程式而言，很多預設的行為都是相當危險的，舉一些最常見的例子SQL Injection、XSS、Buffer overflow，我們可以從這些幾個最常出現被攻擊的類形，都有一個共同的特點，就是它們通常都是因為預設的行為很危險，我們一個一個來看 SQL Injection 這是最常見的網頁程式攻擊手法之一，例如有一個SQL語法這樣寫 SELECT * FROM Member WHERE id = '$userId' userId沒有經過任何過濾，那麼這樣的程式等於打開了SQL的大門任惡意的使用者操作，考濾一下如果使用者帳號輸入這樣 &#8216;; SHUTDOWN &#8211; 如此一來整句SQL語法就會變成這樣 SELECT * FROM Member WHERE id = ''; SHUTDOWN --' SELECT的SQL語法後面被加上了一句Shutdown指令，如此一來SQL Server就會被關掉，當然這還稱不上太邪惡，要做任何事情幾乎都可以，只要SQL語法能辦到，很明顯地，危險來自預設的方式去下SQL指令，使用者，也就是程式設計師，如果沒有這方面的知識，那麼使用預設的行為是理所當然的事情，像PHP較後面的版本就有自動取代一些危險的字元，雖然有點麻煩，但至少它是一個方法，讓預設的行為不那麼的危險 XSS 接著是XSS，也就是Cross-site Scripting，這也一樣是危險的預設行為所引起的問題，假設我們有下面的一個簡單PHP程式 echo &#34;Hello &#34;; echo $userName; &#8230; <a href="http://blog.ez2learn.com/2008/12/13/dangerous-behavior-should-not-be-default-behavior/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>危險的行為</h2>
<p>對於寫程式而言，很多預設的行為都是相當危險的，舉一些最常見的例子SQL Injection、XSS、Buffer overflow，我們可以從這些幾個最常出現被攻擊的類形，都有一個共同的特點，就是它們通常都是因為預設的行為很危險，我們一個一個來看</p>
<p><span id="more-390"></span></p>
<h2>SQL Injection</h2>
<p>這是最常見的網頁程式攻擊手法之一，例如有一個SQL語法這樣寫</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> Member <span style="color: #993333; font-weight: bold;">WHERE</span> id <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'$userId'</span></pre></div></div>

<p>userId沒有經過任何過濾，那麼這樣的程式等於打開了SQL的大門任惡意的使用者操作，考濾一下如果使用者帳號輸入這樣</p>
<blockquote><p>&#8216;; SHUTDOWN &#8211;</p></blockquote>
<p>如此一來整句SQL語法就會變成這樣</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> Member <span style="color: #993333; font-weight: bold;">WHERE</span> id <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">''</span>; SHUTDOWN <span style="color: #808080; font-style: italic;">--'</span></pre></div></div>

<p>SELECT的SQL語法後面被加上了一句Shutdown指令，如此一來SQL Server就會被關掉，當然這還稱不上太邪惡，要做任何事情幾乎都可以，只要SQL語法能辦到，很明顯地，危險來自預設的方式去下SQL指令，使用者，也就是程式設計師，如果沒有這方面的知識，那麼使用預設的行為是理所當然的事情，像PHP較後面的版本就有自動取代一些危險的字元，雖然有點麻煩，但至少它是一個方法，讓預設的行為不那麼的危險</p>
<h2>XSS</h2>
<p>接著是XSS，也就是Cross-site Scripting，這也一樣是危險的預設行為所引起的問題，假設我們有下面的一個簡單PHP程式</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Hello &quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$userName</span><span style="color: #339933;">;</span></pre></div></div>

<p>看起來只是一個無傷大雅跟使用者打招呼的程式，考慮一下$userName變數如果沒有經過任何過濾，如果使用者將userName輸入成下面的資料</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--mce:0--&gt;&lt;/script&gt;</pre></div></div>

<p>這一樣是一個無傷大雅的小惡作劇，輸入這個資料會讓頁面標題被改成你想要的字串，但是把這程式碼改得更邪惡一點就不再是什麼有趣的事，很明顯地，這一樣又是一齣危險的預設行為所造成的悲劇，任何資料輸出都預設直接是完整地顯示出來，沒有經過任何過濾，像name這種顯而易見的欄位可能會被注意到並且記得過濾，那其它欄位呢? 今天我如果是攻擊者，任何可以輸入的欄位都是值得一試的，不是只有text box類形的表單元件才能輸入惡意的資料，因此過濾危險字元，便成了寫PHP網頁程式的重要任務，它是那麼的危險，但是它是預設行為</p>
<h2>Buffer overflow</h2>
<p>接著我們看Buffer overflow，這就算是比較困難一點的手法，SQL Injection那種只要把那句shutdown指令到處貼，<strong>連小孩子都有可能癱渙政府的網站</strong>，我相信只要寫一個bot去爬網站，然後輸入那句語法，被爬到的網站還是會有很多會掛掉，政府機構的網站也是外包的，裡面<strong>只要有一個菜鳥忘記濾語法(或是老練的工程師忘記過濾)，整個網站就完蛋了</strong>，但是Buffer overflow的手法就不一樣了，考慮一下下面的程式碼</p>
<pre lang="c++">void foo(char *userName) {
    char temp[16];
    strcpy(temp, user);
    // do something here....
}</pre>
<p>看起來不怎麼樣的函數，但卻潛藏著大大的危險，如果使用者名稱輸入的資料長度超過16字元，在stack中後面的資料就會被蓋掉，惡意經過設計的資料，會將後面的函數返回的位置蓋掉成想要執行的位置，例如資料本身夾帶一段惡意程式，其中函數返迴的位址改成資料夾帶的惡意程式的位址，如此一來就可以利用資料的輸入來使目的程式做想幹的壞事，原因一樣出在，strcpy預設的行為是不檢查字串長度的，但是因為要了解定址、Stack如何運作等底層的一些知識，絕對不是script kids可以輕易辦到的事，當然利用現成的工具就另當別論，但那還是script kids在幹的事</p>
<h2>危險當預設行為之於安全當預設行為</h2>
<p>PHP的預設行為通常都很危險，這就是我不太喜歡它的原因之一，需要有經驗的程式設計，並且用盡你的力氣想辦法去防堵任何可能的漏洞，你只要忘記一個地方，就等於打開了大門，之前做的辛苦就全白費了，<strong>不止是你，還有你得燒香拜拜祈求你的整個團隊裡沒有出任何一個天兵在程式的某個角落裡忘記過濾惡意資料</strong>，相較之下我使用Python寫的TurboGears開發了不少網站之後，發現它確確實實落實了"<strong>別讓危險成為預設的行為</strong>"的概念，所有在PHP見到那堆煩死人的危險預設行為都看不到</p>
<p>首先是SQL Injection，在TurboGears裡用的是SQLObject或是SQLAlchemy/Elixir等ORM的一層，使用者不必寫任何一句SQL語法，因為語法都由這層ORM產生，自然避開了SQL Injection的問題，任何資料透過這層都會被過濾掉，然而SQLAlchemy等ORM的完備性，並不會因此而限制到太多程式的自由</p>
<p>接著是XSS，TurboGears預設使用的是Kid Template，它是一款樣版引擎，任何輸出的HTML都必須是要合法的才能輸出，而且所有資料預設都是被過濾的，要輸出HTML的情況比較少，須要"明確地說出來"</p>
<p>例如下面一個簡單樣板</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">${userName}</pre></div></div>

<p>我們在這裡看到的userName預設就是把html過濾掉了，那你可能會說，如果我想輸出html怎麼辦，其實很簡單，像這樣</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">${XML(userProfile)}</pre></div></div>

<p>如你所見，Kid template用一個XML函數來明確地指出要輸出html，雖然那些資料也一樣須要自己過濾，但是想想看，80%以上的資料都只是資料只有20%以下的資料是html需要這樣輸出，而樣版引擎也處理了語法迴圈輸出等等的問題，你寶貴的開發時間不該浪費在過濾那些該死的惡意語法上不是嗎?</p>
<p>至於Buffer overflow，Python因為是高階的語言，天生就沒這種問題，除非c語言寫的模組有這樣的問題，又剛好有使用者輸入的資料會跑到那個c語言模組的漏洞</p>
<h2>危險的行為應該要被明確地說出來</h2>
<p>解決的方法，應該說在設計上，就應該要這麼做，讓危險的行為應該要被明確地說出來，例如echo預設就過濾所有包含在裡面的變數，想輸出html需要明確地指出，像是這樣</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;User's profile : &quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> XML<span style="color: #009900;">&#40;</span><span style="color: #000088;">$userProfile</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>這麼一來，只有少數需要將變數內裝html輸出的資料要用XML函數明確地指出來輸出，除此之外，十之八九的資料都不需要過濾，那麼危險的行為當預設行為，明明那麼少用到，變成過濾的工作一直都浪費在這些少數的情況上，這就是PHP很大的敗筆之一</p>
<p>接著是SQL Injection，一樣讓危險的事情需要明確的講出來，又或著用一層ORM之類的避免直接的SQL語法產生和字串合成</p>
<p>接著是Buffer overflow，最大的兇手就是strcpy這個函數，最初就不應該讓這樣的函數設計，造成無數的漏洞，不過當初又有誰會想到有這樣的漏洞，strcpy因為沒檢查邊界所以很危險，預設應該讓它檢查邊界，又或著是，乾脆不要有這樣的函數存在，當然它的存在有一定的方便性，而且檢查邊界又考濾到效能的問題，所以最好的辦法，還是一樣讓危險的行為被明確地指出來，像這樣假設在C++之下，預設是檢查邊界的行為</p>
<pre lang="c++">strcpy(temp, username);</pre>
<p>然而要不檢查邊界的寫法可能像這樣</p>
<pre lang="c++">strcpy(temp, username, NOCHECK);</pre>
<p>以某種程度來說，讓危險的行為麻煩一點總是比較好的，人們都會選擇比較輕鬆的寫法，而比較麻煩的寫法，除非有特別的需要，才會特別明確地指出，甚至不希望使用者去用的話，還可以故意讓危險的行為越麻煩越好</p>
<h2>最後</h2>
<p>切記別讓危險的行為成為預設值，特別是那些佔少數特例、又是極度危險的行為，實在沒有理由讓它們程為預設或是最常用的方法，反而要特別來過濾</p>
<blockquote>
<h2><strong>別讓危險成為預設的行為，讓危險的行為比安全的行為更麻煩</strong></h2>
</blockquote>
<p><strong>&#8212;&#8212;</strong></p>
<p>修改 : 原本strcpy誤植為strlen 奇怪= = 我怎麼會寫成strlen..</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ez2learn.com/2008/12/13/dangerous-behavior-should-not-be-default-behavior/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

