开发安全培训

27 分钟

安全开发的意义

  1. 安全是开发的核心前提:代码编写与系统设计的全流程中,主动预判并规避潜在安全漏洞是开发工作的基础环节,而非后续补充。这要求开发者将安全思维融入需求分析、编码实现、测试验证等每一步,从源头降低漏洞引入风险。
  2. 安全的本质是风险可控:没有绝对的安全是行业共识,安全开发的目标并非追求 “零风险”,而是通过体系化措施将风险压缩至可接受的极低范围,实现 “相对安全” 的稳态。
  3. 安全投入直接关联核心利益:产品安全工作的深度与广度,直接决定了黑客的攻击成本。每多一分安全加固,都能提升攻击门槛,从而为客户数据安全与公司商业利益增添一道坚固屏障。
  4. 左移安全显著降低综合成本:将安全考量与问题解决左移至产品生命周期的早期(如设计阶段、编码初期),实现早规划、早发现、早修复,能大幅降低后期(如上线后)修复漏洞的技术难度与时间成本,更能有效避免漏洞被利用导致的业务中断、数据泄露等重大损失。

安全威胁来自哪里

img

  • 黑/灰产业链:用户信息买卖、订单信息买卖、数据库买卖、电信订单诈骗、黄牛刷单(活动低价商品、优惠券)、0元订单。
  • 白帽子黑客
  • 竞争对手
  • 合作伙伴
  • 供应商
  • 外包商
  • 内部人员

漏洞排行榜

OWASP是什么?

img

  1. OWASPOpen Web Application Security Project(开放式 Web 应用程序安全项目)的缩写,是一个全球性的、非营利性的网络安全组织,致力于提升 Web 应用程序的安全性。
  2. OWASP 的核心使命是 “使安全成为软件开发生命周期中不可分割的一部分”。它通过汇聚全球各地的安全专家、开发人员、研究人员和技术爱好者,以开源协作的方式产出免费、公开的安全资源,帮助企业和个人理解、应对 Web 应用面临的安全风险,打破安全知识和工具的壁垒。

OWASP VS XXX TOP10

OWASP TOP 10 XXX TOP 10
失效的访问控制 不安全的设计
加密失败 敏感信息泄露
注入 失效的访问控制
不安全的设计 安全配置错误
安全配置错误 使用易受攻击和过时的组件
使用易受攻击和过时的组件 注入
身份识别和身份验证失败 跨站脚本
软件和数据完整性故障 不安全的反序列化
安全日志记录和监控失败 服务端请求伪造
服务器端请求伪造 加密失败

OWASP TOP 10高频场景

img

  1. 失效的访问控制:用户的访问权限控制不足,攻击者可能未经授权访问敏感数据或执行关键操作。
  • 水平越权(同权限组用户互访) 某电商 APP 的 “我的订单” 接口为 GET /api/metacat/XXX?groupId=61,后端仅校验用户是否登录,未校验 groupId 属于当前登录用户。攻击者修改 groupId为他人组号(如 62),即可直接查看其他用户的信息。

  • 垂直越权(低权限用户访问高权限功能) 某电网管理系统中,普通员工登录后页面隐藏 “管理员后台” 入口,但管理员后台的核心接口 POST /api/admin/deleteUser 未校验用户角色。攻击者通过抓包工具直接构造该接口请求,可删除任意员工账号。

  • 未授权访问接口资源 某学校管理系统Swagger接口文档信息泄露,通过一个个试验发现存在部门信息接口访问无需权限控制,最终通过小红书求助拿到整个学校的全部学生信息和账号密码。

img

img

img

img

  1. 加密失败:数据加密过程存在问题,导致敏感信息在传输或存储时面临泄露风险。
  • 密码弱哈希存储 某论坛为简化开发,将用户密码用 MD5 算法直接哈希后存储(无盐值)。攻击者获取数据库后,通过 "彩虹表"快速破解大量密码(如 MD5("123456")=e10adc3949ba59abbe56e057f20f883e 可直接匹配)。
  • 传输层未加密 某小型理财平台仍使用 HTTP 协议传输用户登录数据,攻击者通过"中间人攻击"(如抓包),可直接捕获用户输入的账号密码明文,无需破解即可登录。
  • 密钥硬编码与弱加密 某 APP 为保护本地存储的用户 Token,用 AES 算法加密但将密钥硬编码在代码中(String aesKey = "abcdef1234567890"),且加密模式设为 ECB(电子密码本模式,相同明文加密结果相同)。攻击者反编译 APP 获取密钥后,可轻松解密所有用户 Token。

img

  1. 注入:攻击者向应用输入字段注入恶意代码,使应用执行恶意命令或查询,常见的有 SQL 注入、模板注入等。
  • 某工业控制系统管理后台登录页面账号处输入admin' OR '1'='1',使用任意密码可成功登录成admin账户
  • 某商城系统使用 Freemarker 模板,攻击者注入 <#assign value="freemarker.template.utility.ObjectConstructor"?new()>${value("java.lang.ProcessBuilder","calc").start()},可执行任意命令获取服务器权限

img

  1. 不安全的设计:在应用程序设计阶段没有充分考虑安全因素,导致系统存在固有弱点。
  • 某深圳餐饮App提现的功能设计时,仅校验"用户余额≥提现金额",未设计幂等性校验,导致高并发请求提交同一笔提现请求,余额仅扣减 1 次,但实际到账很多次。
  • 登录系统设计为 “连续输错 5 次密码锁定账户30分钟”,但未限制 “同一 IP 对多个账户的尝试次数”。攻击者可利用脚本对大量账户进行批量暴力破解,导致大量用户都被锁定。

img

  1. 安全配置错误:Web 服务器、应用服务器、数据库服务器等配置不当,如开放不必要的服务、使用默认账户密码等。
  2. 使用易受攻击和过时的组件:应用程序使用了存在已知安全漏洞的第三方库、框架或软件版本。
  • 某广州职业学院后台使用actuator对应用系统进行自省和监控,配置不当导致所有的核心信息泄露。
management.endpoints.web.exposure.include=
management.endpoint.shutdown.enabled=true
  • 某企业泛微OA使用的Tomcat9.0.1中间件开启了基于文件的会话持久化功能以及启用了DefaultServlet-Partial PUT请求,导致会话存储文件被恶意的反序列化,造成了任意命令执行。
<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    <Manager className="org.apache.catalina.session.PersistentManager">
    <Store className="org.apache.catalina.session.FileStore"/>
    </Manager>
</Context>
 <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>readonly</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

img

img

  1. 身份识别和身份验证失败:身份验证和会话管理功能实现不当,攻击者可破解密码、会话令牌等冒充其他用户。

某网站前端登录采用RSA加密(公私钥均放到前端js文件中),用于用户鉴别的RSA-JWT与登录使用的一样,导致JWT能够被成功伪造,出现任意用户登录。

img

  1. 软件和数据完整性故障:软件更新、关键数据或基础设施组件未得到妥善保护,导致数据或软件被篡改。

NPM官方仓库中的开发者valorkin维护86个开源项目中的2个组件(ngx-bootstrap 与 ng2-file-upload)以及开发者scttcper维护54个开源项目中的14个组件(@ctrl/tinycolor等),总计涉及近40个开源组件项目,其中受影响的多个热门组件历史总下载量超过亿次,影响范围极大**。**攻击者在组件源码中直接植入混淆恶意文件bundle.js,其主要功能是在组件安装过程中静默窃取受害者系统平台信息、环境变量数据以及主流业务(包括NPM、Github、AWS及GCP等)的token密钥。

img

受害者被投毒攻击后,敏感数据将直接在github上公开泄漏,base64解码后可还原出github token凭证

img

img

  1. 安全日志记录和监控失败:缺乏有效的安全日志记录和实时监控机制,无法及时发现和响应安全事件。
  • 某系统虽开启了日志记录,但日志文件未定期备份且存储在本地,攻击者入侵后直接删除日志文件,销毁攻击痕迹,管理员无法进行事后溯源
  1. 服务器端请求伪造:攻击者操纵服务器向其他系统发送未经授权的请求,访问内部系统资源或获取敏感数据。
@PostMapping(consumes = "multipart/form-data", value = "/file/pdf")
@Operation(
        summary = "Convert a file to a PDF using LibreOffice",
        description =
                "This endpoint converts a given file to a PDF using LibreOffice API  Input:ANY"
                        + " Output:PDF Type:SISO")
public ResponseEntity<byte[]> processFileToPDF(@ModelAttribute GeneralFile generalFile)
        throws Exception {
    MultipartFile inputFile = generalFile.getFileInput();
    File file = null;
    try {
        file = convertToPdf(inputFile);

        PDDocument doc = pdfDocumentFactory.load(file);
        return WebResponseUtils.pdfDocToWebResponse(
                doc,
                Filenames.toSimpleFileName(inputFile.getOriginalFilename())
                                .replaceFirst("[.][^.]+$", "")
                        + "_convertedToPDF.pdf");
    } finally {
        if (file != null) file.delete();
    }
}
 public File convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException {
        String originalFilename = Filenames.toSimpleFileName(inputFile.getOriginalFilename());
        if (originalFilename == null
                || !isValidFileExtension(FilenameUtils.getExtension(originalFilename))) {
            throw new IllegalArgumentException("Invalid file extension");
        }
        Path tempInputFile =
                Files.createTempFile("input_", "." + FilenameUtils.getExtension(originalFilename));
        inputFile.transferTo(tempInputFile);
        Path tempOutputFile = Files.createTempFile("output_", ".pdf");

        try {
            //LibreOffice
            List<String> command =
                    new ArrayList<>(
                            Arrays.asList(
                                    runtimePathConfig.getUnoConvertPath(),
                                    "--port",
                                    "2003",
                                    "--convert-to",
                                    "pdf",
                                    tempInputFile.toString(),
                                    tempOutputFile.toString()));
            ProcessExecutorResult returnCode =
                    ProcessExecutor.getInstance(ProcessExecutor.Processes.LIBRE_OFFICE)
                            .runCommandWithOutputHandling(command);
            return tempOutputFile.toFile();
        } finally {
            if (tempInputFile != null) Files.deleteIfExists(tempInputFile);
        }
    }
POST /api/v1/convert/file/pdf HTTP/1.1
Host: 172.25.24.140:8080
Content-Length: 230
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryXk10yDA52D8VSaGO
Accept: */*
Origin: http://172.25.24.140:8080
Referer: http://172.25.24.140:8080/file-to-pdf?lang=zh_CN
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=node0dylx4lgdtzxwixmnid86661r1.node0
Connection: close

------WebKitFormBoundaryXk10yDA52D8VSaGO
Content-Disposition: form-data; name="fileInput"; filename="1.html"
Content-Type: text/html

<img src='http://xxx.dnslog.cn'>

------WebKitFormBoundaryXk10yDA52D8VSaGO--
  • 某Web应用程序存在SSRF且云上配置不当,导致所有云机器被接管。
https://help.aliyun.com/zh/eci/user-guide/obtain-the-metadata-from-a-container-1
https://help.aliyun.com/zh/ecs/user-guide/view-instance-metadata

img

img

知名例子

麦当劳

弱口令+失效的访问控制

麦当劳的招聘平台McHire使用了Paradox.ai开发的名为Olivia的AI聊天机器人,来收集求职者的个人信息,包括姓名、电话号码、电子邮件地址、物理地址等,McHire存在安全漏洞,超过6400万求职者的个人信息遭暴露。在成功登录后,可以修改网址中的数字参数(应聘者的ID编号),任何McHire账户持有者都能查看其他申请人的聊天交互机密信息。

img

img

安全配置错误

  1. 麦当劳系统Design Hub(120个国家团队使用的品牌资产平台) 中发现漏洞,平台仅依靠客户端密码进行保护,只需要将https://admin.me.mcd.com/feel-good-design/login中的login改成register,即可访问开放端点,该API还会提示用户填写缺失字段,使得账户被任意创建。
  2. Design Hub中的JavaScript文件硬编码存储了Magicbell API密钥和密钥允许列出用户并通过麦当劳基础设施发送钓鱼通知,导致允许通过麦当劳的基础设施发送钓鱼通知。

img

img

印度麦当劳App

McDelivery系统,允许订购麦当劳外卖,在Google Play下载量超过1000万次,在印度开发了独有的App。

img

订单信息遍历

  1. McDelivery网站和移动应用程序使用Angular构建,面向消费者的高交互性应用程序,在main.js中找到了了关于订单信息的接口和参数。

img

  1. 通过尝试order-tracking中的参数,倾向输入0或1查看是否是简单的整数值,果然得到了结果。

img

  1. 订单 ID 是连续的,这意味着您可以不断将数字加 1 以获取下一个订单的详细信息,从而获取更多用户信息,由于在API调用中需要JWT令牌,尚未创建帐户,也未登录。该令牌来自加载网站时在后台运行的访客登录 API 调用。

img

img

零元购

麦当劳选购下单的时候,选择一个海上的地址进行配送,底部显示地址无法使用,通过删除前端的disable按钮进行下单,点击支付,跳转到支付处理器Juspay

img

img

img

JustPay订单支付的接口里面,有字段名orderDetails,它包含所有需要修改的键值,包括订单的ID,价格等等。因为存在一个校验字段Signature服务端的校验字段,更改它们不会产生预期的结果,签名在服务器端生成如下:

  • 订单 API 接受您的购物车 ID 并从购物车对象中提取所有需要的信息。
  • 创建 orderDetails 对象,并基于该对象创建 RSA 签名。
  • 两者都返回给客户端

img

购物车对象能够接受商品更新,但它也能接受价格更新吗?我整理了一个 PUT 请求来更新价格,成功更新了价格,并且得到了一个有效的签名,最终完成了零元购。

img

管理数据泄露

McDelivery 的管理面板位于https://oms.mcdelivery.co.in/,通过JS数据找到了一个管理端点来查看接受消费者 JWT 令牌的KPI报告。

img

img

本企业漏洞案例

保密问题暂删除。

注意事项

类别 注意事项
注入 1.SQL 注入防护:强制使用参数化查询(PreparedStatement),避免直接拼接用户输入到 SQL 语句中;若使用 ORM 框架(如 MyBatis),通过 XML 映射文件的参数占位符(#{})实现参数化,而非字符串拼接的${}。 2. 命令注入防护:避免直接调用Runtime.exec()等系统命令执行方法,若必须使用,需对用户输入进行白名单校验(只允许特定命令或参数)。 3. XSS 注入防护:对输出到 HTML 页面的用户输入,使用 HTML 转义工具(如 OWASP Java Encoder)进行转义;前端也需配合,使用框架自带的安全渲染方式。 4. 模板注入防护:若使用模板引擎(如 Thymeleaf、Freemarker),禁用动态模板生成;对模板中的变量,强制进行沙箱限制(如 Freemarker 禁用execute等危险方法)。
失效的身份认证 1.密码安全:使用强哈希算法(如 BCrypt、Argon2)存储密码,而非 MD5、SHA-1 等已被破解的算法;强制要求用户设置复杂密码(长度≥8,包含大小写、数字、特殊字符),并在前端 / 后端双重校验。 2. 会话管理:会话 ID 必须随机且不可预测,使用框架自带的安全会话生成机制(如 Java Servlet 的HttpSession);设置合理的会话超时时间(如 30 分钟无操作则过期),并在用户注销时立即销毁会话;为 Cookie 设置HttpOnly和Secure属性,防止 XSS 窃取和非 HTTPS 传输。 3. 多因素认证(MFA):敏感操作(如修改密码、转账)强制启用 MFA(短信验证码 + 密码、硬件令牌等);自定义 MFA 逻辑时,确保验证码一次性有效、有过期时间。
敏感信息泄露 1.数据传输安全:所有涉及敏感信息(密码、身份证号、银行卡号等)的传输,必须使用 HTTPS 协议,启用 TLS 1.2 及以上版本。 2. 数据存储安全:对敏感数据进行加密存储,使用强加密算法(如 AES),并通过密钥管理系统(KMS)安全管理密钥,避免硬编码密钥。 3. 日志与错误处理:日志中禁止记录敏感信息(如密码明文);错误页面禁止返回详细的堆栈跟踪或系统路径,只展示通用错误提示,详细错误信息在后台日志中记录。 4. 数据脱敏:展示敏感信息时进行脱敏处理(如手机号显示为138****1234),仅在必要场景(如用户本人查看)展示完整信息。
不安全的设计 1.安全设计评审:核心功能(如支付、用户权限管理)的设计方案,必须经过安全专家评审,确保符合最小权限、纵深防御等安全原则。 2. 业务流程安全:关键业务流程(如订单生成、支付、退款)需设计多重校验(如服务端二次验证前端参数、异步对账),防止流程被篡改或绕过。 3. 应急响应设计:在系统设计中融入应急响应机制,明确安全事件的检测、通知、处置流程,例如:异常流量监控、数据备份与恢复策略。
安全配置错误 1.环境隔离与最小化:开发、测试、生产环境严格隔离;服务器只安装必要的软件和服务,关闭不必要的端口(如 FTP、Telnet)和默认服务。 2. 默认配置修改:修改所有系统、应用、数据库的默认账户和密码,使用强密码,并定期更换;避免使用默认的加密密钥、证书等。 3. 配置文件安全:敏感配置(如数据库连接信息、API 密钥)禁止硬编码在代码中,应存储在加密的配置中心(如 Nacos、Consul)或环境变量中。
使用易受攻击和过时的组件 1.主动维护清单:清楚掌握项目中使用的每一个第三方库、框架及其版本号(例如使用 package-lock.json、pom.xml 等)。 2.只从官方渠道获取:永远只从官方仓库或可信源安装组件(如 Maven Central、npmjs、官方 GitHub Release),避免使用来路不明的 Jar 包或 JS 文件。 3.移除无用依赖:及时清理项目中不再使用的库,减少不必要的攻击面。
身份识别和身份验证失败 1.登录安全:设置登录失败次数限制(如 5 次失败后锁定账户 15 分钟),并启用验证码或行为验证(如滑块验证)防止暴力破解。 2. token 安全:若使用 JWT 等令牌,确保签名密钥的安全性,设置合理的过期时间,避免令牌被盗用后长期有效;令牌传输必须通过 HTTPS,禁止在 URL 中传递令牌。 3. 第三方认证集成:集成第三方登录(如 OAuth、OpenID)时,严格校验回调参数,确保重定向 URL 在白名单内,防止开放重定向漏洞。 4. 权限校验粒度:权限校验需精准到 “操作 + 资源” 维度,例如:用户只能修改自己创建的订单,管理员才能删除用户,避免 “一刀切” 的权限设计。
软件和数据完整性故障 1.不要相信来自外部的数据:任何从客户端、API、第三方服务收到的数据都可能被篡改,必须进行严格校验。 2.验证数字签名:如果使用了来自外部的代码、更新包或配置文件,必须检查其数字签名,确保它来自可信作者且未被修改。 3.使用安全的依赖库:只从官方渠道获取第三方库,并定期检查是否有已知漏洞,防止引入恶意依赖。
安全日志记录和监控失败 1.日志记录范围:关键操作(登录 / 登出、数据修改、权限变更、异常请求)必须记录日志,包含时间、用户 ID、IP 地址、操作内容、请求 ID 等信息。 2. 日志存储与保护:日志存储在安全的位置,设置访问权限,防止未授权访问;定期备份日志,保留足够长的时间(如 6 个月)以满足审计需求。 3. 实时监控与告警:集成安全监控工具(如 ELK + Wazuh、Splunk),对日志进行实时分析,设置告警规则(如多次登录失败、异常数据访问),确保安全事件能及时发现。 4. 日志格式与标准化:统一日志格式(如 JSON 格式),便于自动化分析和关联,例如:将所有系统的日志按照相同字段格式输出。
服务器端请求伪造 1.输入白名单校验:对用户可控的 URL 参数,强制校验域名和协议,只允许访问白名单内的合法域名,禁止访问内部 IP 段(如127.0.0.1、192.168..)。 2. URL 解析与规范化:使用安全的 URL 解析库(如 Java 的java.net.URL)对用户输入的 URL 进行解析和规范化,避免利用 URL 的特殊格式(如@、//)绕过校验。 3. 网络层限制:通过防火墙或网络策略,限制应用服务器对外发起请求的范围,仅允许访问必要的外部服务。 4. 错误信息限制:处理外部请求时,禁止将详细的错误信息(如内部服务的堆栈跟踪、网络拓扑)返回给用户,防止攻击者利用错误信息进行进一步攻击。

靶场体验

抓包工具:https://github.com/yaklang/yakit/releases/tag/v1.4.4-0912

代理工具:Google插件proxy

靶场地址:https://github.com/whgojp/JavaSecLab

img

~  ~  The   End  ~  ~


 赏 
承蒙厚爱,倍感珍贵,我会继续努力哒!
logo图像
tips
文章二维码 分类标签:安全安全
文章标题:开发安全培训
文章链接:https://www.aiwin.net.cn/index.php/archives/4520/
最后编辑:2025 年 10 月 20 日 20:28 By Aiwin
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
(*) 2 + 5 =
快来做第一个评论的人吧~