slavik 2019-07-01
页面上输出query参数 页面上显示搜索框脚本 引入外部js资源 富文本 - 写日志 - 富文本 - 塞入的 - 加入scrpit 在线商城 - 订单信息input消息的填写 - 订单信息流入后台 - 获取后台的管理员信息和后台地址
红框内为输入内容,导致属性标签闭合 添加了新的属性
取值: 0关闭 1默认(开启) 1后面带参数 - 拦截后自动发送到该网址上 限制:只拦截反射类型注入 - 只对HTML属性和节点内容有用
demo(koa)
不被浏览器解析正常显示 < > 内容 “ ‘ 是属性
JSON.stringfy - 所有的单引号/双引号都会被转义
黑名单 - 正则替换 - 因为变形有很多,只能阻挡一部分 白名单 - 在白名单的HTML允许写入 - 实现复杂 - 把html解析成树状结构 - 依次分析过滤每个节点的name,attr,过滤掉不在白名单内的属性和tag 使用npm包 - xss自动实现 https://www.npmjs.com/package/xss
content security policy 内容安全策略,用于指定哪些内容可执行
类型
Child-src 页面子内容 iframe Connect-src ajax Default-src fallback 所有的内容 Font-src Frame-src Img-src Manifest-src webapp Media-src audio/video Object-src 插件 Script-src Style-src Worker-src serviceWorker
配置选项 - 那些可信任那些不可信任
<host-source> 主机域名 <scheme-source> 协议 Self 同域 - 引入的资源 Unsafe-inline 直接插入页面的内容 Unsafe-eval none 不信任任何内容 Nonce-<base64-value> 指定一次性凭证 凭证匹配时可执行 <hash-source> Stric-dynamic 引入的后续网址是否
demo
没有指定的全部不信任,只信任同源的引入文件,对于直接插入的不信任
cross site request forgy 跨站请求伪造 Cross-site: 其他网站对本网站进行的影响,在用户不知情的额情况下向目标网站发送请求 打开连接就可能对其他网站进行操作 post请求 - 第三方站点攻击时 - 需要构建表单
<body> hello,这里什么也没有。 <script> document.write(` <form name="commentForm" target="csrf" method="post" action="http://localhost:1521/post/addComment"> <input name="postId" type="hidden" value="1"> <textarea name="content">来自CSRF!</textarea> </form>` ); var iframe = document.createElement('iframe'); iframe.name = 'csrf'; iframe.style.display = 'none'; document.body.appendChild(iframe); setTimeout(function(){ document.querySelector('[name=commentForm]').submit(); },1000); </script> </body>
Form在提交时会刷新 - 但如果指向一个iframe,则页面刷新会发生在iframe中
get会更容易,而且可以是一张图片等其他信息
demo
qq音乐分享到qq空间,点击链接又可以发送
s1:用户登录A网站
s2:A网站确认身份
s3:B网站页面向A网站发起请求(带A网站身份)
B网站向A网站请求,带A网站Cookies
不访问A网站前端
referer为B网站
- same-site属性[strict/Lax] Strict - 任何请求都不能带上 Lax - ajax/form不允许,链接可以 对于匿名无效 只对chrome/oprea支持
1.图像验证码 - ccap 必须经过A页面,去页面上拿到验证码,且用户必须输入 2.页面生成随机token - 攻击者必须经由前端页面才能拿到我们的页面 校验请求中的token和用户cookie中的token Token都可以拿到,是否有意义? ajax提交 - 吧token信息不让用户输入,而是放在页面的meta标签中来获取 WT:如果我打开了很多个页面,每打开一个页面就新生成一个token,导致只有最后的那个可以被提交,因为cookie中的被覆盖,怎么解决?
referer http请求头, 请求来自于那里 验证请求referer 只允许本网站 - 不能直接indexOf域名,不严谨
cookie一旦设置,同源下的请求头上,都会带上cookie,只要是请求,就算是对css等静态资源的 请求
login接口的响应中可以看到设置cookie
前端操作:
Document.cookie - 获取 Document.cookie = ‘key=value’ 不是覆盖是追加?cookie特性 删除cookie - 设置cookie过期
路劲:对网站不同层级设置不同的cookie 域名: 有效期:session(会话内有效) Http-only: 只允许请求,请求的发送和接受,js不能使用cookie,js中看不到 Secure: 只允许在https使用cookie Same-site:
存储个性化设置 存储未登录时用户唯一标识 存储已登录用户的凭证 存储其他业务数据
存储个性化设置 存储未登录时用户唯一标识 存储已登录用户的凭证 存储其他业务数据
用户ID - 可以使用document.cookie随意更改 - 安全隐患 用户ID+签名 - crypto 篡改该用户名时,你永远不知道他的签名值是是多少
设置签名防止,篡改用户id 用户id,标识用户信息
校验签名:
sessionId - 服务器根据这个区寻找用户信息,再去验证你的身份 实现: 生成sessionId 缺点:服务重启会丢失 session持久化:文件、数据库、缓存(redis)
登录成功设置sessionID
评论验证获取userId
cookie存在浏览器端,当发送请求时,自动寻找该域下没有过期的cookie
特征:
用户操作 用户不知情 点点点的游戏 - 打开摄像头
javascript防御
直接页面和内嵌iframe页面的区别:top window不相等
反击:
Html5 iframe新属性 - shadow:禁止脚本运行,只允许表单提交
X-Frame-Options ie8+
请求头属性 DENY - 禁止内嵌 SAME-ORIGIN - 同一个网站 ALLOW-FROM - 只允许指定网站![clipboard.png](/img/bVbpTkt)
其他手段 - 验证码 - 辅助手段
链路层?
http协议 请求明文发布 无加密
链路层有很多节点 - 传输过程中 - 转发这些流量数据 - 请求数据对这些节点都是公开透明的
Traceroute www.xingshulin.com
HTTP劫持和篡改
e.g.: 运营商劫持 - 校园网登录/提示续费网页 网站被塞广告 局域网劫持 支付宝网页 - 局域网流量走自己的机器,设置了一个网关,劫持了请求 公共wifi - 所有的流量 都经过这个 公共网络
解决:
改用https - TSL(SSL) 加密 将明文转为 密文 传输
但是存在还是存在伪造,劫持
解决:
发布证书 - CA 信任CA列表在 钥匙串访问 - 系统根证书 12306 security
保证这几个节点的安全:
证书无法伪造 证书不会被偷走,私钥不会被泄露 域名管理权不泄露 - CA在给该域名发布证书时,需要对域名的管理权进行验证 CA坚守原则 - CA不验证域名的话,不给发证书
部署
服务器申请证书: Ca 访问指定地址要求你给出指定的返回 访问一个域名 - 给出一个给定的值 模拟:https://www.sslforfree.com/
得到的CA:
把前两个合并
在一个web站点配置一个https的项目
1.服务器下新建项目目录 2.写入nignx配置文件
3.通过工具自动申请证书到服务器
自动脚本获取证书
curl https://get.acme.sh | sh
方法是:写入cert要求的内容
得到
4.把得到的证书放入配置文件
变换次数越多越安全 - 密码加密解密只存在登录时 加密成本几乎不变(生成密码时速度慢一些) 彩虹表失效()
https传输
频率限制 - 避免猜出密码 - 一分钟输入10次 前端加密 - 意义有限 - http传输时,仍可以拿到 - 意义:防止拿到明文密码登陆其他相关网站
Npm install js-md5
密码加密 - 服务端实现
旧用户没有salt,升级 if (!user.salt) { var salt = password.getSalt(); var newPassword = password.encryptPassword(salt, user.password) await query(`update user set password = '${newPassword}', salt = '${salt} where id = ${user.id}'`) user.salt = salt user.password = newPassword } var encryptPassword = password.encryptPassword(user.salt,user.password) if (encryptPassword !== user.password) { throw new Error('密码不正确') }
公司使用的基本都是node服务,不过度叙述了哈哈哈~
上传文件 再次访问上传的文件 上传的文件被当做程序解析