
從XSS凈化到OAuth登錄Wri.pe安全設計完整清單與自查教程【免費下載鏈接】open-wripehttps://wri.pe source code項目地址: https://gitcode.com/gh_mirrors/op/open-wripeWri.pe 是一款開源的 Web 個人筆記應用https://wri.pe 的源代碼核心能力包括 Markdown 筆記編輯、多端日歷視圖、頁面分享以及 GitHub、Facebook、Evernote、Dropbox 等第三方登錄與同步。對于筆記里存著敏感內容的產品來說安全設計不是可選項。本文帶你用8 個真實代碼點完整拆解 Wri.pe 的安全機制并附一份可直接抄走的自查清單。 Wri.pe 安全設計總覽清單先給一張全景表后面逐項展開#安全維度Wri.pe 的做法關鍵文件1XSS 防護Markdown 渲染后二次凈化 鏈接協議白名單app/models/page.rb2前端轉義模板統一escape_htmlapp/assets/javascripts/shared/utils.js.coffee3CSRF 防護protect_from_forgery 失敗降級處理app/controllers/application_controller.rb4會話管理session 只存用戶 ID登出即重置app/controllers/sessions_controller.rb5OAuth 登錄GitHub/Facebook 走 OAuth2Evernote 走 OAuth1.0alib/ghauth.rb、lib/evernote_auth.rb6密鑰管理敏感配置獨立 YAML按環境加載config/github-sample.yml7數據權限讀/寫/分享三級權限越權返回 403app/models/page.rb8并發安全lock_version樂觀鎖沖突返回 409app/controllers/pages_controller.rb? 深度一XSS 凈化——先渲染再消毒最后查戶口筆記應用最大的風險是用戶輸入 Markdown → 渲染成 HTML → 危險標簽被瀏覽器執行。Wri.pe 在 app/models/page.rb 的body_html方法里做了三道防線第一道渲染。用 Redcarpet 把 Markdown 轉成 HTML開啟lax_html_blocks等選項支持富文本。第二道凈化。HTML 交給sanitize庫清洗Sanitize.clean(html, Sanitize::Config::RELAXED)依據白名單移除script、onerror等危險節點和屬性依賴聲明在 Gemfile 中升級時建議同步關注安全公告。第三道鏈接協議白名單。用 Nokogiri 遍歷所有a標簽只保留http/https協議的 href其余比如javascript:alert(1)這種直接被降級為span并刪掉 href——等于給每個鏈接查戶口。前端也同步轉義JS 模板中拼接用戶數據前統一走escape_html底層是 lodash 的_.escape見 app/assets/javascripts/shared/utils.js.coffee例如日歷面板里插入標題前先轉義# app/assets/javascripts/app/calendar_panel.js.coffee li class\page\a href\\##{escape_html(p.key)}/edit\#{escape_html(p.title)}/a/li 自查要點凡是有用戶輸入 → HTML路徑的地方問自己三個問題服務端凈化了嗎白名單是什么前端拼接轉義了嗎 深度二CSRF 與會話——給每個請求發防偽貼紙Wri.pe 的控制器全部繼承自 app/controllers/application_controller.rb其中兩處設計很值得借鑒全局開啟 CSRF 防護protect_from_forgery一行代碼所有表單和寫操作都必須攜帶合法 token。失敗的優雅降級handle_unverified_request拋出的InvalidAuthenticityToken被統一攔截——HTML 請求重定向回首頁JSON 請求返回412 Precondition Failed。對單頁應用SPA的 AJAX 調用特別友好前端能明確感知token 失效并引導重新登錄。會話本身保持極簡app/controllers/sessions_controller.rb 中 session 里只存authorized_user_id一個整數用戶信息實時查庫并校驗active?狀態。登出時調用reset_session徹底清空sessions_controller.rb避免 session 固定攻擊。同時前端每次啟動都會向服務端拉取最新的csrf_token用于后續 API 請求。 自查要點會話里是否存了不必要的敏感數據token 校驗失敗時接口返回是否能讓前端做正確處理 深度三OAuth 登錄——第三方賬號的安全接入Wri.pe 支持四種第三方登錄源碼分布清晰服務協議授權模塊回調控制器GitHubOAuth 2.0lib/ghauth.rbapp/controllers/ghauth_controller.rbFacebookOAuth 2.0lib/fbauth.rbapp/controllers/fbauth_controller.rbEvernoteOAuth 1.0alib/evernote_auth.rbapp/controllers/evernote_auth_controller.rbDropboxOAuth見模型 app/models/dropbox_user.rbapp/controllers/dropbox_auth_controller.rb以 GitHub 為例流程只有兩步app/controllers/ghauth_controller.rb發起授權302 跳轉到 GitHub 的授權頁只申請最小權限scope: user:email——這是 OAuth 安全里最小權限原則的典型示范回調換 token拿code換取 access_token驗證用戶身份后把user.id寫入 session 并跳轉首頁。兩個細節很見功力控制器頂部rescue_from OAuth::Unauthorized授權異常統一重定向回首頁不會把堆棧暴露給用戶回調中的 token 交換用rescue e兜底失敗只記日志 友好提示絕不把 token 或異常細節渲染到頁面。密鑰管理是 OAuth 安全的另一半client_id/client_secret放在獨立 YAML 中且按環境隔離——倉庫里只提供 config/github-sample.yml、config/evernote-sample.yml 等模板真實密鑰通過 lib/ghauth.rb 里的YAML.load(...)[Rails.env]按當前環境加載。部署時替換模板即可模板文件本身不含任何秘密。 自查要點OAuth 權限范圍是否最小化token 是否只出現在日志和內存中密鑰是否隨環境隔離且模板入庫 深度四數據權限與并發——最后一道門即使前面全部做對誰能看什么也不能失守。Wri.pe 在 app/models/page.rb 定義了三級權限permit_read?本人、公開頁SHARE_URL或被授權的協作者可讀permit_write?/permit_share?本人或顯式授予寫/分享權限的用戶。控制器里 app/controllers/pages_controller.rb 的show/update/destroy都在第一行就檢查權限越權直接403 Forbidden先鑒權再干活。并發安全方面頁面表帶lock_version字段樂觀鎖更新時若客戶端提交的版本號落后于服務端app/controllers/pages_controller.rb直接返回409 Conflict而不是盲目覆蓋——多人協作場景下避免后寫覆蓋先寫的數據丟失。另外用戶的備份導出鏈接靠創建時隨機生成的 96 位export-key保護app/models/user.rb相當于URL 即憑證無法被枚舉猜測。? 安全自查教程5 問清單可直接套用到你的項目XSS所有用戶輸入 → HTML的路徑服務端有白名單凈化嗎前端拼接有統一轉義函數嗎參考body_html的三道防線CSRF全局開了 forgery 防護嗎token 失效時接口返回能驅動前端重新登錄嗎會話session 里存的最小化嗎登出是否reset_session用戶狀態失效后舊會話是否立刻作廢OAuthscope 最小化了嗎異常路徑會不會泄露 token/堆棧密鑰是否入庫權限與并發每個數據接口第一行是鑒權嗎寫操作有版本號或等價機制嗎 延伸閱讀核心模塊路徑數據模型與凈化邏輯app/models/page.rb權限與會話基類app/controllers/application_controller.rb頁面接口鑒權/樂觀鎖app/controllers/pages_controller.rbOAuth 模塊lib/ghauth.rb、lib/fbauth.rb、lib/evernote_auth.rb會話管理app/controllers/sessions_controller.rb依賴聲明Gemfile登錄功能測試spec/features/Wri.pe 的安全設計沒有炫技全是小步到位凈化用白名單、授權用最小 scope、鑒權放在接口第一行、密鑰按環境隔離。這正是開源項目最值得新手抄作業的地方——每一條防護都有對應的具體代碼可以對照學習。【免費下載鏈接】open-wripehttps://wri.pe source code項目地址: https://gitcode.com/gh_mirrors/op/open-wripe創作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考