{"id":20838051,"url":"https://github.com/timcsy/websecuritydemo","last_synced_at":"2026-04-22T15:34:19.652Z","repository":{"id":187409699,"uuid":"296685433","full_name":"timcsy/WebSecurityDemo","owner":"timcsy","description":null,"archived":false,"fork":false,"pushed_at":"2020-09-20T06:22:13.000Z","size":416,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-26T05:03:48.968Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timcsy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-09-18T17:18:17.000Z","updated_at":"2020-09-20T06:22:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"49e411fa-544e-4793-a6f1-02ee579e8cb9","html_url":"https://github.com/timcsy/WebSecurityDemo","commit_stats":null,"previous_names":["timcsy/websecuritydemo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/timcsy/WebSecurityDemo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timcsy%2FWebSecurityDemo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timcsy%2FWebSecurityDemo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timcsy%2FWebSecurityDemo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timcsy%2FWebSecurityDemo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timcsy","download_url":"https://codeload.github.com/timcsy/WebSecurityDemo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timcsy%2FWebSecurityDemo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32143651,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T15:33:03.595Z","status":"ssl_error","status_checked_at":"2026-04-22T15:30:42.712Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-18T01:09:17.097Z","updated_at":"2026-04-22T15:34:19.620Z","avatar_url":"https://github.com/timcsy.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"網路安全 Demo\n===\n\n這是一個簡單呈現一些網路攻擊的專案。\n\n![](images/forum.png)\n\n前置作業\n---\n\n這裡有分兩類檔案：\n\n第一種是 .html 檔，是用來呈現簡單的 JavaScript 功能，如何與網路安全扯上關係\n\n第二種是 .php 檔，這不能像 .html 一樣可以直接用瀏覽器開啟，必須架設 PHP 的伺服器，\n\n而這些 .php 檔是在創造一個沒有做什麼資安防護的環境，這裡使用會員系統與留言板來呈現。\n\n（註：delete.html 是屬於第二部分的檔案）\n\n### 環境需求\n\nHTML 檔可以直接用瀏覽器開啟。\n\nPHP 的執行環境可以使用 docker 安裝（網路很多教學），或者在 Windows 上的話也可以安裝 wamp。\n\n終極的目的是要一個可以執行 PHP 的環境、可以使用 MySQL。\n\n筆者的做法是在電腦裝 php 7，這樣直接在專案目錄下用終端機執行\n\n```\nphp -S localhost:8000\n```\n\n就可以在 http://localhost:8000 執行 php 程式（微型 server）。\n\n至於 MySQL 的部分是用 docker 安裝 mysql 和 phpMyAdmin（可以瀏覽 MySQL 的工具），\n\n安裝（使用 docker 的 Kitematic）的注意事項是：\n\nmysql 要設置 MYSQL_ROOT_PASSWORD 參數，\n\nphpMyAdmin 的 Network 的 Links 要加入一條：把 mysql 對應到 ALIAS db。\n\n這樣就可以在映射出來的 port 使用 mysql 和 phpMyAdmin 了！（建議也固定 port 設定）。\n\n### 資料庫設定\n\n本專案需要兩張資料表\n\nforum:\n```\nCREATE TABLE `forum` (\n  `id` int NOT NULL,\n  `name` text NOT NULL,\n  `text` text NOT NULL\n)\n\nALTER TABLE `forum`\n  ADD PRIMARY KEY (`id`);\n\nALTER TABLE `forum`\n  MODIFY `id` int NOT NULL AUTO_INCREMENT\n```\n\nusers:\n```\nCREATE TABLE `users` (\n  `id` int NOT NULL,\n  `username` varchar(255) NOT NULL,\n  `password` varchar(255) NOT NULL\n)\n\nALTER TABLE `users`\n  ADD PRIMARY KEY (`id`),\n  ADD UNIQUE KEY `username` (`username`);\n\nALTER TABLE `users`\n  MODIFY `id` int NOT NULL AUTO_INCREMENT;\n```\n\n對於使用者密碼驗證需要執行此命令：\n```\nALTER USER '使用者名稱' IDENTIFIED WITH mysql_native_password BY '使用者密碼';\n```\n\n### 環境變數設定\n\n需要於專案的根目錄新增一個 env.php 檔（或拿 env.php.template 來修改）如下：\n\n```\n\u003c?\n$DB_HOST = '資料庫主機名稱';\n$DB_USER = '資料庫使用者名稱';\n$DB_PASSWORD = '資料庫使用者密碼';\n$DB_NAME = '資料庫的名稱';\n?\u003e\n```\n\n\n介紹\n---\n\n### 先備知識（Cookie \u0026 Session）\n\n[SessionID.cookie,Session傻傻分不清楚??](https://dotblogs.com.tw/daniel/2017/04/08/110915)\n\n[介紹 Session 及 Cookie 兩者的差別說明](https://blog.hellojcc.tw/introduce-session-and-cookie/)\n\n儲存位置：\n\nCookie -\u003e Client 端\n\nSession -\u003e Server 端\n\nSession ID -\u003e Cookie 中\n\n\n### JavaScript 的攻擊性\n\n前半段在說明網路攻擊常用在 JavaScript 的哪些特性\n\n註：我們常用 `alert()` 函數做簡單的呈現，因為它可以跳出警告視窗，上面放我們提供的訊息。\n\n#### 重新導向（參考 redirection.html、harmful.html）\n\nJavaScript 重新導向（Redirect）的語法範例（假設 3000 毫秒後跳轉）：\n\n```=JavaScript\n\u003cscript\u003e\n\tsetTimeout(() =\u003e {\n\t\tlocation.href = 'harmful.html'\n\t}, 3000)\n\u003c/script\u003e\n```\n\n#### 彈跳式視窗（參考 adgen.html、ad.html）\n\nJavaScript 彈跳的語法範例（假設開 10 個視窗）：\n\n```=JavaScript\n\u003cscript\u003e\n\tfor (let i = 0; i \u003c 10; i++) {\n\t\twindow.open('ad.html?' + (i + 1), i, 'popup')\n\t}\n\u003c/script\u003e\n```\n\n#### HTML 標籤：\\\u003ciframe\u003e、\\\u003cimg\u003e、手動的按鈕（參考 iframe.html、img.html）\n\n這些標籤的共同特性為「可以執行JavaScript」!\n\n\\\u003ciframe\u003e 中置入 JavaScript 的語法範例（在 onload 中放入 JavaScript 碼）：\n\n```=JavaScript\n\u003ciframe onload=\"alert('竊取的 Cookie：\\n' + document.cookie);\"\u003e\u003c/iframe\u003e\n```\n\n\\\u003ciframe\u003e 中置入 JavaScript 第二種情形的範例（在 src=\"javascript:\" 中放入 JavaScript 碼）：\n\n```=JavaScript\n\u003ciframe src=\"javascript:alert('竊取的 Cookie：\\n' + document.cookie);\"\u003e\u003c/iframe\u003e\n```\n\n\\\u003cimg\u003e 中置入 JavaScript 的語法範例（在 onerror 中放入 JavaScript 碼，再加入一個失效連結）：\n\n```=JavaScript\n\u003cimg src=\"錯誤的網址\" onerror=\"alert('竊取的 Cookie：\\n' + document.cookie);\"\u003e\n```\n\n按鈕的範例就省略了（使用 onclick 即可）。\n\n#### 讀取 Cookie 與 Session ID（參考 view_cookie.html）\n\n因為 Session ID 會存在 Cookie 中，所以如果取得 Cookie 就可以取得 Session ID。\n\n但如果有被 HttpOnly 屬性保護的 Cookie 記錄就不能被 JavaScript 讀到了。\n\nJavaScript 讀取 Cookie 的方式很簡單（但是是沒有處理過的）：\n\n```=JavaScript\ndocument.cookie\n```\n\n如果要跳出警告視窗：\n\n```=JavaScript\n\u003cscript\u003ealert(document.cookie)\u003c/script\u003e\n```\n\n### 常見的網路攻擊\n\n我們是用 PHP 實作出會員系統、留言版來呈現這個部分。\n\n![](images/forum.png)\n\n以下是常見的攻擊：\n\n#### XSS（Cross-Site Scripting，跨網站指令碼）\n\n![](images/xss.jpg)\n\n介紹\n- Script 放置於文字或是圖片等區塊\n- 攻擊者先植入一些代碼\n- 使用者來瀏覽的時候就被這些代碼攻擊\n- [跨網站指令碼（XSS）](https://zh.wikipedia.org/wiki/跨網站指令碼)\n- [淺談兩種常見的跨站攻擊（XSS和CSRF）](https://kknews.cc/tech/z633bbl.html)\n- [那些年我们一起学XSS](https://www.ctolib.com/docs/sfile/xss-naxienian/index.html)\n\n情境\n- 重新導向\n- 彈出式廣告\n- 竊取 cookie\n- 你能想像用JavaScript做得到的事（參考上面）\n\n防範\n- 過濾特殊字元\n\t- 對輸入做檢查（是否有 HTML Tag 之類的）\n- 指定 render 出來的文件類型\n  - http header\n  - JavaScript 不會當成 HTML 解釋\n\nDemo\n- 先去 http://localhost:8000 （或是你的 host address）註冊並且登入\n- 你會看到一個留言板系統\n- 可以試著將上面所有提到的 Javascript 碼複製到留言框\n- 因為我們沒有對留言做檢查，所以可能將這個 HTML 元素呈現出來\n  - 因為 PHP 的運作是先在後端跑過一遍，再將已經渲染好的 HTML 丟到前端顯示\n  - 所以我們所留言的文字會直接被當成真的 HTML 元素處理\n\n#### CSRF（Cross-site request forgery，跨站請求偽造）\n\n![](images/csrf.jpg)\n\n介紹\n- Request 放在超連結、按鈕或是圖片等有連結的地方\n- 使用者先登入，（而且沒有關閉瀏覽器）\n- 在另外的地方（網站）進行需要登入等等的敏感操作\n- [讓我們來談談 CSRF](http://blog.techbridge.cc/2017/02/25/csrf-introduction/)\n\n情境\n- Call API\n- 對資料進行 CRUD 操作\n- 進行交易\n- 高級隱身術\n\n防範\n- 概念：擋掉從別的 domain 來的 request（共同小秘密）\n  - 加上圖形驗證碼、簡訊驗證碼等等\n  - 加上 CSRF token（回應當下隨機產生的）\n  - Double Submit Cookie\n    - 比對token和cookie是否一樣（同源）\n  - SameSite cookie\n\nDemo\n- 當我們維持登入中的時候，我們從其他地方呼叫（誤按）以下連結：\n  ```\n  http://localhost:8000/delete.php?id=要刪除的留言id\n  ```\n  在留言板介面將滑鼠移到「刪除」上面，左下角就會顯示\n\t\u003e ![](images/delete.png)\n  \u003e \n  可以在「刪除」按鈕的上面點選「複製連結網址」\n- 去到檔案系統，用瀏覽器開啟根目錄的「delete.html」(這樣 domain 就會是 null，與 localhost 不同) \n- 在「貼上刪除留言的網址」中貼上剛剛複製的網址，按確定\n- 這時就會出現一個「心理測驗」的連結，但網址其實是剛剛複製過來的那個\n  \u003e ![](images/csrf.png)\n- 可以發現我們的留言被刪除了！（delete.php 刪除後會重新導向回 forum.php）\n- 因為這個請求是需要權限的，但是因為我們沒有關閉瀏覽器或登出，所以 Session 紀錄還在，這樣攻擊者就可以取得權限\n- 這是讓使用者自己點擊，也有的攻擊會放在 \\\u003cimg\u003e 標籤中，或是製造一個假表單\n\n#### SQL injection（SQL注入）\n\n![](images/sql.png)\n\n介紹\n- [一次看懂 SQL Injection 的攻擊原理](https://medium.com/@jaydenlin/淺談駭客攻擊-網站安全-一次看懂-sql-injection-的攻擊原理-b1994fd2392a)\n- 用恆等式破解 SQL 查詢\n\n情境\n- 免輸入密碼\n  - e.g. `' OR '1'='1`\n- 繞過權限使用 API（內部進行一些 SQL 操作），像是取得會員獨享文章等等\n\n防範\n- 參數的類型檢查\n- hashing the password\n\nDemo\n\n![](images/pwd.png)\n\n- 在登入介面，帳號隨便輸入（不必先行註冊也行）\n- 密碼打 `' OR '1'='1`\n- 這樣便可以成功登入！\n- 原因是因為，這個專案的登入檢查的寫法為：\n\t```\n\t\"SELECT * FROM users WHERE username = '\". $username. \"' and password = '\". $password. \"'\"\n\t```\n\t假設今天 $username = guest, $password = pwd，那麼上面 SQL 指令會是\n\t```\n\tSELECT * FROM users WHERE username = 'guest' and password = 'pwd'\n\t```\n\t所以如果我讓 $password = `' OR '1'='1`，那麼上面 SQL 指令會是\n\t```\n\tSELECT * FROM users WHERE username = 'guest' and password = '' OR '1'='1'\n\t```\n\t最後會有一個恆等式 `'1'='1'`，前面又是用 OR 結合，一個對的敘述 OR 任意敘述結果一定是對的，\n\t所以我就符合登入條件了！\n\n#### HTTP Session\n\n介紹\n- [HTTP Session 攻擊與防護](https://devco.re/blog/2014/06/03/http-session-protection/)\n\n情境：取得 cookie 中的敏感資訊（session key）\n- 由 XSS 竊取\n- 用 ARP欺騙技術(ARP spoofing)中間人攻擊來竊聽\n- 如果允許透過 URL 傳遞 Session ID\n- 先取得 Session ID 再給不知情的人用\n\n防範\n- 確認身份：IP、瀏覽器 User-Agent\n- Cookie\n  - 設定 Secure Flag (HTTPS)\n  - 設定 HTTP Only Flag\n- 有狀況就換新\n  - 成功登入後立即變更 Session ID\n\nDemo\n- 這個專案不實作這部分\n- 但是可以在 Chrome 中開啟「開發人員工具」，去到「Application」頁籤\n- 點選 Cookies 下面的網站地址\n- 接下來就會看到這個網站的 Cookies，我們可以特別去觀察「PHPSESSID」，這就是 PHP 的 Session ID\n- 因為我有把 PHP 的 HttpOnly 設成 true，所以這裡會看到他是打勾的\n\t![](images/httponly.jpg)\n- 如果在 https 底下也會開啟 Secure（如果用 http 卻又開啟的話會讀不到 Session）\n\n\n### 進階練習\n\n這裡列出一些封包擷取分析的工具，有興趣可以來練習。\n\n- [封包分析器](https://zh.wikipedia.org/wiki/數據包分析器)\n- [Pcap (packet capture)](https://zh.wikipedia.org/wiki/Pcap)\n    - 用於捕獲網絡流量的應用程式接口（API）\n    - [TCPDUMP/LIBPCAP public repository](https://www.tcpdump.org/)\n- [tcpdump](https://zh.wikipedia.org/wiki/Tcpdump)\n    - 執行在命令行下的嗅探工具\n- [Wireshark](https://zh.wikipedia.org/wiki/Wireshark)\n    - 免費開源的網路封包分析軟體\n- [Scapy](https://zh.wikipedia.org/wiki/Scapy)\n    - 用於處理掃描、跟蹤\n\n參考資料\n---\n- [Page hijacking - Wiki](https://en.wikipedia.org/wiki/Page_hijacking)\n- [2015年的漏洞攻擊包（Exploit Kit）：充斥著Flash漏洞、淪陷網站和惡意廣告](https://blog.trendmicro.com.tw/?p=17109)\n- [SessionID.cookie,Session傻傻分不清楚??](https://dotblogs.com.tw/daniel/2017/04/08/110915)\n- [Egg.js Security](https://eggjs.org/zh-cn/core/security.html)\n- [淺談兩種常見的跨站攻擊（XSS和CSRF）](https://kknews.cc/tech/z633bbl.html)\n- [跨網站指令碼（XSS）](https://zh.wikipedia.org/wiki/跨網站指令碼)\n- [那些年我们一起学XSS](https://www.ctolib.com/docs/sfile/xss-naxienian/index.html)\n- [讓我們來談談 CSRF](http://blog.techbridge.cc/2017/02/25/csrf-introduction/)\n- [一次看懂 SQL Injection 的攻擊原理](https://medium.com/@jaydenlin/淺談駭客攻擊-網站安全-一次看懂-sql-injection-的攻擊原理-b1994fd2392a)\n- [HTTP Session 攻擊與防護](https://devco.re/blog/2014/06/03/http-session-protection/)\n- [如何使用ARP欺騙技術(ARP spoofing)進行中間人攻擊](https://www.uuu.com.tw/Public/content/article/20/20200217.htm)\n- [封包分析器](https://zh.wikipedia.org/wiki/數據包分析器)\n- [Pcap (packet capture)](https://zh.wikipedia.org/wiki/Pcap)\n- [TCPDUMP/LIBPCAP public repository](https://www.tcpdump.org/)\n- [tcpdump](https://zh.wikipedia.org/wiki/Tcpdump)\n- [Wireshark](https://zh.wikipedia.org/wiki/Wireshark)\n- [Scapy](https://zh.wikipedia.org/wiki/Scapy)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimcsy%2Fwebsecuritydemo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimcsy%2Fwebsecuritydemo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimcsy%2Fwebsecuritydemo/lists"}