测试web应用程序的验证,会话管理,访问控制

在早期的时候,web应用程序还不能完全叫应用程序,因为那个时候的web页面都是htm页面,主要功能也只是给人家来看的,即使被攻破也只能对其进行修改或者传播一些不实消息。后来,随着网络技术的发展和人民对网络生活需求的日益提高, web程序从刚开始的给人看, 衍生出了许多贴近生活的功能,比如购物,博客,论坛。
web程序从刚开始的给人提供查看阅读变成了大众生活的一部分, 这个时候, 就要对其进行管理, 为什么要管理? 这个其实跟现实生活一个道理, 比如我买东西, 肯定得先进行确认,然后建立联系, 再进行交易, 要是不确认大家都随便买随便卖那就都乱套了,所以这个时候就得对其进行管理。
因为网络世界和现实世界终究还是有差别的, 必须把完整的指令给它它才知道做什么, 并且,一个平台上又不是只有你一个人, 如果程序要对各种用户提出的请求进行确认是否允许或者拒绝, 前提就得先进行确认,这些请求来源于谁。
web程序发展至今, 流行的验证方式就是通过账户密码from表单确认, 然后服务器颁发一个令牌, 以后客户端再提出什么请求都会带上这个令牌再次进行提交, 以此来进行身份确认。 一些保密性要求比较高的, 还会通过active控件进行加强验证。除此之外,提供验证身份确认的方式还有:
1.http基础认证方式
2. 验证服务
3. 本机导入证书验证
4. 物理令牌验证
针对验证的安全机制, 开发者大多使用这种互联的方式处理用户的访问:
身份验证
会话管理
访问控制

针对访问控制安全机制里的验证机制来说, 它在现实中容易出现的缺点为两个方面, 验证机制的设计缺陷和验证机制逻辑判断/执行缺陷
设计缺陷主要有这些:
1. 密码强度不够
2. 登录表单可以被暴力破解方式登录
3. 提供的报错信息过于详细
4. 不安全的验证信息传输方法
5. 密码的修改功能,忘记密码功能, 记住我功能
6. 水平权限提升问题
7. 证书确认不完善
8. 可注册同名用户
9. 用户名和密码可预测
10. 注册后的授权信息颁发方式不安全
验证机制执行缺陷:
1. 验证里逻辑判断不严谨
2. 多阶段登录缺陷
3. 验证信息服务器后端存储不安全

针对这些问题的测试方法
1. 密码强度问题:
可以尝试注册多个账户, 一个账户使用强密码, 另外一个账户使用弱密码, 如果弱密码可以被成功注册并且成功登录, 就说明该应用程序没有实行密码强度标准策略。
2. 暴力破解问题:
观察登录表单, 是否存在验证码, 如果没有出现验证码, 就先使用相同和不同的账户进行登录尝试5~8次查看是否会出现验证码, 如果依然没有出现, 可以继续使用burpsuite对登录表单进行拦截, 查看令牌信息是否完整, 是否是加密的, 如果加密是否可逆, 如果可逆或者没有加密, 就可以对其进行暴力破解尝试。
3. 提供的报错信息过于详细:
登录的地方, 采用多个账户进行登录, 然后观察提示信息,有的程序员会很认证的给你提示出来, 账户不存在, 或者密码错误, 如果存在提示账户不存在, 密码错误这种情况, 提示密码错误很可能就说明该账户是存在的, 如果登录这里它的提示信息采取了模糊策略, 可以尝试注册用户的地方, 密码找回的地方。
4. 不安全的验证信息传输方法:
登录的时候, 对表单进行抓包, 查看是否通过明文传输令牌, 是否通过GET参数方式传输令牌, 是否通过POST明文方式传输令牌, 不要以为用POST就安全了可以用明文, ARP一样可以捕捉。 还有一个是登录表单协议方式的问题, 常规的做法是, 进入账户登录就应该采用https方式, 不应该在提交验证信息的时候才转换https,因为这样存在页面被修改和验证信息被拦截的风险。 其实https这个东西是个鸡肋, 只防好人罢了。。 事实的情况是, 不管你用不用https想对你的当前页面进行操作该操作还是一样操作, 用了, 你的登录信息可以被一部分人拦截, 不用, 谁都可以拦截, 具体的还是得因人而异。

5. 密码的修改功能, 忘记密码功能, 本地浏览器的记住我功能:
密码修改:
修改的时候抓包, 看看能不能找到规律和更新密码的方式, 如果在抓包的内容里发现了userid,pass类似的内容, 可以尝试一下, 把userid改成别人的能否修改成功, 把pass改一个不符合规范的是否可以修改成功。
忘记密码:
使用一个存在的账户和不存在的账户进行测试忘记密码流程, 如果出现了使用存在账户正常进入验证流程,使用不存在账户提示失败的情况, 则可通过该方式枚举存在的ID,如果只是单纯的通过生成验证码的方式直接在忘记密码的步骤里修改密码, 则可以尝试通过buspsuite进行修改密码的验证码的爆破, 这个是属于上节, 我忘写了。
本地浏览器的记住我功能:
查看记住我保存的信息是否包含认证令牌信息和一切有关的敏感字段。

6. 水平权限提升问题:
注册后的账户进入账户管理页面后确定我是否可以访问别人的页面和功能, 修改密码的时候是否可以修改同级人的密码。
7. 证书确认不完善:
注册个账户, 尝试使用密码的前几位登录确认是否可以成功登录。 在账户里输入sql语句查看是否可以造成非预料结果。
8. 可注册同名账户:
看标题就好了。 不说了这个, 其实还有一种方式, 可以查看一下该站的图片或者文件存储方式, 如果采用的是用户名/文件名的方式, 可以查看是否可以注册a.aspx, a,php这样的用户。
9. 用户名和密码可预测:
有的系统是给内部员工用的, 账户密码分配有很多都是生成, 可以尝试使用各种奇淫邪技获取一些样本, 观察一下有无明显规律。 如果观察出来了, 就可以批量生成2个段进行爆破。
10. 验证信息分配方式不安全:
尝试找回下密码, 查看验证方式,认证码是否可以穷举, 是否存在明文向邮箱发送密码? 是否存在验证url可预测问题?

验证机制执行缺陷:
1. 验证里逻辑判断不严谨
尝试空密码登录, or = or登录, 登录账户密码框里输入sql语句。

2. 多阶段登录缺陷
尝试不按顺序执行程序流程, 确认多阶段登录的验证方式, 问题是否可预测, 认证码是否可以爆破, 是否存在第x阶段无验证或者验证失效问题, 是否存在绕过问题。

3. 验证信息服务器后端存储不安全
典型的, 明文存储密码。 可以观察下, 注册或者登录的验证信息是否是明文的, 如果是, 八九不离十后端就是明文存储。

验证问题的解决:
强制使用规范符合强度要求的密码, 账户登录页面使用https, 禁止使用GET,明文方式传输令牌, 完整的确认登录过程, 禁止多次提交和修改,使用服务器端session验证不信任所有来自客户端数据, 报错提示采用模糊方式提醒, 找回密码最好直接给邮箱发个连接然后采用双因子认证方式, 搜集常用登录地址, 方式, 设备, 出现新地址, 方式, 设备登录时,即时邮件提醒。
———————————————————————————————
上一节说了身份验证问题, 这个身份验证如果单纯的靠账户密码形式, 这样肯定不行, 为什么不行, 因为不安全, 可以伪造或者出现各种不能预料的问题, 这个时候, 如果要与服务器进行确认, 谁是谁和哪个请求是谁提出的, 就要通过会话方式来进行,涉及到会话, 多用户, 想安全稳定, 就要进行会话管理, 针对会话, 现在大多使用cookie以此作为client与server之间的传输机制, 出现了对应模式, 就会有可能出现各种安全问题, 针对会话,现在有这么两种类型的安全问题:
1. 生成环节出现的问题
2. 会话处理过程中出现的问题

针对生成环节, 现在有这么几种问题:
1. 会话令牌可以预测:
包含一定的含义
加密程度不够
针对处理环境, 现在有这么几种问题:
1. 在网络上泄露会话信息
2. 在日志中泄露会话信息
3.会话令牌劫持问题
4. 不正确的会话终止方式
5. 会话令牌的传输机制(cookie)范围过宽问题

它们的测试方法:
包含一定含义, 加密程度不够:
准备俩账户, 一个高权限的, 一个普通权限的 ,登录的时候抓包, 查看对比高权限和低权限的cookie是什么样的, 有没有加密或者可寻的规律, 是否替换关键信息后可以造成水平权限乃至垂直权限提升问题, 加密方式是否可以猜解, 生成令牌的强度是否达到标准, 可以通过burpsuite测试。
在网络和日志中泄露会话信息:
抓包查看是否通过直接GET的方式传送会话认证信息, 传输方式是否使用了https, cookie里是否启用了secure,日志是否可以通过url路径的形式直接访问, 是否记录信息过于详细。
会话令牌劫持问题:
确定目标的所有输入和输出点, 进行xss测试, 查看退出账户后再使用原有cookie还能不能登录账户, 分析cookie是否存在替换userid就可以造成水平权限提升问题。
不正确的会话终止方式:
登录账户后进行退出, 然后再使用cookie对账户进行登录确认是否只是通过清空本地会话的形式而没有向服务器进行确认。
范围过宽问题:
登录的时候进行拦截, 查看cookie里是否进行了httponly设置(domain,path)。
会话管理安全问题的解决:
使用强加密算法, 适当在头尾增加一些随机数增加强度, 不要完全依靠cookie进行认证确认, 不使用不安全的传输方式传输会话信息, 比如GET, 过滤好网站的输入和输出部分, 终止会话的时候应该是向服务器确认不是本地清空就完事了, 在cookie里设置domain,path属性限制域名和路径。
其实现实中有些环境没办法做到这么死, 真做这么死肯定会影响用户体验还没办法真正保障安全, 还是那句话, 只有相对安全没有绝对安全。

——————————————————————————————–

访问控制部分:

为什么把访问控制放到这个机制的最下面是因为如果没有身份验证和会话管理就没办法做到访问控制, 从安全上讲, 任何没有做到访问控制的点造成的问题都可以被称为未授权访问, 要是仔细点说的话, 访问控制可以造成的问题主要分为这三种:

1. 垂直权限提升问题
我可以修改/使用管理员才能用到的数据/功能。
2. 水平权限提升问题

我可以修改/使用同级的其他人才可以使用的数据/功能, 任何可以造成水平权限提升的地方都有可能会继续产生垂直权限提升的问题。

3. 上下文访问控制不当问题

这个主要体现在多步登录/操作上, 比如我可以不按程序制定的流程访问有关数据,功能。

如何测试他们?

垂直权限提升, 水平权限提升问题:

准备三个账户, 两个同级的, 一个管理员的, 登录的时候抓包, 尝试把A账户里的关键信息改成B账户能否访问B账户内容, A账户登录后显示的URLB账户能否直接访问? 管理员登录的时候出现的连接A,B账户是否可以访问? 有没有存在可以直接通过http://url/x.doc这种文件下载的地方? 是否可以直接通过连接和过滤不全的地方把A,B账户提升为管理员权限? 不登录状态下访问普通用户页面和管理员页面能否直接访问? 查看是否只是单纯的通过JS验证, 如果是单纯的JS验证查看是否可以通过禁用JS方式绕过登录? 是否存在直接在登录后泄露密码问题, 是否存在直接通过id=方式标识用户问题? 对本地客户端所做的修改服务器端有没有进行二次验证? 是否存在服务器端配置不当问题 ,绕过登录限制? 比如单纯的通过ip,referer验证, 或者是一个页面只禁用了某种访问方式, 把GET换成POST就可以访问或者禁用客户端组件就可以直接访问。

上下文访问控制不当问题:

测试能否不使用程序限制的顺序访问有关功能, 能否绕过二次登录, 二次登录的是否是否存在输入验证不严格问题, 是否可以在第一/二/三步的时候访问别人的账户/信息/数据。

如何防御基于访问控制的攻击?

现在最好的办法是做一个统一认证, 然后其他地方再分步授权, 再细化一点, 分别给数据库账户, 系统账户降权, 只允许它可以使用达到目的的最低权限, 不使用显式方式传递可以识别用户的标识, 不可以信任来自客户端的一切数据, 任何来自客户端的输入都要服务器进行二次确认, 如果客户端没有按照顺序访问, 应该取消上一次的输入或者操作, 或者直接退回第一步, 具体的还是得看环境。 现实中有很多基于访问控制的模型供我们使用, 但是不能完全考虑使用某一种, 或者是因为业务的混杂程度, 或者是出于用户体验的考虑, 必须要结合实际的平台来制定。
几个访问控制的安全模型:

编程控制:

权限写死, 直接在数据库和程序内严格划分权限。

自主控制:

制定一个垂直的用户组, 在需要的时候管理员可以为剩下的用户分配权限。
角色控制:

你就是你, 他就是他, 权限完全严格划分。
声明式控制:

在程序外进行声明, 所有的功能都在不影响正常使用的情况下使用最低权限。

此条目发表在安全控制分类目录,贴了, , , , , 标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注