mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-09-17 08:46:40 +08:00
1227 lines
34 KiB
HTML
1227 lines
34 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
|
||
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
|
||
<head>
|
||
|
||
<head>
|
||
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
|
||
|
||
<link rel="icon" href="/static/favicon.png">
|
||
|
||
<title>34 账号密码泄露成灾,应该怎样预防?.md.html</title>
|
||
|
||
<!-- Spectre.css framework -->
|
||
|
||
<link rel="stylesheet" href="/static/index.css">
|
||
|
||
<!-- theme css & js -->
|
||
|
||
<meta name="generator" content="Hexo 4.2.0">
|
||
|
||
</head>
|
||
|
||
|
||
|
||
<body>
|
||
|
||
|
||
|
||
<div class="book-container">
|
||
|
||
<div class="book-sidebar">
|
||
|
||
<div class="book-brand">
|
||
|
||
<a href="/">
|
||
|
||
<img src="/static/favicon.png">
|
||
|
||
<span>技术文章摘抄</span>
|
||
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<div class="book-menu uncollapsible">
|
||
|
||
<ul class="uncollapsible">
|
||
|
||
<li><a href="/" class="current-tab">首页</a></li>
|
||
|
||
</ul>
|
||
|
||
|
||
|
||
<ul class="uncollapsible">
|
||
|
||
<li><a href="../">上一级</a></li>
|
||
|
||
</ul>
|
||
|
||
|
||
|
||
<ul class="uncollapsible">
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/00 开篇词 你为什么应该学好软件工程?.md.html">00 开篇词 你为什么应该学好软件工程?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/01 到底应该怎样理解软件工程?.md.html">01 到底应该怎样理解软件工程?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/02 工程思维:把每件事都当作一个项目来推进.md.html">02 工程思维:把每件事都当作一个项目来推进.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/03 瀑布模型:像工厂流水线一样把软件开发分层化.md.html">03 瀑布模型:像工厂流水线一样把软件开发分层化.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/04 瀑布模型之外,还有哪些开发模型?.md.html">04 瀑布模型之外,还有哪些开发模型?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/05 敏捷开发到底是想解决什么问题?.md.html">05 敏捷开发到底是想解决什么问题?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/06 大厂都在用哪些敏捷方法?(上).md.html">06 大厂都在用哪些敏捷方法?(上).md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/07 大厂都在用哪些敏捷方法?(下).md.html">07 大厂都在用哪些敏捷方法?(下).md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/08 怎样平衡软件质量与时间成本范围的关系?.md.html">08 怎样平衡软件质量与时间成本范围的关系?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/09 为什么软件工程项目普遍不重视可行性分析?.md.html">09 为什么软件工程项目普遍不重视可行性分析?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/10 如果你想技术转管理,先来试试管好一个项目.md.html">10 如果你想技术转管理,先来试试管好一个项目.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/11 项目计划:代码未动,计划先行.md.html">11 项目计划:代码未动,计划先行.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/12 流程和规范:红绿灯不是约束,而是用来提高效率.md.html">12 流程和规范:红绿灯不是约束,而是用来提高效率.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/13 白天开会,加班写代码的节奏怎么破?.md.html">13 白天开会,加班写代码的节奏怎么破?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/14 项目管理工具:一切管理问题,都应思考能否通过工具解决.md.html">14 项目管理工具:一切管理问题,都应思考能否通过工具解决.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/15 风险管理:不能盲目乐观,凡事都应该有B计划.md.html">15 风险管理:不能盲目乐观,凡事都应该有B计划.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/16 怎样才能写好项目文档?.md.html">16 怎样才能写好项目文档?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/17 需求分析到底要分析什么?怎么分析?.md.html">17 需求分析到底要分析什么?怎么分析?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/18 原型设计:如何用最小的代价完成产品特性?.md.html">18 原型设计:如何用最小的代价完成产品特性?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/19 作为程序员,你应该有产品意识.md.html">19 作为程序员,你应该有产品意识.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/20 如何应对让人头疼的需求变更问题?.md.html">20 如何应对让人头疼的需求变更问题?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/21 架构设计:普通程序员也能实现复杂系统?.md.html">21 架构设计:普通程序员也能实现复杂系统?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/22 如何为项目做好技术选型?.md.html">22 如何为项目做好技术选型?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/23 架构师:不想当架构师的程序员不是好程序员.md.html">23 架构师:不想当架构师的程序员不是好程序员.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/24 技术债务:是继续修修补补凑合着用,还是推翻重来?.md.html">24 技术债务:是继续修修补补凑合着用,还是推翻重来?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/25 有哪些方法可以提高开发效率?.md.html">25 有哪些方法可以提高开发效率?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/26 持续交付:如何做到随时发布新版本到生产环境?.md.html">26 持续交付:如何做到随时发布新版本到生产环境?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/27 软件工程师的核心竞争力是什么?(上).md.html">27 软件工程师的核心竞争力是什么?(上).md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/28 软件工程师的核心竞争力是什么?(下).md.html">28 软件工程师的核心竞争力是什么?(下).md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/29 自动化测试:如何把Bug杀死在摇篮里?.md.html">29 自动化测试:如何把Bug杀死在摇篮里?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/30 用好源代码管理工具,让你的协作更高效.md.html">30 用好源代码管理工具,让你的协作更高效.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/31 软件测试要为产品质量负责吗?.md.html">31 软件测试要为产品质量负责吗?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/32 软件测试:什么样的公司需要专职测试?.md.html">32 软件测试:什么样的公司需要专职测试?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/33 测试工具:为什么不应该通过QQ微信邮件报Bug?.md.html">33 测试工具:为什么不应该通过QQ微信邮件报Bug?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
<a class="current-tab" href="/专栏/软件工程之美/34 账号密码泄露成灾,应该怎样预防?.md.html">34 账号密码泄露成灾,应该怎样预防?.md.html</a>
|
||
|
||
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/35 版本发布:软件上线只是新的开始.md.html">35 版本发布:软件上线只是新的开始.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/36 DevOps工程师到底要做什么事情?.md.html">36 DevOps工程师到底要做什么事情?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/37 遇到线上故障,你和高手的差距在哪里?.md.html">37 遇到线上故障,你和高手的差距在哪里?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/38 日志管理:如何借助工具快速发现和定位产品问题 ?.md.html">38 日志管理:如何借助工具快速发现和定位产品问题 ?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/39 项目总结:做好项目复盘,把经验变成能力.md.html">39 项目总结:做好项目复盘,把经验变成能力.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/40 最佳实践:小团队如何应用软件工程?.md.html">40 最佳实践:小团队如何应用软件工程?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/41 为什么程序员的业余项目大多都死了?.md.html">41 为什么程序员的业余项目大多都死了?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/42 反面案例:盘点那些失败的软件项目.md.html">42 反面案例:盘点那些失败的软件项目.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/43 以VS Code为例,看大型开源项目是如何应用软件工程的?.md.html">43 以VS Code为例,看大型开源项目是如何应用软件工程的?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/44 微软、谷歌、阿里巴巴等大厂是怎样应用软件工程的?.md.html">44 微软、谷歌、阿里巴巴等大厂是怎样应用软件工程的?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/45 从软件工程的角度看微服务、云计算、人工智能这些新技术.md.html">45 从软件工程的角度看微服务、云计算、人工智能这些新技术.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/一问一答第1期 30个软件开发常见问题解决策略.md.html">一问一答第1期 30个软件开发常见问题解决策略.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/一问一答第2期 30个软件开发常见问题解决策略.md.html">一问一答第2期 30个软件开发常见问题解决策略.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/一问一答第3期 18个软件开发常见问题解决策略.md.html">一问一答第3期 18个软件开发常见问题解决策略.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/一问一答第4期 14个软件开发常见问题解决策略.md.html">一问一答第4期 14个软件开发常见问题解决策略.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/一问一答第5期 22个软件开发常见问题解决策略.md.html">一问一答第5期 22个软件开发常见问题解决策略.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/学习攻略 怎样学好软件工程?.md.html">学习攻略 怎样学好软件工程?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/特别放送 从软件工程的角度解读任正非的新年公开信.md.html">特别放送 从软件工程的角度解读任正非的新年公开信.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/软件工程之美/结束语 万事皆项目,软件工程无处不在.md.html">结束语 万事皆项目,软件工程无处不在.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
|
||
|
||
<div class="sidebar-toggle-inner"></div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<script>
|
||
|
||
function add_inner() {
|
||
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
|
||
inner.classList.add('show')
|
||
|
||
}
|
||
|
||
|
||
|
||
function remove_inner() {
|
||
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
|
||
inner.classList.remove('show')
|
||
|
||
}
|
||
|
||
|
||
|
||
function sidebar_toggle() {
|
||
|
||
let sidebar_toggle = document.querySelector('.sidebar-toggle')
|
||
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
|
||
let content = document.querySelector('.off-canvas-content')
|
||
|
||
if (sidebar_toggle.classList.contains('extend')) { // show
|
||
|
||
sidebar_toggle.classList.remove('extend')
|
||
|
||
sidebar.classList.remove('hide')
|
||
|
||
content.classList.remove('extend')
|
||
|
||
} else { // hide
|
||
|
||
sidebar_toggle.classList.add('extend')
|
||
|
||
sidebar.classList.add('hide')
|
||
|
||
content.classList.add('extend')
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
function open_sidebar() {
|
||
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
|
||
sidebar.classList.add('show')
|
||
|
||
overlay.classList.add('show')
|
||
|
||
}
|
||
|
||
function hide_canvas() {
|
||
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
|
||
sidebar.classList.remove('show')
|
||
|
||
overlay.classList.remove('show')
|
||
|
||
}
|
||
|
||
|
||
|
||
</script>
|
||
|
||
|
||
|
||
<div class="off-canvas-content">
|
||
|
||
<div class="columns">
|
||
|
||
<div class="column col-12 col-lg-12">
|
||
|
||
<div class="book-navbar">
|
||
|
||
<!-- For Responsive Layout -->
|
||
|
||
<header class="navbar">
|
||
|
||
<section class="navbar-section">
|
||
|
||
<a onclick="open_sidebar()">
|
||
|
||
<i class="icon icon-menu"></i>
|
||
|
||
</a>
|
||
|
||
</section>
|
||
|
||
</header>
|
||
|
||
</div>
|
||
|
||
<div class="book-content" style="max-width: 960px; margin: 0 auto;
|
||
|
||
overflow-x: auto;
|
||
|
||
overflow-y: hidden;">
|
||
|
||
<div class="book-post">
|
||
|
||
<p id="tip" align="center"></p>
|
||
|
||
<div><h1>34 账号密码泄露成灾,应该怎样预防?</h1>
|
||
|
||
<p>你好,我是宝玉。我们日常总能看到各种与黑客和网络安全相关的新闻,而这其中大部分安全问题都和软件程序有关系。比如说像 CSDN 数据库泄露事件、携程泄露用户银行卡信息事件、有些电商网站用户可以篡改支付购买金额等等。</p>
|
||
|
||
<p>在软件项目开发时,安全是一个很容易被忽略的问题,但又可能会造成严重损失。所以我们在软件开发时有必要对安全问题引起重视,防患未然,构建安全软件。</p>
|
||
|
||
<p>今天,我将带你了解一下软件开发中的安全问题,学习如何构建安全的软件,以及出现了安全问题之后该怎么办。</p>
|
||
|
||
<h2>安全问题本质是技术风险</h2>
|
||
|
||
<p>如果你还记得《15 风险管理:不能盲目乐观,凡事都应该有 B 计划》这篇文章中的内容,我在其中提到,风险是指不确定的事件,一旦发生,将会造成消极的影响。</p>
|
||
|
||
<p>**安全问题,本质上也是一种技术风险,没发生问题的时候一切都好,一旦发生就会有严重的影响。**在对安全问题的应对上,你也可以借鉴对风险管理的方法来改进软件的安全问题,也就是风险识别、风险量化、应对计划和风险监控。</p>
|
||
|
||
<p>在做风险管理时,首先要做的就是识别风险和对风险量化,对于安全问题,你也可以先思考一下:软件项目中安全问题的主要来源是什么?搞清楚安全问题的来源,以及造成的后果,你就可以对软件中导致安全问题的情况有一个基本的识别和量化。</p>
|
||
|
||
<p>软件中的安全问题来源主要可以分为以下三大类。</p>
|
||
|
||
<ul>
|
||
|
||
<li><strong>第一类:恶意输入</strong></li>
|
||
|
||
</ul>
|
||
|
||
<p>很多我们熟知的软件安全问题都属于此类型,就是黑客通过恶意输入,然后绕过软件限制对系统进行攻击和破坏。</p>
|
||
|
||
<p>像 SQL 注入,就是黑客把 SQL 命令输入到软件的输入框或网页的 URL 查询参数,欺骗服务器,执行恶意的 SQL 命令。这样可以绕过密码验证,登录管理员账号,或者删除数据库数据,甚至控制服务器。</p>
|
||
|
||
<p>还有像 XSS 攻击,将恶意代码通过外部参数或者用户输入的方式植入网页中,获取用户的 Cookie 等敏感信息、盗用管理员权限,甚至非法转账。</p>
|
||
|
||
<p>这类问题都是由于恶意输入导致的,应对恶意输入的问题,最简单有效的方式就是对用户输入的数据,做严格的校验,格式化。</p>
|
||
|
||
<ul>
|
||
|
||
<li><strong>第二类:假冒身份</strong></li>
|
||
|
||
</ul>
|
||
|
||
<p>很多程序对于用户身份的校验比较弱,可能会导致黑客假冒用户身份做出超越权限的事情。</p>
|
||
|
||
<p>比如说,我见过有的网站,把后台入口隐藏起来,而没有做权限控制,导致黑客猜到地址后就可以进入后台操作。</p>
|
||
|
||
<p>还有的游戏后台不做验证,直接接收传入的数据,导致可以伪造游戏用户发送数据,破坏游戏平衡。</p>
|
||
|
||
<p>如果对用户的身份不做严格的验证,很可能就会导致假冒身份的安全问题。应对策略就是要对用户的身份做验证,尤其是涉及敏感权限的操作,甚至要做两重验证。</p>
|
||
|
||
<ul>
|
||
|
||
<li><strong>第三类:数据泄露</strong></li>
|
||
|
||
</ul>
|
||
|
||
<p>很多软件都储存了用户的敏感信息,比如用户帐号密码信用卡记录,或者服务器的敏感信息,比如数据库连接字符串、登录帐号密码,而这些数据是有被泄露风险的。</p>
|
||
|
||
<p>一些软件会把服务器上的敏感信息打包在程序中,而程序可能会被反编译导致敏感数据泄露。携程泄露用户银行卡信息事件中,就是因为把用户信用卡信息记录在日志中,日志泄露导致用户信用卡信息也被泄露,造成盗刷等严重问题。</p>
|
||
|
||
<p>还有 CSDN,对用户密码明文存储到数据库中,数据库泄露后,用户密码也跟着一起泄露了,而大多数用户习惯于在不同的网站也用相同的密码,导致在其他网站的密码也一起泄露了。</p>
|
||
|
||
<p>对于软件来说, <strong>我们不能假设数据存储是安全的,而是要考虑到数据是有泄露的可能,提前做好预防措施,对敏感数据进行加密。</strong></p>
|
||
|
||
<p>在了解了这些常见的安全问题来源和可能带来的后果之后,我们在软件开发时,就可以对薄弱环节、重点问题进行提前预防,在开发时就考虑到可能的安全漏洞,做出科学的应对方案。</p>
|
||
|
||
<h2>如何预防软件中的安全问题?</h2>
|
||
|
||
<p>预防软件中的安全问题,也可以参考对风险管理的策略。在风险管理中,对风险识别和量化后,接下来就是要制定应对计划了。</p>
|
||
|
||
<p>很多开发人员觉得安全问题,只要在软件开发完成之后,测试阶段做一个安全测试就可以了,但这样做等于把安全问题留到了最后环节,是很难达到对安全问题进行高质量管控的。</p>
|
||
|
||
<p>一方面,对于安全测试来说,很难覆盖到所有可能存在的场景,可能会出现疏漏,导致安全漏洞被利用。另一方面,如果测试阶段发现安全问题,可能需要修改大量代码,甚至于要重新设计,这时候成本就太高了。</p>
|
||
|
||
<p>所以应对安全问题,最好的方式就是在整个生命周期中都做到重视安全问题,各个阶段都考虑到安全方面的问题,才能真正做到防患于未然,构建出安全的软件。</p>
|
||
|
||
<p>那么在软件开发的各个阶段,都需要如何考虑好安全方面的问题呢?</p>
|
||
|
||
<ul>
|
||
|
||
<li><strong>需求阶段</strong></li>
|
||
|
||
</ul>
|
||
|
||
<p>需求是软件项目的源头,**在确定需求,做产品设计的时候,不仅要考虑到功能上的需求,还要同时考虑到安全方面的要求。**这样当你在架构设计的时候,就不会轻易遗漏安全方面的架构设计。</p>
|
||
|
||
<p>尤其是对于一些外包项目,如果在需求中没有提出安全需求,大概率外包公司是不会帮你考虑这些需求的。</p>
|
||
|
||
<p>需求阶段,涉及用户输入的内容,需要考虑到可能的恶意输入,做出针对性预防措施;对于涉及用户权限的,要求有身份的验证,一些对安全要求极高的,可以在需求上就要求做双重验证;对于有敏感数据的,可以在需求上就要求对数据进行加密。</p>
|
||
|
||
<p>举个简单例子,比如说用户登录功能,如果让你提出安全方面的需求,你会考虑到哪些需求?这里我简单列几个功能参考:</p>
|
||
|
||
<ul>
|
||
|
||
<li>
|
||
|
||
<p>登录网页使用 Https 或者在传输密码时加密;</p>
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
<p>增加图形校验码,避免恶意攻击;</p>
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
<p>密码失败次数过多,应该锁定用户一段时间;</p>
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
<p>记录用户登录 IP。</p>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
<p>当你在需求阶段就提出了安全性的需求,设计、实现和测试时自然不会遗漏掉安全方面的内容,从源头上就让大家有了安全方面的意识。</p>
|
||
|
||
<ul>
|
||
|
||
<li><strong>设计阶段</strong></li>
|
||
|
||
</ul>
|
||
|
||
<p>在做设计架构时,最重要的事就是要把安全加入到设计目标,有了安全方面的设计目标,自然能找到很多安全相关的解决方案。</p>
|
||
|
||
<p>为了保障在设计时就考虑好安全方面的问题,在做架构设计方案的评审时,也需要增加安全方面的评审,确保有安全方面的考虑,确保技术方案切实可行。</p>
|
||
|
||
<p>现在架构设计领域,也有了一些业界公认的好的安全相关的设计原则,比如说攻击面最小化、权限最小化、纵深防御等。</p>
|
||
|
||
<ul>
|
||
|
||
<li><strong>攻击面最小化</strong></li>
|
||
|
||
</ul>
|
||
|
||
<p>攻击面就是指程序被用户直接访问到的部分,比如 API、网站等,这些暴露给用户的地方也是最可能被黑客攻击的地方。</p>
|
||
|
||
<p>暴露的面越多则风险越高,攻击面最小化的设计原则,就是说尽量减少暴露黑客可能发现并试图利用的攻击面数量。</p>
|
||
|
||
<p>举例来说,你的数据库应该关闭外网访问,避免黑客直接攻击数据库导致数据泄露。还有像对于一些复杂的多网站业务系统,实行单点认证,就可以让所有业务都在一个地方登录,你可以在这一个地方做到足够安全,这样所有网站的登录都是相对安全的。</p>
|
||
|
||
<ul>
|
||
|
||
<li><strong>权限最小化</strong></li>
|
||
|
||
</ul>
|
||
|
||
<p>权限最小化的设计原则就是对于系统的用户、文件访问、进程运行等,都只给予其能拥有的最小权限,这样可以保证一个应用程序或者网站被攻击、破解,能将损害降到最低。</p>
|
||
|
||
<p>举例来说,以前在部署 Asp.Net 程序的时候,运行 Asp.Net 的程序是单独的一个用户,这个用户所拥有的权限是只能运行程序所在目录,不能超出其目录范围,这样即使用户上传了恶意木马文件,那么也只能控制这一个目录,避免了进一步的损失。</p>
|
||
|
||
<ul>
|
||
|
||
<li><strong>纵深防御</strong></li>
|
||
|
||
</ul>
|
||
|
||
<p>纵深防御的设计原则,指的是从不同的维度去实施安全保护措施,从而缓解被攻击的风险。纵深防御并不是同一个安全方案要做两遍或多遍,而是要从不同的层面、不同的角度对系统做出整体的解决方案。</p>
|
||
|
||
<p>这里我给你举一个电商网站的例子(摘自:<a href="https://shimo.im/docs/oNJvDIXQw3EgQGyn">代码未写,漏洞已出—架构和设计的安全</a>)。</p>
|
||
|
||
<blockquote>
|
||
|
||
<p>国内中小电商,一半以上在早年都犯过这个错误,现在基本都修复了。电商的交易和支付系统之间流程是这样,一个人过来说老板我要买一台冰箱,多少钱?两千。OK,你把钱付给支付系统。因为支付请求也是在用户侧的浏览器里提交的。这个过程对用户是不可见的,但攻击者实际上可以修改这个数据。攻击者可以修改浏览器提交的数据,本来交易系统让他提交 2000 元,攻击者改为提交 1 元,然后支付系统就返回 OK,说我收到钱了。这个 OK 到交易系统那里,交易系统一看支付成功了,那就安排发货,1 元钱就把冰箱买到了。</p>
|
||
|
||
</blockquote>
|
||
|
||
<p>你看,单独从支付系统和交易系统来看,设计上都没有问题,都对数据输入做了校验,但问题是没有站在一个系统的整体角度去考虑,没有考虑到不仅要校验交易有没有成功,还要校验交易的金额是不是匹配。</p>
|
||
|
||
<p>当然解决方案其实也很简单:</p>
|
||
|
||
<blockquote>
|
||
|
||
<p>不要只反馈是否 OK,同时也把支付的金额和 OK 一起返回过去。是支付 2000 元 OK 还是 1 元 OK。这就解决了问题,现在的电商都改成这个设计了。</p>
|
||
|
||
</blockquote>
|
||
|
||
<p>通过这样一些好的安全设计原则,就可以在设计阶段把很多安全问题预防好。</p>
|
||
|
||
<p><strong>开发阶段</strong></p>
|
||
|
||
<p>只是设计阶段做好安全相关的设计还不好,很多安全问题其实都是编码阶段时,没有好的编码习惯、没有良好的安全意识导致的。</p>
|
||
|
||
<p>对于开发阶段的安全问题预防,需要从以下几个方面入手。</p>
|
||
|
||
<ul>
|
||
|
||
<li>编码规范中加入安全相关内容</li>
|
||
|
||
</ul>
|
||
|
||
<p>对于用户输入的数据,需要有校验,防止恶意输入;对于涉及权限的操作,要检查用户权限;对于敏感数据要进行加密处理;对于用户的操作,要有日志记录;不能在日志中记录敏感信息等等。</p>
|
||
|
||
<ul>
|
||
|
||
<li>要有代码审查</li>
|
||
|
||
</ul>
|
||
|
||
<p>代码审查其实在我们专栏提过很多次,这也是预防安全问题一个行之有效的手段,通过代码审查,及时发现代码中的安全问题。</p>
|
||
|
||
<ul>
|
||
|
||
<li>增加安全相关的自动化测试</li>
|
||
|
||
</ul>
|
||
|
||
<p>现在有些安全工具,可以帮助对代码做安全检查,甚至可以和 CI 集成,如果增加相应的自动化安全测试代码,也可以第一时间对代码中的安全问题进行反馈。</p>
|
||
|
||
<h2>测试阶段</h2>
|
||
|
||
<p>在测试阶段,除了功能测试以外,增加对安全性方面的测试。除了增加相应的测试用例,也可以借助一些安全测试工具(可参考上一篇“软件测试工具”这篇文章)来进行测试。</p>
|
||
|
||
<h2>上线维护</h2>
|
||
|
||
<p>上线部署时,不部署源代码,只对编译后程序部署;删除 Debug 文件。</p>
|
||
|
||
<p>对服务器进行安全设置,比如说严格限制端口,只保留必须的端口;只对少数服务器开发外放服务;开启操作日志;对访问目录设置最小的权限。</p>
|
||
|
||
<p>通过对整个软件生命周期都做好安全方面的考虑,并落实到位,才能真正保证好软件的安全。</p>
|
||
|
||
<h2>如果真的出现安全问题怎么办?</h2>
|
||
|
||
<p>是不是我们在整个软件生命周期都做好安全方面的考虑,也落实到位,就完全不会有安全问题了?</p>
|
||
|
||
<p>安全问题就像程序的 Bug 一样,没有谁能保证绝对的安全,就像风险管理的最后一步风险监控那样,我们必须做好 Plan B,万一出现安全问题,马上应对,将损失降到最低。</p>
|
||
|
||
<p>首先,要设立应急的流程。当出现安全问题了,根据流程,知道该找谁,应该怎么去第一时间恢复生产,避免进一步损失。</p>
|
||
|
||
<p>其次,要分析程序的漏洞在哪里。通过分析日志,找出漏洞在哪里,才能针对性去修补漏洞。</p>
|
||
|
||
<p>最后,要总结原因。从错误中吸取教训,看问题是在哪个环节导致的,必要的话,就改进开发流程,避免类似的安全问题再次发生。</p>
|
||
|
||
<h2>总结</h2>
|
||
|
||
<p>今天我带你一起学习了如何构建安全的软件,软件的安全问题本质也是一种技术风险,可以借用风险管理的知识来帮助构建高安全性的软件。</p>
|
||
|
||
<p>软件安全问题主要来源是:恶意输入、假冒身份和数据泄露,要注意对输入数据的校验、对用户身份的校验和对敏感数据的加密。</p>
|
||
|
||
<p>构建高安全性软件,最好的方式就是在整个生命周期中都做到重视安全问题,各个阶段都考虑到安全方面的问题,才能真正做到防患于未然,构建出安全的软件。</p>
|
||
|
||
<p>安全问题就像程序的 Bug 一样,不能绝对避免,同时也要做好应对措施,在出现安全问题后,将损失降到最低,并且避免以后发生类似问题。</p>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div>
|
||
|
||
<div style="float: left">
|
||
|
||
<a href="/专栏/软件工程之美/33 测试工具:为什么不应该通过QQ微信邮件报Bug?.md.html">上一页</a>
|
||
|
||
</div>
|
||
|
||
<div style="float: right">
|
||
|
||
<a href="/专栏/软件工程之美/35 版本发布:软件上线只是新的开始.md.html">下一页</a>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
|
||
|
||
</div>
|
||
|
||
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70997c87bfb03cfa","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
|
||
|
||
</body>
|
||
|
||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||
|
||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
|
||
|
||
<script>
|
||
|
||
window.dataLayer = window.dataLayer || [];
|
||
|
||
|
||
|
||
function gtag() {
|
||
|
||
dataLayer.push(arguments);
|
||
|
||
}
|
||
|
||
|
||
|
||
gtag('js', new Date());
|
||
|
||
gtag('config', 'G-NPSEEVD756');
|
||
|
||
var path = window.location.pathname
|
||
|
||
var cookie = getCookie("lastPath");
|
||
|
||
console.log(path)
|
||
|
||
if (path.replace("/", "") === "") {
|
||
|
||
if (cookie.replace("/", "") !== "") {
|
||
|
||
console.log(cookie)
|
||
|
||
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
setCookie("lastPath", path)
|
||
|
||
}
|
||
|
||
|
||
|
||
function setCookie(cname, cvalue) {
|
||
|
||
var d = new Date();
|
||
|
||
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
|
||
|
||
var expires = "expires=" + d.toGMTString();
|
||
|
||
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
|
||
|
||
}
|
||
|
||
|
||
|
||
function getCookie(cname) {
|
||
|
||
var name = cname + "=";
|
||
|
||
var ca = document.cookie.split(';');
|
||
|
||
for (var i = 0; i < ca.length; i++) {
|
||
|
||
var c = ca[i].trim();
|
||
|
||
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
|
||
|
||
}
|
||
|
||
return "";
|
||
|
||
}
|
||
|
||
|
||
|
||
</script>
|
||
|
||
|
||
|
||
</html>
|
||
|