所谓的安全,其实是指两个方面
- 私密性:不被非法获取和利用(Get)
- 代码层面
- 架构层面
- 运维层面
- 问题
- 用户身份被盗用
- 用户密码泄露
- 用户资料被盗取
- 网站数据库泄露
- 其他
- 可靠性:不丢失不损坏不被篡改
跨站脚本攻击XSS(Cross Site Scripting)
原理
- 数据代码当成程序代码执行
- 解决:转义时注意场景和范围。script <> ,HTML 单引号 双引号,富文本 白名单
分类
- 反射型(url参数直接注入)
- URL转换(转网址)
- 存储型(存储到DB后读取时注入)
- 把恶意脚本存储到攻击目标的数据库中,等待猎物点击
注入点
- HTML节点内容
<div>#{content}</div>
注入点 <div><script>alert(1)</script></div>
- HTML属性(提前终止属性)
<img src="#{image}" />
注入点<img src="1" onerror="alert(1)"/>
- Javascript代码(字符串提前关闭)
<script type="text/javascript">
var data = "#{data}";
var data = "hello";alert(1);"";
</script>
- 富文本
- 富文本具有HTML
- HTML有XSS攻击的风险
防御XSS(浏览器,只针对反射性)
- chrome浏览器自带防御,反射性XSS(HTML内容和属性),就两种
ctx.set('X-XSS-Protection',1);
- 参数出现在HTML内容或属性
HTML内容的防御
- 用户发表,进入数据库之前转义
- 显示时进行转义
转义< < > >
<script></script>
var escapeHtml=function(str){
str=str.replace(/</g,'<');
str=str.replace(/>/g,'>');
str=str.replace(/"/g,'&quto;');
str=str.replace(/'/g,''');
str=str.replace(/&/g,'&');
return str;
};
HTML属性的防御
- 空格,单引号,双引号
- 一般空格不转义,但是这样我们就需要想到使用单引号或者双引号
<img class="#{class}"/>
<img class="hello" onload="alert(1)"/>
var escapeHtmlProperty=function(str){
if(!str)return '';
str=str.replace(/"/g,'&quto;');
str=str.replace(/'/g,'';');
str=str.replace(//g,' ;');
return str;
}
JavaScript的防御
- / " 转义或者转换成json(stringify)
- 小心注释符//和引号提前截断
<script>
var data="#{data}";
var data="hello";alert(1);"";
</script>
var escapeForJs.=,function(str){
if(!str)return';
str=str.replace(/\\/g,'\\\\');
str=str.replace(/"/g,'\\"');
return str;
};
富文本防御
- js可以藏在标签里,超链接url里,何种属性里
<script>alert(1)</script>
<a href="javascript:alert(1)"></a>
<img src="abc" onerror="alert(1)"/>
- 过滤
- 黑名单(正则过滤,简单,全面困难)
- 去掉
var whitelist={
'img':['src']
};
$('*').each(function(index,elem){
//console.Log("this is elem:",elem);
if(!whiteList[elem.name]){
$(elem).remove();
return;
}
for(var attr in elem.attribs){
if(whiteList[elem.name].indexofattr)===-1){
$(elem).attr(attr,null);
}
}
});
console.log(html,$.html());
return $.html();
CSP(Content Security Policy)
- 内容安全策略
- 用于指定哪些内容可以执行
- child-src
- connect-src
- default-src
- font-src
- frame-src
- img-sre
- manifest-src
- media-src object-src
- script-src
- style-src
- worker-sre
<host-source><scheme-source>'self'
- ‘unsafe-inline’ ‘unsafe-eval’ ‘none’
- ‘nonce-’
- ‘strict-dynamic’
- default-src ‘self’ .只允许本站资源
router.all('/*',async function(ctx, next){
console.log('enter site.js');
ctx.set('X-XSS-Protection',0);
ctx.set(`Content-Security-Policy`,`default-src 'self'`)
await next();
});
商城form提交
- 发送脚本
- 取到登陆态(cookie+后台地址)
PHP防御XSS
- 内置函数转义
- DOM解析白名单
- 第三方库
- CSP
密码安全
- 密码存储
- 严禁明文存储(防泄露)
- 单向变换(防泄露)
- 变换复杂度要求(防猜解)
- 密码复杂度要求(防猜解)
- 加盐(防猜解)
- 密码泄露
- 数据库被偷
- 服务器被入侵
- 通讯被窃听
- 内部人员泄露数据
- 其他网站(撞库)
信息摘要算法(哈希算法)
- 这种函数是一种摘要算法,你给他输入一个任意长的数据A他给你返回固定长度的数据B,也称B为“指纹”。
- 明文 -> 密文
- 雪崩效应(密码混乱)
- 不可逆性
- 密文固定长度
- md5(单向变换) sha1 sha256
- 用复杂密码对抗彩虹表
- md5(sha1(md5(ID+ab83kd+原始密码+81kdso+盐+1lso;$2)))
- 加密成本几乎不变(生成密码时速度慢一些)
- 彩虹表失效(数量太大,无法建立通用性)
- 解密成本增大N倍
- md5(sha1(md5(ID+ab83kd+原始密码+81kdso+盐+1lso;$2)))
密码存储
alter table `user` add column `salt` varchar(64) NULL default '' after `password`;
var password={};
var md5=function(str){
var crypto=require('crypto');
var md5Hash =crypto.createHash('md5');
md5Hash.update(str);
return md5Hash.digest('hex');
};
password.getSalt=function(){
return md5(Math.random()*999999+'+new Date().getTime());
}
password,encryptPassword=function(salt,password){
return md5(salt +‘af@!93520128#@#e'+password);
};
module.exports=password;
const results=await query(
`select * from user where username='${data,username}'`);
if(results.length){
let user=results[0];
// 没有盐,升级
if(!user.salt){
var salt=password.getSalt();
var newPassword = password.encryptPassword(salt,user.password);
await query(`update user set password ='${newPassword}'`
user.salt=salt;
user,password=newPassword;
}
var encryptedPassword = password.encryptPassword(user.salt,data.password):
if(encryptedPassword !==user,password){
throw new Error('密码不正确’);
}
密码传输安全性(明文)
- 前端加密只能阻止用户的明文密码不被拿到。(防止伤害其他网站,随机性,防止反破解)
jspm install npm:js-md5
- https传输
- 频率限制
- 前端加密意义有限
var md5=require('js-md5');
var $form=document.queryselector('[name=loginForm]');
$form.addEventListener('submit',(e)=>{
e.preventDefault();
let data=formSerialize($form,{
hash:true
});
var SUGAR='!QFDSA~U~FSAFDAH个*#G':
data.password=md5(data.username+SUGAR+data.password);
axios.post('/user/login',data).then((data)=>{
if(data,status === 200 && data.data.status ===0){
location.href=/';
console.log(登录成功);
var password={};
var md5=function(sts){
var crypto=require('crypto');
var md5Hash=crypto.createHash('md5);
md5Hash.update(str);
return md5Hash.digest('hex');
);
password.getPasswordFromText=function(username,password){
var SUGAR='!@FDSA~U~FSAFDAH个*#G';
return md5(username +SUGAR+password);
};
password.getSalt=function(){
return md5(Math.random()*999999+''+new Date().getTime());
};
password.encryptPassword=function(salt,password){
return md5(salt +'af@!93$20128#@#e'+password);
};
module.exports=password;
if(!user.salt){
var salt=password.getSalt();
var newPassword=password.getPasswordFromText(user.username,user.password.....
var encryptedPassword=password,encryptPassword(salt,newPassword)
await query(update user set password ='${encrypteord}',salt='${salt
user.salt=salt;
user,password=encryptedPassword;
}
encryptedPassword=password.encryptPassword(user.salt,data.password);
if(encryptedPassword !== user.password){
throw new Error('密码不正确');
}
PHP密码
md5,sha1,hash,crypt函数
生物特征密码问题(指纹(唇纹),虹膜(3sTAR),声纹(微信),人脸……)
- 私密性-容易泄露
- 安全性-碰撞(概率性(相似)判断)
- 无雪崩
- 唯一性-终身唯一-无法修改
- 无雪崩
信息泄露
- 泄露系统敏感信息
- 泄露用户敏感信息
- 泄露用户密码
- 泄露途径
- 错误信息失控
- SQL注入
- 水平权限控制不当
- XSS/CSRF
- 后果
- 你的身份由你掌握的资料确定
- 别人掌握了你的资料
- 别人伪装成你的身份
- 利用你的身份干坏事
- 案例
- 电信诈骗(徐玉玉案)
- 伪装公检法
- QQ视频借钱
- 微信伪装好友
利用OAuth思想防止资料泄露
- 一切行为由用户授权
- 授权行为不泄露敏感信息
- 授权会过期
- 方式
- 去掉数据库查询
- 改用调用Token
- 用户授权读取资料
- 无授权的资料不可读取
- 不允许批量获取数据
- 数据接口可风控审计
拒绝服务DOS
- 模拟正常用户
- 大量占用服务器资源(上线)->系统崩溃
- 类型
- TCP半连接
- HTTP连接
- DNS
分布式拒绝服务攻击DDOS
- 流量可达几十到上百G
- 分布式(肉鸡,代理)
- 难防御
- 防御
- 防火墙
- 交换机、路由器
- 流量清洗
- 高防IP
- 避免重逻辑业务
- 快速失败快速返回
- 防雪崩机制
- 有损服务
- CDN
重放攻击
重放攻击(Replay Attacks)又称重播攻击、回放攻击,是指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。
- 请求被窃听或记录
- 再次发起相同的请求
- 产生意外的结果
- 后果
- 用户被多次消费
- 用户登录态被盗取
- 多次抽奖
- 防御
- 加密(HTTPS)
- 时间戳
- token(session)
- nonce
- 签名防篡改