一、SQL注入
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
在构建Web应用程序时,我们经常需要处理用户输入,特别是在实现如登录、注册等需要用户认证的功能时。然而,这些用户输入如果不经过严格的处理和验证,就可能导致严重的安全问题,其中最典型的便是SQL注入攻击。
以登录功能为例,当用户在登录界面输入用户名和密码并提交时,应用程序通常会通过调用类似/user/login/的接口,并携带用户名和密码参数来进行验证。在后台,这些参数通常会被直接拼接到SQL查询语句中,以从数据库中检索用户信息。
示例SQL注入攻击
假设正常的查询语句是:
SELECT * FROM users WHERE username = 'ls' AND password = '123456';
然而,如果攻击者在用户名输入框中输入' or 1=1 -- '(注意这里的--是SQL中的单行注释符号),那么拼接后的SQL语句将变成:
SELECT * FROM users WHERE username='' or 1=1 -- ' AND password='123456';
由于--之后的内容被注释掉了,所以上述SQL语句实际上等同于:
SELECT * FROM users WHERE username='' or 1=1;
这个条件总是为真,因此会返回数据库中的所有用户记录,导致未授权访问。更糟糕的是,如果攻击者构造了更复杂的输入,如' or 1=1; DROP TABLE users; -- ',那么不仅会泄露所有用户信息,还会删除整个用户表,造成数据丢失。
防范SQL注入攻击
为了防范SQL注入攻击,开发者需要采取一系列的安全措施:
- 使用参数化查询:避免将用户输入直接拼接到SQL语句中,而是使用参数化查询(prepared statements)或ORM(对象关系映射)框架来构建安全的查询语句。
- 验证和清理用户输入:对用户输入进行严格的验证和清理,确保只接受预期的输入类型和格式。对于敏感数据(如密码),应使用哈希算法进行加密存储。
- 最小权限原则:数据库连接应使用具有最小必要权限的数据库用户,避免使用具有过高权限的root或admin用户。
- 错误处理:不要将详细的数据库错误信息暴露给用户,而是返回通用的错误消息。这可以防止攻击者利用错误信息来猜测数据库结构或尝试不同的攻击方法。
- Web应用防火墙(WAF):使用Web应用防火墙来监控和拦截潜在的SQL注入攻击。WAF可以识别和阻止恶意的输入模式,并保护应用程序免受攻击。
- 持续的安全监控和审计:定期检查和审计应用程序的安全性,确保没有新的安全漏洞被引入。使用安全扫描工具来检测潜在的SQL注入漏洞,并修复发现的问题。
二、失效的身份认证
在现代应用程序中,认证和会话管理是其安全体系的核心组成部分。然而,如果这些部分没有得到妥善实现,攻击者便有可能利用这些漏洞来泄露密码、口令或令牌,从而可能进一步获取其他用户的身份。以下是对这些潜在漏洞的成因及其相应防范措施的深入分析。
漏洞成因
- 自动化攻击的风险:应用程序若未设置有效的防护措施,便可能允许凭据填充(credential stuffing)等自动化攻击,通过利用已泄露的凭据信息来尝试登录其他服务。
- 暴力破解与自动攻击:若系统未设置合理的登录尝试限制,攻击者便可能通过暴力破解或其他自动攻击手段来猜测用户的密码。
- 默认、弱或广为人知的密码:使用“admin/admin”等默认、弱或广为人知的密码,为攻击者提供了轻易入侵的机会。
- 凭据恢复和忘记密码策略不足:弱或无效的凭据恢复和忘记密码策略可能导致攻击者能够轻易地重置用户密码。
- 密码存储不当:使用明文、加密或弱哈希存储密码,一旦数据库被泄露,用户的密码便可能直接暴露。
- 多因子认证机制缺陷:损坏的或无效的多因子认证可能无法有效阻止攻击者。
- 会话ID管理不当:在URL中暴露会话ID、成功登录后未轮换会话ID或未及时销毁会话ID,都为攻击者提供了可乘之机。
防范措施
- 实施多因子认证:通过引入多因子认证机制,有效阻止自动化攻击和凭据重用,增加攻击者的入侵难度。
- 避免使用默认密码:强制用户设置复杂且独特的密码,并鼓励定期更换密码。
- 弱密码检查:在注册和更改密码时,实施弱密码检查,拒绝接受那些易于猜测或已广泛使用的密码。
- 规范密码策略:明确密码的长度、复杂度等要求,确保用户密码具有足够的强度。
- 加固注册、凭据恢复和API:采用安全措施,如验证码、账户锁定等,来抵御账户枚举攻击。
- 限制登录尝试:限制或延迟失败的登录尝试,并记录所有失败尝试,以便在发现异常时及时报警。
- 使用安全的会话管理:利用服务端、安全、内置的会话管理机制,确保每次登录都生成新的随机会话ID,并避免在URL中暴露。同时,确保会话ID在不再需要时及时销毁。
三、敏感数据泄露
攻击者不是直接攻击密码,而是在传输过程中或从客户端(例如:浏览器)窃取密钥、发起中间人攻击,或从服务器端窃取明文数据。这通常需要手动攻击。通过使用图形处理单元(GPU),早前检索的密码数据库可能被暴力破解。
防范措施:
对系统处理、存储或传输的数据分类,并根据分类进行访问控制。
对于没必要存放的、重要的敏感数据,应当尽快清除,或者通过PCI DSS标记或拦截。未存储的数据不能被窃取。
确保存储的所有敏感数据被加密。
确保使用了最新的、强大的标准算法或密码、参数、协议和密匙,并且密钥管理到位。
确保传输过程中的数据被加密,如:使用安全传输层协议(TLS)。确保数据加密被强制执行,如:使用HTTP严格安全传输协议(HSTS )。
禁止缓存对包含敏感数据的响应。
确保使用密码专用算法存储密码,如:Argon2 、 scrypt 、bcrypt 或者PBKDF2 。将工作因素(延迟因素)设置在可接受范围。
四、越权访问
越权访问(Broken Access Control,简称BAC)是Web应用程序中一种常见的漏洞,由于其存在范围广、危害大,被OWASP列为Web应用十大安全隐患的第二名。
该漏洞是指应用在检查授权时存在纰漏,使得攻击者在获得低权限用户账户后,利用一些方式绕过权限检查,访问或者操作其他用户或者更高权限。越权漏洞的成因主要是因为开发人员在对数据进行增、删、改、查询时对客户端请求的数据过分相信而遗漏了权限的判定。越权访问漏洞主要分为水平越权访问和垂直越权访问。
水平越权访问漏洞
水平越权访问是一种“基于数据的访问控制”设计缺陷引起的漏洞。由于服务器端在接收到请求数据进行操作时没有判断数据的所属人/所属部门而导致的越权数据访问漏洞。
假设用户A和用户B属于同一角色,拥有相同的权限等级,他们能获取自己的私有数据(数据A和数据B),但如果系统只验证了能访问数据的角色,而没有对数据做细分或者校验,导致用户A能访问到用户B的数据(数据B),那么用户A访问数据B的这种行为就叫做水平越权访问。
垂直越权访问漏洞
垂直越权是一种“基于URL的访问控制”设计缺陷引起的漏洞,又叫做权限提升攻击。
由于后台应用没有做权限控制,或仅仅在菜单、按钮上做了权限控制,导致恶意用户只要猜测其他管理页面的URL或者敏感的参数信息,就可以访问或控制其他角色拥有的数据或页面,达到权限提升的目的。
防范措施:
前后端同时对用户输入信息进行校验,双重验证机制
调用功能前验证用户是否有权限调用相关功能
执行关键操作前必须验证用户身份,验证用户是否具备操作数据的权限
直接对象引用的加密资源ID,防止攻击者枚举ID,敏感数据特殊化处理
永远不要相信来自用户的输入,对于可控参数进行严格的检查与过滤
五、安全性错误配置
攻击者能够通过未修复的漏洞、访问默认账户、不再使用的页面、未受保护的文件和目录等来取得对系统的未授权的访问或了解。
使用默认账户和密码、在应用栈中任意一处没有安全加固,云服务器授权没有正确配置、应用服务器,应用框架,库,数据库中的安全设置没有被设为安全值、服务器没有发送安全头或指令等都有可能造成安全性错误配置漏洞。
防范措施:
一个可以快速且易于部署在另一个锁定环境的可重复的加固过程。开发、质量保证和生产环境都应该进行相同配置,并且,在每个环境中使用不同的密码。这个过程应该是自动化的,以尽量减少安装一个新安全环境的耗费。
搭建最小化平台,不包含任何非必须地特性,组件,文档。
包管理工具中检查并更新安全配置。
一个能在组件和用户间提供有效的分离和安全性的分段应用程序架构,包括:分段、容器化和云安组。
向客户端发送安全指令,如:安全标头。
在所有环境中能够进行正确安全配置和设置的自动化过程。
六、XSS跨站脚本攻击
XSS漏洞出现在当web页面包含不可信的数据,却没有合适的验证手段来找到它的时候。XSS使得攻击者能够在受害者的浏览器中执行脚本,从而劫持会话,或重定向到恶意站点。
漏洞成因:
存在三种XSS类型,通常针对用户的浏览器:
反射式XSS:应用程序或API包括未经验证和未经转义的用户输入,作为HTML输出的一部分。让攻击者在受害者的浏览器中执行任意的HTML和JavaScript。例如恶意漏洞网站,广告或类似内容。
存储式XSS:你的应用或者API将未净化的用户输入存储下来了,并在后期在其他用户或者管理员的页展示出来。存储型XSS一般被认为是高危或严重的风险。
基于DOM的XSS:会动态的将攻击者可控的内容加入页面的JavaScript框架、单页面程序或API存在这种类型的漏洞。
防范措施:
防止XSS需要将不可信数据与动态的浏览器内容区分开。这可以通过如下步骤实现:
使用自动转义XSS的框架,比如React JS。学习每种框架的XSS保护,并手动处理用例没有覆盖到的部分。
转义不可信的HTTP请求数据能够解决反射型和存储型XSS威胁。
在客户端修改浏览器文档时应用内容敏感的编码以抵御DOM XSS。或使用相似的内容敏感转义技术。
启用CSP(Content Security Policy),这是一种对抗XSS的纵深防御弥补控制。
七、不安全的反序列化
反序列化过程,尽管在某些情况下是数据交换的便捷手段,但也隐藏着巨大的安全风险。其中最严重的后果莫过于远程代码执行(RCE),但更为常见的是攻击者通过篡改序列化数据中的特定字段来实现权限提升或越权操作。
在一个常见的场景中,用户登录成功后,服务器会将用户的身份信息以自定义的格式存储在浏览器的cookie中。这些cookie数据往往包含用户的身份标识、权限级别等敏感信息。然而,由于缺乏对数据完整性的有效校验,攻击者有可能通过篡改cookie中的某些字段来伪装成具有更高权限的用户。
例如,原本一个普通用户的cookie数据可能如下:
Cookie: 3844998|AliceM|y|27|*NU*|active|null|201809
但攻击者通过修改其中的权限字段(从NU改为ADMIN),就能够将用户伪装成管理员:
Cookie: 3844998|AliceM|y|27|*ADMIN*|active|null|201809
当服务器接收到这个被篡改的cookie时,如果没有进行有效的验证和过滤,就可能错误地将该用户当作管理员来处理,从而给系统安全带来极大的隐患。
为了防范这类反序列化攻击,我们可以采取以下措施:
- 避免接受不可信来源的序列化对象:这是最安全的策略,但如果业务需求不得不接受,则应谨慎处理。
- 实施数据完整性检测:使用数字签名等技术手段来确保序列化数据的完整性和真实性,防止数据被篡改。
- 严格限制反序列化类型:在反序列化过程中,应明确指定所期望的数据类型和结构,防止恶意对象的注入。
- 隔离反序列化环境:在低权限的环境中独立运行反序列化代码,以减少潜在的安全风险。
- 记录与监控:记录反序列化过程中出现的所有异常和错误,以便及时发现潜在的安全问题。同时,对反序列化操作进行监管,并在发现异常行为时及时报警。
- 限制网络访问:对于来自反序列化过程的网络请求,应限制其访问范围,防止潜在的跨站请求伪造(CSRF)等攻击。
八、使用具有已知漏洞的组件
库,框架等软件组件和应用有着相同的权限。如果存在有漏洞的组件,那么攻击就能够导致数据泄露甚至控制服务器。组件中的漏洞会导致整个应用和API安全性的下降。
漏洞成因:
管理员不知道使用的所有组件的版本,包括直接使用的和其依赖的组件。
软件易受攻击,不再支持,或是过时的。包括OS, web服务器,DBMS,APIs和所有组件,运行时环境,库。
没有周期性扫描漏洞,没有关注所使用组件的安全公告。
没有及时修复或升级平台,框架,依赖。
软件开发者没有测试升级,更新,补丁的兼容性。
防范措施:
移除不使用的依赖、不需要的功能、组件、文件和文档。
利用如 versions、DependencyCheck 、retire.js等工具来持续的记录客户端和服务器端以及它们的依赖库的版本信息。持续监控如CVE 和NVD等是否发布已使用组件的漏洞信息,可以使用软件分析工具来自动完成此功能。订阅关于使用组件安全漏洞的警告邮件。
仅从官方渠道安全的获取组件,并使用签名机制来降低组件被篡改或加入恶意漏洞的风险。
监控那些不再维护或者不发布安全补丁的库和组件。如果不能打补丁,可以考虑部署虚拟补丁来监控、检测或保护。
九、不足的日志记录和监控
日志和监控不足,再加上缺失或无效的事件响应,允许攻击者进一步攻击系统,他可以转向更多系统,进行篡改,提取,销毁数据。大部分研究表明违反往往会在超过200天后才被检测出来,而且还是由外部参与者检测到的。
漏洞成因:
未记录可审计性事件,如:登录、登录失败和高额交易。
告警和错误事件未能产生或产生不足的和不清晰的日志信息。
没有利用应用系统和API的日志信息来监控可疑活动。
日志信息仅在本地存储。
没有定义合理的告警阈值和制定响应处理流程。
渗透测试和使用DAST工具(如:OWASP ZAP)扫描没有触发告警。
对于实时或准实时的攻击,应用程序无法检测、处理和告警。
防范措施:
确保登录,访问控制失败,服务断输入验证失败等事件会被日志记录,同时记录足够多的用户上下文以确定可疑账号。保存足够长的时间以用于分析。
确保日志以一定格式生成,便于日志管理。
确保高额转账带有审计跟踪和完整性控制以避免篡改或删除。
建立有效的监管和报警机制,使得可疑活动被及时检测和响应。
建立事件响应和恢复计划。
十、CSRF跨站请求伪造
简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。
攻击流程:
1、用户在一个正常的页面下浏览并且登录了该网站
2、在这个网站没有关闭的情况下,用户又打开了一个恶意的网页(上面植入了一些恶意的代码),它会伪造一个正常的报文去向正常服务器发送请求,由于用户的cookie处于登录态,所以只要伪造的请求跟正常的一样,浏览器在发送请求的时候就会自动携带上cookie,从而也就能够实现删除帖子、发布帖子等一系列操作。
防范措施:
在表单中添加一个随机的数字或字母验证码,通过强制用户和应用进行交互,来有效地遏制CSRF攻击。
如果检查发现是非正常页面提交的请求(根据Referer进行判断),则极有可能是CSRF攻击。
在请求的参数里增加一个随机的token参数,且不可被猜测。
敏感的操作应该使用POST,而不是GET,以form表单的形式提交,可以避免token泄露。
十一、点击劫持
点击劫持(Clickjacking),又称界面伪装攻击(UI Redress Attack),是一种视觉欺诈技术。在这种攻击中,攻击者通过精心设计的透明iframe覆盖在正常的网页上,从而诱导用户在毫无察觉的情况下执行预定义的恶意操作。用户被诱导点击的实际上并非他们意图点击的按钮或链接,而是被重定向至攻击者精心设计的恶意内容。这种攻击手段不仅限于构建独立的恶意网站,还可能用于执行钓鱼攻击等。
黑客通常会创建一个包含目标网站的网页,并通过iframe元素将目标网站嵌入其中。随后,他们利用CSS样式或其他技术手段隐藏目标网站的内容,使用户在浏览时无法察觉到其存在。接着,黑客会构建一个诱骗界面,其中可能包含看似无害的按钮或链接(如“PLAY!”按钮),但实际上这些元素与恶意操作相关联。
当用户被诱导点击这些按钮时,他们实际上是在触发执行恶意网页的命令,而非自己预期的操作。这种攻击方式具有高度的隐蔽性和欺骗性,使得用户在不知不觉中成为攻击者的帮凶。
为了防范点击劫持攻击,目前最可靠的方法是使用X-FRAME-OPTIONS HTTP头。这个头由微软提出,专门用于防御利用iframe嵌套的点击劫持攻击。它在IE8、Firefox 3.6、Chrome 4等主流浏览器版本中均得到了良好的支持。
X-FRAME-OPTIONS头有三个可选值:
DENY:禁止任何域的页面通过iframe嵌套当前页面。
SAMEORIGIN:只允许与当前页面同源的页面通过iframe嵌套。
ALLOW-FROM uri:允许指定uri的页面通过iframe嵌套当前页面(其中uri为允许加载的页面地址)。
通过合理配置X-FRAME-OPTIONS头,可以有效防止点击劫持攻击,保护用户免受欺诈和恶意操作的侵害。
十二、任意文件上传和读取下载
1. 任意文件上传
任意文件上传(Unrestricted File Upload),是一种常见的web安全漏洞,由于web应用程序在实现文件上传功能是对上传的文件缺少必要的检查,使得攻击者可上传任意文件。利用该漏洞,攻击者可以直接上传webshell(webShell 就是以asp\php\jsp或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称之为一种网页后门)、病毒、恶意脚本等各种危险文件,可能导致服务器权限被直接获取,从而危及整个系统的安全运行。
防范措施:
校验文件格式,对上传的文件后缀进行判断,如果是上传头像处,仅允许jpg、png、gif等图片文件格式上传,而且对图片进行二次渲染,防止黑客利用解析漏洞来getshell。
校验文件大小,限制过大文件上传。
重命名上传文件。
2. 任意文件读取下载
由于业务需求,往往需要提供文件查看或文件下载功能,但若对用户查看或下载的文件不做限制,则恶意用户就能够查看或下载任意敏感文件,这就是文件查看与下载漏洞。
一般链接形式:
download.php?path=
down.php?file=
data.php?file=
防范措施:
过滤".",使用户在url中不能回溯上级目录
正则严格判断用户输入参数的格式
php.ini配置open_basedir限定文件访问范围
设置白名单,即只能下载/访问某个目录下的文件,权限给到最低