安全开发checklist
美的金融科技
安全开发checklist
安全设计与开发checklist | |
---|---|
检查类型 | 检查项(checklist) |
输入验证
|
校验跨信任边界传递的不可信数据(策略检查数据合法性,含白名单机制等) |
格式化字符串时,依然要检验用户输入的合法性,避免可造成系统信息泄露或者拒绝服务 | |
禁止向java Runtime.exec()方法传递不可信、未净化的数据(当参数中包含空格,双引号,以-或者/符号开头表示一个参数开关时,可能会导致参数注入漏洞), 建议如果可以禁止JVM执行外部命令,未知漏洞的危害会大大降低,可以大大提高JVM的安全性。 |
|
验证路径之前应该先将其标准化为实际路径(特殊的文件名,如“..”,symbolic links 、hard links、shortcuts) | |
从ZipInputStream提取文件,如果不在程序预期计划的目录之内时,应拒绝将其提取出来,或者将其提取到一个安全的位置 | |
从ZipInputStream提取文件,若解压之后的文件大学超过一定限制时,必须拒绝将将其解压 | |
在处理以前,验证所有来自客户端的数据,包括:所有参数、url、http头信息(比如:cookie名字和数据值),确定包括了来自JavaScript、Flash或者他潜入代码 的postf返回信息 |
|
如果任何潜在的危险字符必须作为输入,请确保您执行来了额外的安全控制,比如:输入转义、输出编码、特定的安全API等。部分常见的危险字符,包含但不限于: <> " ' % () & + \ \' \" |
|
如果您使用的标准验证规则无法验证下面的输入,那么它们需要被单独验证,比如验证空字节(%00);验证换行符(%0d,%0a,\r,\n);验证路径替代字符../或..\;如果支持UTF-8扩展字符集编码,验证替代字符:%c0%ae%c0%ae(使用规范化验证双编码或者其他类型的编码) | |
严格验证来自重定向输入的数据(一个攻击者可能向重定向的目标直接提交恶意代码,从而避免开应用程序逻辑以及在重定向前执行的任何验证) | |
验证数据类型 | |
验证数据范围 | |
验证数据长度 | |
输出编码 |
为每一种输出编码方法采用一个标准的、已通过测试的规则 |
通过语义输出编码方式,对所有从服务端返回到客户端的数据进行编码。比如HTML编码、URL编码等,编码形式根据具体的应用场景选择 | |
除非对目标编译器是安全的,否则请对所有字符进行编码 | |
针对sql、xml和ldap查询,语义净化所有可信数据的输出 | |
对操作系统命令,净化所有不可信数据输出 | |
异常处理 | 禁止在异常中泄露敏感信息(敏感数据的范围应该基于应用场景以及产品威胁分析的结果来确定。典型的敏感数据包括口令、个人信息、通讯录、秘钥、数据库信息登) |
禁止在异常中泄露应用服务器的指纹信息(版本、路径、框架) | |
方法发生异常是要恢复到之前的对象状态(业务操作失败时,进行回滚业务;或者避免去修改对象状态,维持对象状态一致) | |
I/O操作 | 临时文件使用完毕及时删除 |
不要讲Buffer对象封装的数据暴露给不可信带代码 | |
在多用户系统中创建文件时指定合适访问许可,以防止未授权的文件访问 | |
当一个外部进程通过其输出流对外输出信息或者错误时,必须及时清空其输出流,以防止输出流中的缓冲区被耗尽而导致外部进程被阻塞 | |
白名单控制共享目录操作文件权限,比如读/写/可执行权限 | |
运行环境 | 不要使用危险得许可与目标组合(比如不要将AllPermission许可赋予给不信任得代码,不要将ReflectPermission许可和suppressAccessChencks目标组合使用,不要将java.lang.RuntimePermission许可与createClassLoader目标组合) |
不要禁用JVM字节码验证,如歌使用得字节码,如class文件被恶意篡改,将会存在安全风险 | |
建议监控平台不要对互联开放,避免照成信息泄露 | |
建议将所有安全敏感代码(例如进行权限控制或者用户名密码校验得代码)都放在一个jar包中 | |
生产代码不能包含任何调试代码或接口 | |
身份验证 | 除了那些特定设为“公开”的内容以外,对所有的网页和资源都要进行身份验证,并正确设计身份验证功能 |
所有的身份验证过程都必须在服务器后端执行 | |
所有的身份验证控制应当安全的处理未成功的身份验证,比如给出模糊的错误提示,隐藏敏感信息 | |
登录入口应具有防止爆力猜解及撞库猜解的措施,超过设定失败次数需要启用锁定或者图片随机码进行访问控制 | |
采用https psot请求方式传输身份验证的凭据信息 | |
身份压着的失败提示信息采用迷糊处理,比如key使用“用户名或密码错误”,而不是使用“用户名错误”或者“密码错误”明确提示 | |
涉及敏感信息或功能的外部系统连接应配置身份验证功能,并进行有效身份验证控制 | |
在执行关键操作(如个人信息密码修改操作)时,应对用户身份进行再次验证 | |
为高度敏感或重要的交易账户使用多因子身份验证机制,如支付密码、短信验证码等 | |
短信验证码 | 一次一用 |
发送频率控制(建议60s获取一次) | |
验证码有效期(建议60s内有效,发送短信时进行友好提示) | |
复杂度(短信验证码建议6位数字) | |
安全提示:是否是自己操作等风险提示信息 | |
在前端校验(客户端的检验只能作为辅助手段,很容易被绕过),必须使用服务端代码对输入数据进行最终校验 | |
图形验证码 | 一次一用,自动刷新 |
验证码有效期(5分钟内有效,可根据场景兼容安全和体验灵活设置) | |
复杂度(4位及以上数字、字母替换并模糊处理),根据需要也可以采用拖拽验证、计算验证、识别验证 | |
服务端进行认证,并每次验证后清理缓存 | |
从用户体验和安全角度出发,可设计为当用户输入3次错误密码后自动弹出验证码 | |
密码管理 | 禁止使用私有或者弱加密算法(不如禁止使用DES,sha1等,推荐使用AES:128位,RSA:2048位,DSA2048位) |
采用基于哈希算法和加盐(salt)方式安全存储口令信息 | |
密码输入框,可设计为显示密码和隐藏密码切换功能 | |
密码重设和更改操作,需要进行二次合法身份验证 | |
密保问题,应当支持尽可能随机得问题提问 | |
密码重设时,应对注册手机号和邮箱进行有效验证,链接只能发送多预先注册得邮箱地址和这预先绑定得手机号 | |
验证码和链接应该设计一个短暂得有效期,防止暴力破解 | |
当密码重新设置时,应短信通知用户是否是本人在操作,告知安全风险 | |
密码复杂度设置:建议8个字符以上,包含字母、数字及特殊字符等 | |
密码设置场景中应具有密码复杂度检查功能 | |
密码不能输出到日志和控制台 | |
数据库链接配置中得用户密码要以加密得形式存储 | |
建议设计密码定期修改提醒机制 | |
会话管理 | 用户登出后应立即清理会话及其相关登录信息 |
注销功能应当完全终止相关的会话或者链接 | |
增加cookie安全性,添加“httponly” | |
回话cookie应设计有限期,超时后立即失效 | |
当设计允许用户在多渠道终端同事登录时,建议应进行常用设备登录限制 | |
为包含已验证的会话标识符的cookie设置域和路径,为站点设置一个恰当的限制值。默认cookie的域是当前域名,默认cookie的路径是当前页面的目录路径。如果想要跨域或者在其他的路径下访问cookie就必须要重新设置这两个属性,domain和path | |
注销功能应当可用于所有受身份验证保护的网页 | |
在平衡风险和业务功能需求的基础上,设置一个尽量短的会话超时时间。 | |
不要再url、错误信息或者日志中暴露会话表示符,会话表示符应当只出现在http套信息中,不要将会话标识符以get参数进行传递 | |
定期生成一个新的会话标识符并周期性地使上一个会话标识符失败(可以缓解那些标识符被获取的特定会话劫持情况) | |
在身份验证的时候,如果连接从HTTP变为HTTPS,则会生成一个新的会话标识符。在应用程序中,推荐持续使用https,不应在http和https之间来回转换,有效避免切换过程会话被劫持篡改。 | |
为服务器端的操作执行标准的安全会话管理,为每个会话执行合法的身份验证和权限控制,防止存在csrf跨站请求伪造漏洞 | |
访问控制 | 将具有特权的逻辑从其他应用程序代码中隔离开 |
限制只有授权的用户才能访问文件资源 | |
限制只有授权的用户才能访问受保护的url | |
限制只有授权的用户才能访问受保护的功能 | |
限制只有授权的用户才能访问直接对象引用 | |
限制只有授权的用户才能访问受保护的服务 | |
限制只有授权的用户才能访问受保护的应用程序数据 | |
限制只有授权的用户才能访问与安全相关的配置信息 | |
限制只有授权的外部应用程序或者接口才能访问受保护的本地程序或者资源 | |
服务器端执行的访问控制规则和前端实施的访问控制规则必须匹配 | |
服务器中创建文件时需指定合理的访问权限(读/写/可执行) | |
当权限重新设置发送改变时,应记录日志,并短信通知用户是否是本人在操作,告知可能存在的安全风险 | |
日志规范 | 不要在日志中保存敏感信息,包括系统指纹信息、会话标识符、账号密码、证件等 |
确保日志记录包含了重要的日志世间数据 | |
记录所有失败的输入验证 | |
记录所有失败的身份验证记录 | |
记录所有成功的身份验证记录 | |
记录所有失败的访问和操作记录 | |
记录所有失败的成功和操作记录 | |
记录明显的修改事件,包括对于状态数据的修改 | |
记录连接无效或者已过期的会话令牌尝试 | |
记录所有的管理功能操作行为,包含但不限于安全配置设置的更改 | |
记录所有失败的后端连接 | |
记录加密模块的错误信息 | |
敏感信息 | 临时产生的敏感数据(写入内存或文件),应具有即时清除和释放机制 |
不要再http get请求参数中包含敏感信息,如用户名、密码、sessionid等 | |
禁止表单中的自动填充功能,因为表单中可能包含敏感信息,包括身份验证信息 | |
不要再客户端上以明文形式保存密码或者其他敏感信息 | |
为所有敏感信息采用SSL加密传输 | |
禁止将敏感信息硬编码在程序中 | |
禁止明文存储用户敏感信息,如密码、银行卡号、身份证号等 | |
不要再日志中保存敏感信息,包含但不限于系统详细信息,会话标识符,密码等 | |
禁止在异常中泄露应用服务器的指纹信息,如版本信息,路径信息,组件版本等 | |
禁止将源码或者sql上传到开源平台或者社区,如github、开源中国等 | |
请求只能含有敏感参数(如订单号,id等),应进行混淆处理,防止产生参数遍历获取信息风险 | |
敏感信息需要展示在web页面时,应在后台进行敏感字段脱敏处理 | |
请求返回数据不应该包含请求之外的业务数据,特别是敏感信息数据 | |
密码找回安全 | 服务端做认证,避免绕过前端控制 |
增加二次认证因子,如验证码 | |
涉及登录验证token之类的,不要直接将验证内容直接返回给用户 | |
认证凭证加密,推荐强算法(AES128位、RSA2048位、DSA2048位) | |
认证凭证中的参数应进行混淆处理 | |
在多个验证操作中,要对各验证机制进行排序,以防出现跳过前面验证机制直接到最后一步认证的安全风险 | |
手机短信验证码验证,需同时校验手机号和短信是否对应 | |
输入框中,应校验输入数据的合法性,防止产生XSS和注入 | |
SQL注入 | 永远不要信任用户的输入,要对用户的所有输入进行校验,包含sql语句的过滤和转义 |
永远不要使用动态拼接sql,可以使用参数化的sql或者使用存储过程进行数据查询存取 | |
永远不要使用管理员权限进行数据库连接,为每个应用使用单独的非特权权限,且配置有限的数据库连接数 | |
不要把敏感信息明文存储,采用加密或者哈希、混淆对敏感信息进行脱敏存储 | |
应用的异常信息用不带有敏感信息,给出尽量可能少的提示;建议使用自定义的错误信息对原始错误进行包装,可把异常信息存放在独立的数据库表中 | |
xml注入 | 不要使用字符串/StringBuilder/StringBuilder/StringFormat组装XML |
建议对XML元素属性或者内容进行转义 | |
XSS跨站脚本攻击 | 对输入的数据进行过滤和转义,包含但不限于<>" ' % () & + \ \' \"等危险特殊字符 |
数据添加到html元素属性或者内容中时,谁数据进行html转义 | |
数据添加到script转义脚本中时,对数据进行script | |
数据添加到style中时,对数据进行css转义 | |
CSRF跨站请求伪造 | 建议在每个关键表单中引入CSRF验证(回话中生成随机串,提交后校验) |
在关键表单提交时要求用户进行二次身份验证(录入密码、插入key、输入图片验证码、短信验证码) | |
对请求refer做验证(比如跨域,系统内部应用) | |
文件上传安全 | 上传操作应设计身份验证机制,并进行合法身份校验 |
只允许上传满足业务需要的相关文档类型 | |
通过检查文件头信息,比如JPEG(jpg)文件头信息(十六进制):FFD8FF,验证上传文档是否是所期待的类型 | |
不要把文件保存在于应用程序相同的web环境中,建议将文件保存在专用的文档服务器中,单独给文档服务器配置域名范文更好 | |
限制上传任意可能被web服务器解析的文件,比如jsp、php、aspx等 | |
上传文件以二进制形式下载,建议不提供直接访问(防止木马文件直接执行) | |
禁止授予上传we你安存储目录可执行权限 | |
组件安全 | 在使用随机数函数时,推荐使用强随机数函数(如java.security.SecureRandom类) |
精简组件中不需要得功能、方法、以免带来未知得安全风险 | |
不可将系统内部使用得锁对象暴露给不可信代码 | |
建议使用SSL Socket代替Socket进行安全数据交换 | |
封装本地方法调用(所有得本地方法都应该被定义为私有得,然后仅通过一个封装方法调用) | |
使用安全管理器(比如java.security或第三方组件)来保护敏感操作 | |
编写自定义类加载器必须覆盖getPermissions()函数时,在为代码源分配任意权限钱,应调用超类super.getPermissions()函数,实现处了自定义策略外,系统全局的默认安全策略也被应用 | |
避免完全依赖URLclassLoader和java.util.jar提供的默认自动签名认证机制,应从加载类的代码源(Code-Source)中获取认证链,然后检查认证是否属于本地秘钥库中的受信任签名者 | |
接口安全 | 调用方来源IP控制,比如可通过防火墙、主机host deny、Nginx deny等技术措施进行实施 |
调用方身份认证,比如key 、secret、证书等技术措施进行实施 | |
调用参数认证,需设计参数容错机制,避免出现参数可遍历敏感数据安全问题 | |
采用数字签名保障接口身份来源可信,数据防篡改 | |
调用方权限控制设置 | |
调用频率、有效期进行控制 | |
调用行为实时检测,对异常阻拦 | |
幂等性校验,保持数据一次性 | |
采用应用接入安全网关,实现APPID/KEY身份认证,加密传输,摘要签名安全保障 | |
Redis调用安全 | 用启用客户端IP访问控制验证功能 |
用启用客户端身份验证功能 | |
敏感信息不要明文存储于redis |