“在代码的世界里,每一行都是进步的足迹,每一次挑战都是成长的机遇。”

软件编码安全问题

在软件开发领域,程序员的素养不仅仅体现在写出高效、功能完善可扩展的代码,更要确保代码的安全性。安全编码是构建可靠软件系统的基石,它涉及到从设计到实现的每一个环节,很大部分软件程序员对编码安全意识淡薄,错误编码极容易导致系统性能下降,数据泄露,被植入恶意代码造成不必要的损失。对于硬件,通信,中间件的我们只要经常关注,多和运维工程师沟通常升级加固即可,软件程序员在平常编码中多点安全意识能大大保障系统的稳定性,以下是一份全面的安全编码指南,旨在提升程序员在安全方面的素养。

对于大部分程序员来说,肯定听说说sql注入,xss攻击漏洞这些。目前很多orm框架,mvc框架很多都对恶意代码进行了过滤,但是在实际应用中,往往存在复杂的业务逻辑,开发人员可能需要编写自定义的代码来实现特定功能。这些自定义代码可能没有受到框架安全机制的保护,从而成为安全漏洞的来源。例如,在一个电商系统中,开发人员为了实现特殊的商品搜索功能,编写了自定义的 SQL 查询构建代码,如果没有进行充分的安全检查,就可能存在 SQL 注入风险。

以下是一些常见的常见的因为编码不规范导致的低级漏洞。这里代码就不贴了,有兴趣随便百度一下就能找到demo。

水平越权

  • 原理:指攻击者能够访问与他同级别(具有相同角色)的其他用户的数据或执行其他用户的操作。这是因为应用程序在处理用户请求时,没有对用户身份进行足够精细的区分。
  • 示例:A用户可以查看B用户的信息,比如通过ID或者用户名去查询。
  • 解决办法:增加验证从session和redis中拿到用户比对。

垂直越权

  • 原理:低级别用户能够访问高级别用户才能访问的资源或执行高级别用户才能执行的操作。这是因为应用程序没有对不同级别的用户权限进行严格的检查和控制。
  • 示例:普通角色可以访问高级角色的数据。
  • 解决办法:强制验证,非法访问返回403或者提示。

反序列化漏洞

  • 原理:当应用程序对用户输入的序列化数据进行反序列化处理时,如果没有对数据进行严格验证,攻击者可以构造恶意的序列化数据,在反序列化过程中执行恶意代码。这种漏洞可能导致远程代码执行、信息泄露等严重后果。
  • 示例:在 Java 中,如果使用了不安全的反序列化库,攻击者可以通过网络发送恶意的序列化对象,利用类路径中的可利用类(如具有特定构造函数或方法的类)来执行恶意操作。
  • 解决办法:选择合适的反序列化框架,验证输入,使用序列化类白/黑名单控制,例如Apache Commons IO的ValidatingObjectInputStream,ObjectInputStream.readUnshared

Groovy

  • 简介:Groovy 是一种基于 Java 虚拟机(JVM)的敏捷开发语言,它可以与 Java 代码无缝集成。在安全方面,如果在使用 Groovy 的应用程序中没有对用户输入进行严格控制,可能会导致安全问题。例如,攻击者可能在允许执行 Groovy 脚本的环境中注入恶意代码。
  • 安全风险示例:如果一个应用程序使用 Groovy 来实现动态脚本功能,且没有对用户输入的脚本内容进行过滤,攻击者可以编写恶意的 Groovy 脚本,访问系统资源、读取敏感文件或执行其他恶意操作。
  • 解决办法:验证脚本输入,增加白名单。

JavaScript 脚本引擎

  • 原理:当应用程序使用 JavaScript 引擎来执行动态脚本内容时,如果对输入的脚本来源和内容没有充分的安全检查,可能会导致安全漏洞。例如,在浏览器环境中,XSS 攻击就是利用了 JavaScript 脚本引擎执行恶意脚本的情况。
  • 安全风险示例:在一个 Web 应用程序中,如果用户输入的内容直接被传递到 JavaScript 函数中执行,攻击者可以插入恶意的 JavaScript 代码,如窃取用户的登录凭证、修改页面内容等。
  • 解决办法:验证脚本输入,增加白名单。

SQL 注入

  • 原理:攻击者通过在用户输入字段中插入恶意的 SQL 语句,欺骗应用程序将其作为合法的 SQL 代码执行。这可能导致数据库信息泄露、数据篡改、数据库服务器被控制等问题。
  • 示例:在一个登录页面中,如果应用程序直接将用户输入的用户名和密码拼接成 SQL 查询语句(如SELECT * FROM users WHERE username = 'user_input' AND password = 'pass_input'),攻击者可以输入' OR '1'='1作为用户名,使查询条件恒成立,从而绕过登录验证。
  • 解决办法:使用成熟的ORM框架,Mybatis等,参数验证,${}的入参尽量交给代码控制并限制,而不是交给用户表单去输入。

XSS 攻击(跨站脚本攻击)

  • 原理:攻击者将恶意脚本(通常是 JavaScript)注入到目标网站中,当用户访问该网站时,浏览器会执行这些恶意脚本,从而导致用户信息泄露、账户被盗用等问题。
  • 示例:在一个论坛系统中,如果用户发表的评论内容没有经过 HTML 编码就直接显示在页面上,攻击者可以在评论中插入<script>alert('XSS');</script>这样的脚本,当其他用户查看该评论时,浏览器会弹出警告框,表明存在 XSS 攻击的可能性。更恶意的脚本可以窃取用户的登录信息等。
  • 解决办法:扩展拦截器或者过滤器,对html转义,HtmlUtils.htmlEscape(),Jsoup增加html的白名单Jsoup.clean(content, whitelist);

Xml 外部实体注入(XXE)

  • 原理:当应用程序解析 XML 输入时,如果没有正确配置对外部实体的处理,攻击者可以利用 XML 的外部实体功能来读取本地文件、执行内部端口扫描等恶意操作。
  • 示例:如果一个应用程序接受用户上传的 XML 文件并进行解析,攻击者可以构造包含恶意外部实体声明的 XML 文件,如<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><root>&xxe;</root>,尝试读取服务器上的/etc/passwd文件。
  • 解决办法:增加白名单。

跨域资源伪造漏洞(CSRF)

  • 原理:攻击者诱导用户在已登录的目标网站上执行非预期的跨域请求,利用用户的身份进行恶意操作,而用户通常不知情。这是因为目标网站在处理跨域请求时没有足够的验证机制。
  • 示例:攻击者在一个恶意网站上放置一个隐藏的<form>标签,其action指向目标银行网站的转账接口,当用户访问恶意网站时,浏览器会自动提交该表单,利用用户在银行网站的登录状态执行转账操作。
  • 解决办法:增加白名单@CrossOrigin(origins = {“localhost”, “http://localhost, “https://localhost”})

跨站请求伪造(同 CSRF)

  • 原理和示例与跨域资源伪造漏洞相同,只是不同的叫法。

重定向漏洞

  • 原理:当应用程序在处理重定向时,如果没有对重定向的目标 URL 进行严格验证,攻击者可以构造恶意的重定向,将用户引导到钓鱼网站或其他恶意网站。(代码审计redirectforward,ModelAndView(“redirect://” + url);相关数据)
  • 示例:在一个登录后的应用程序中,如果存在重定向漏洞,攻击者可以修改重定向参数,使原本应该重定向到合法页面的用户被重定向到一个外观相似的钓鱼网站,从而骗取用户的登录信息。
  • 解决办法:重定向增加域名或ip白名单,重定向的地址和参数要验证,审计redirectforward等代码和参数。

SpEL Injection (Spring 表达式注入)

  • 原理:在使用 Spring 框架的应用程序中,如果对用户输入在 Spring 表达式语言(SpEL)中的使用没有进行充分的安全检查,攻击者可以注入恶意的 SpEL 表达式,从而执行恶意操作,如访问或修改对象的属性、调用方法等。
  • 示例:如果一个 Spring 应用程序接受用户输入并将其用于 SpEL 求值,攻击者可以输入#{T(java.lang.Runtime).getRuntime().exec('calc')}(在 Windows 环境下,这可能会弹出计算器,演示了恶意代码执行)来尝试执行任意命令。
  • 解决办法:使用SimpleEvaluationContext ,
  • ExpressionParser parser = new SpelExpressionParser();
    EvaluationContext simpleContext = SimpleEvaluationContext.forReadOnlyDataBinding().build();

SSRF(服务器端请求伪造)

  • 原理:攻击者利用服务器端的功能,让服务器发起请求,访问内部资源或其他受限的网络资源。这通常是因为服务器没有对请求的目标进行充分的验证。
  • 示例:如果一个服务器端应用程序提供了根据用户输入的 URL 获取内容的功能,攻击者可以输入内部网络的敏感资源地址,如http://192.168.1.100:8080/internal-api,利用服务器的权限获取敏感信息。

目录遍历

  • 原理:攻击者通过构造特殊的请求,尝试访问服务器上受限的目录和文件,绕过服务器的访问限制机制。这通常是由于对用户输入的文件路径或目录路径没有进行严格的验证。
  • 示例:在一个文件下载功能中,如果应用程序直接使用用户输入的文件名进行文件读取,攻击者可以输入../secret/file.txt(假设..表示上级目录)来尝试访问服务器上受限的文件。
  • 解决办法:限制目录,对入参校验,入../或者/。

接口未授权

  • 原理:应用程序中的某些接口没有进行适当的身份验证或授权检查,使得攻击者可以直接访问这些接口,获取敏感数据或执行敏感操作。
  • 示例:一个 Web API 原本应该只有授权用户才能访问,但由于没有正确的认证机制,攻击者可以直接通过 HTTP 请求访问该 API,获取用户数据或修改系统状态。
  • 解决办法:使用自动化测试检查参数返回值,避免漏网之鱼。

上传漏洞

  • 原理:当应用程序提供文件上传功能时,如果没有对上传的文件类型、内容等进行严格的安全检查,攻击者可以上传恶意文件,如可执行文件、包含恶意脚本的文件等,从而对服务器或其他用户造成危害。
  • 示例:在一个图片分享网站中,如果没有对上传的文件进行有效的类型检查,攻击者可以上传一个名为image.jpg.php的文件(实际上是一个 PHP 脚本),当服务器处理该文件时,可能会执行其中的恶意代码。
  • 解决办法:验证文件的后缀,有些木马可能会伪装成图片,可以进一步解析图片。

XPath 注入

  • 原理:类似于 SQL 注入,攻击者在 XPath 查询中注入恶意的 XPath 表达式,欺骗应用程序执行非预期的查询操作,从而获取或篡改数据。
  • 示例:在一个使用 XPath 查询用户信息的应用程序中,如果用户输入直接用于构建 XPath 语句,攻击者可以注入' or 1=1 or '这样的表达式,改变查询的逻辑,可能获取到其他用户的信息。
  • 正则表达式攻击(ReDoS – Regular expression Denial of Service)
  • 原理
    • 正则表达式是用于匹配和处理文本模式的强大工具。然而,如果正则表达式的设计不当,攻击者可以构造特殊的输入字符串,导致正则表达式在匹配过程中出现灾难性回溯。当正则表达式引擎处理这种输入时,它可能需要花费大量的时间和计算资源来尝试所有可能的匹配路径,从而使应用程序陷入长时间的计算甚至导致服务不可用。
  • 示例
    • 考虑一个简单的正则表达式(a+)+b,用于匹配以一个或多个a组成的字符串,后面跟着一个b。攻击者可以构造一个非常长的字符串,如大量的a字符,当正则表达式引擎尝试匹配这个字符串时,它会在内部进行大量的回溯操作。对于一个足够长的输入,这可能会消耗大量的 CPU 时间和内存,导致应用程序响应缓慢甚至崩溃。
  • JSON 大对象攻击
  • 原理
    • 当应用程序接收并解析 JSON 数据时,如果没有对 JSON 对象的大小进行限制,攻击者可以发送一个极大的 JSON 对象甚至知道接口参数发送递归的数据。这可能会导致以下问题:一是消耗大量的内存资源,因为应用程序需要将整个 JSON 对象加载到内存中进行解析;二是可能导致解析过程超时,堆栈(递归)异常或其他异常,影响应用程序的正常运行。这种攻击利用了服务器端在处理 JSON 数据时的资源消耗特性。
  • 示例:假设一个 Web 应用程序的某个 API 端点接受 JSON 格式的输入,用于更新用户配置信息。攻击者构造一个包含数百万个键值对的巨大 JSON 对象,并将其发送到这个 API。如果应用程序没有对 JSON 输入的大小进行限制和验证,在尝试解析这个大对象时,服务器的内存可能会被耗尽,导致服务器性能下降甚至服务中断。
  • 解决办法:设置json的大小,限制递归的层级。


4 Comments

  1. Aes128 256 在线加密
    3 11 月, 2024

    Aes128 256 在线加密

  2. XIANG
    13 11 月, 2024

    https://aes.golong.uk/ aes加密在线工具

  3. XIANG
    13 11 月, 2024

    https://timestamp.golong.uk/ 时间戳转换工具

Write your comment Here