Key Protect 示意图:一个带有锁和钥匙的安全蓝色立方体,包含云和其他数据元素

什么是安全编码?

安全编码的定义

安全编码,也称为安全编程,是指编写能够抵御来自威胁参与者网络攻击的源代码的实践。将安全性嵌入代码中有助于限制漏洞,创造出足够健壮和有弹性的软件以抵御网络威胁

安全编程是安全软件开发生命周期 (SSDLC) 的重要组成部分。与传统 SDLC 仅在测试阶段才将安全性纳入考虑不同,SSDLC 将网络安全融入软件开发过程的每个阶段。代码安全不仅仅是事后的想法、可选的附加项或一个孤立的方面,而是构建安全软件的基本要素。

安全编码也属于应用程序安全的更广泛范畴。安全编程专注于将网络安全融入代码,而应用程序安全则涵盖广泛的安全措施——从硬件防护到基于软件的防御——并贯穿整个 SDLC。

根据 IBM 2026 年 X-Force Threat Intelligence Index,漏洞利用已成为攻击的主要原因。转向更主动和预防性的方法(如安全编码)可以在威胁升级之前捕获它们。

安全编码的优势

安全编程提供以下优势:

  • 成本效益:在部署前修复安全缺陷比发布后修复成本更低。

  • 早期检测与预防:在开发过程中捕获并消除漏洞,防止其传播到生产环境。

  • 节省时间和精力:安全代码有助于避免与实时系统的事件响应和修复相关的大量时间和精力。

安全编码技术解决的常见漏洞

代码中的安全漏洞通常源于软件设计和架构的缺陷、配置错误或编程错误等。恶意行为者经常利用这些漏洞作为攻击的入口点。

以下是安全编程旨在解决的一些典型漏洞,这些漏洞基于开放全球应用程序安全项目 (OWASP) 列出 的 Web 应用程序安全风险:

  • 身份验证失败

  • 访问控制失效

  • 加密失败

  • 注入攻击

  • 不安全的设计

  • 日志记录与告警失败

  • 安全配置错误

  • 软件或数据完整性失败

身份验证失败

网络犯罪分子利用身份验证机制中的弱点,窃取用户凭证并实施恶意活动。身份验证失败包括弱密码策略、缺乏强身份验证方法、不当的会话管理,以及对密码破解手段(如通过试错找到正确密码的暴力破解攻击,或利用已泄露的用户名和密码对进行凭证填充以获取用户账户访问权限)防护不足。

访问控制失效

访问控制用于确定谁被允许访问数据或资源,以及他们被允许执行哪些操作。失效或执行不当的访问控制可能导致未经授权的访问和权限滥用。威胁可能包括:修改 API 请求和 URL 参数以绕过访问控制检查,或者不安全的直接对象引用(即在不验证权限的情况下,直接使用唯一标识符引用数据或资源)。

加密失败

加密方法中的缺陷可能暴露敏感数据并导致数据泄露。加密失败包括使用过时或弱加密算法、密钥管理协议不佳、采用硬编码密钥,以及未进行适当加密就传输或存储数据。

注入攻击

注入攻击是最常见的安全漏洞类型之一。恶意输入——无论是代码、命令、查询还是脚本——被插入到程序或网页中,以发起恶意软件攻击、修改数据或窃取私密信息等。跨站脚本攻击、跨站请求伪造和服务器端请求伪造是一些常见的注入攻击。

跨站脚本 (XSS)

跨站脚本攻击 (XSS) 是在受信任的网站上部署不受信任的代码或脚本,然后由不知情的用户执行。这通常发生在应用程序未能对用户提供的数据进行转义、过滤、清理或验证时。

 
跨站请求伪造(CSRF 或 XSRF)

跨站请求伪造(CSRF 或 XSRF)会从一个已认证的用户向网站发送未授权的请求。它利用网站对已认证用户网页浏览器的信任,通过链接或脚本诱使浏览器向目标网站发送恶意请求。

服务器端请求伪造 (SSRF)

服务器端请求伪造 (SSRF) 会操纵发送到服务器的 URL。当服务器在未先验证 URL 的情况下接收被操纵的请求时,该请求可用于连接内部服务(如数据库)或读取文件、服务器配置及其他元数据。

不安全的设计

不安全的设计涉及由业务逻辑或应用程序架构缺陷引起的漏洞。它出现在 SDLC(软件开发生命周期)的早期规划阶段,即在定义需求和绘制系统蓝图时。缺乏风险评估、安全设计模式和参考架构使用有限、以及极少进行威胁建模来系统分析计划架构中潜在安全漏洞——这些因素都可能导致不安全的设计。

日志记录与告警失败

不充分或无效的告警和日志可能导致攻击和泄露事件未被发现,使威胁参与者能够造成严重损害。日志记录与告警失败的一些实例包括:关键事件未被记录或记录不一致;日志存储不安全,可能容易被篡改或未经授权访问;对实时或近实时活跃攻击的告警不足;日志消息不清晰或缺乏细节及上下文;以及日志包含敏感数据但未进行脱敏或清洗。

安全配置错误

当应用程序栈(包括云服务、数据库、框架、库、操作系统Web 服务器)的安全设置未正确配置时,就会出现此漏洞。安全配置错误包括:禁用安全更新、权限过于宽泛、默认凭证未更改以及不必要的功能被保持启用。

软件或数据完整性失败

这些失败涉及缺乏针对接受或处理来自外部来源的无效或不可信数据的防护措施。示例包括:自动应用软件更新而未验证其完整性;使用不可信来源的依赖项(如第三方库和插件);以及 CI/CD 流水线在未经验证的情况下拉取代码或其他软件开发工件。

用于安全编码的生成式 AI

一些生成式 AI 技术可以帮助进行安全编程。例如,像 Claude Code 和 IBM Bob 这样的智能体式 AI 编码平台可以实时发现漏洞并为不安全的代码提出修复建议。AI 代码生成工具还可以协助重构代码以提升安全性。

虽然 AI 编码助手可以自动化并加速软件开发,但它们仍然需要指导才能生成安全的代码。程序员必须提供清晰的 提示,不仅要指定功能,还要指定安全要求。例如,像“创建一个登录函数”这样的通用提示可以扩展为“创建一个检查用户输入是否符合预期格式和长度的登录函数”,以包含安全编码指令。开源安全基金会的指南 包含示例指令,以帮助 AI 助手考虑代码安全性。

软件工程团队还可以提供上下文,引导生成式 AI 生成更安全的代码。检索增强生成 (RAG) 将 AI 驱动的开发者工具与内部安全编码标准连接起来。对于没有定义指南的团队,Secure Code Warrior 的 AI 安全规则 可作为生成更安全的 AI 代码的起点。

与 AI 助手一样,AI 编码智能体也需要指导。CodeGuard 项目 提供了一个规则集和技能框架,将安全编码实践直接嵌入到智能体工作流中。AI 编码智能体可以在规划阶段将这些规则和技能作为其目标的一部分,并在执行阶段编写代码时使用它们。

人工智能本身生成的代码可能会引入漏洞,因此准确性和安全性的最终判断仍由人类程序员负责。生成式 AI 措施还必须与以下安全编码最佳实践相结合,以构建多层保护。

安全编码最佳实践

安全编码的最佳实践包含多种防御性编程策略,以增强软件安全性。企业可能担心在安全编码与交付速度之间取得平衡。但许多实践在不牺牲快速交付的情况下将安全性集成到代码中,例如将安全融入设计阶段、建立安全编码指南、培训开发者使其能够在编码时识别和修复安全缺陷,以及自动化代码分析和测试以发现漏洞。

虽然无法列举所有现有的安全编码最佳实践,但此列表可作为起点,结合这些实践可以增强组织的安全态势

  • 遵循安全编码标准

  • 将安全融入设计

  • 验证和净化输入并编码输出

  • 实施强大的加密协议

  • 进行身份验证和授权

  • 建立健全的日志记录和安全的错误处理机制

  • 全面安全测试

  • 将安全作为代码审查的一部分

遵循安全编码标准

这些标准作为将安全编码技术有效集成到现有开发工作流中的基本指南。它们为跨软件项目的安全编程提供了共享的基线。

OWASP 开发者指南

OWASP 开发者指南 是程序员参考的指南,帮助他们导航并编写安全的源代码。该指南概述了与技术无关的安全编码实践,并附有从已归档的 OWASP 安全编码实践快速参考指南中迁移过来的检查清单,突出关键代码安全要点。

OWASP 还提供了一系列速查表 ,用于实施安全编码原则并应对广泛的各种代码漏洞。

SEI CERT 编码标准

SEI CERT 编码标准 由卡内基梅隆大学的软件工程研究所创建,为 Android、C、C++、Java 和 Perl 编程语言提供安全编程指导。这些标准包含规则、建议以及合规代码和不合规代码的示例。规则和建议附有相应的风险评估,按严重性、可能性和修复成本进行分类,以帮助软件工程团队确定工作优先级。

NIST 安全软件开发框架

除了用于信息安全和网络安全风险管理网络安全框架外,美国国家标准与技术研究院 (NIST) 还发布了其安全软件开发框架。该框架由高层次、基于结果的安全软件开发实践组成,使其成为 OWASP 和 SEI CERT 更具技术性标准的理想补充。

将安全融入设计

将安全设计构建到系统蓝图中,符合将安全更早地引入软件开发过程的“左移”方法。它甚至在编写第一行代码之前就考虑如何使软件变得安全。

 

全面的风险评估和威胁建模有助于发现软件架构中的潜在安全漏洞。安全设计阶段还必须引入安全团队进行实践协作,并就安全要求以及如何在源代码层面处理这些要求提供指导。

有关将安全融入设计的更多信息,团队可以参考 OWASP 关于安全产品设计 和威胁建模 的速查表,以及其安全设计框架

验证和净化输入并编码输出

核心的安全编码原则是永不信任任何输入,注入攻击就证明了这一点。服务端验证和净化有助于确保输入在处理之前不存在安全风险。

软件工程团队可以将所有验证和净化逻辑放在一个安全的核心文件或位置中,以保持一致性并便于快速访问和更新。他们还可以使用编程语言和框架内置的验证和净化模块,但这些模块必须定期更新以应对新发现的漏洞。

验证输入

输入验证用于检查数据类型、格式、长度、范围、尺寸及其他约束条件是否正确。这可能涉及将输入与允许的模式进行匹配,或将其与允许的字符集或值集进行比较。

净化输入

净化输入意味着清理输入并将其转换为安全的形式。它必须针对特定的编程语言或框架进行定制。

例如,在 HTML 中,转义特殊字符如 &、<、>、" 和 ' 有助于防止 XSS 攻击。像 DOMPurify  这样的库可以帮助进行 HTML 净化。

对于数据库,将参数化查询与预编译语句结合使用,有助于防止 SQL 注入攻击,因为输入被当作数据处理,而非可能被意外执行的 SQL 代码。参数化查询首先定义所有 SQL 代码,为输入或参数留出占位符,然后将每个参数随后传递给查询。预编译语句是预编译的 SQL 语句,这意味着注入的 SQL 命令无法改变查询的意图或其执行方式。

编码输出

输出编码使数据能够以文本形式安全显示,从而不会被解释为代码。许多框架自带默认的输出编码保护或自动编码和转义函数。OWASP Java Encoder  支持针对不同上下文的上下文相关输出编码,例如将变量放入 URL、内联 CSS 或内联 JavaScript 中,以及将变量插入 HTML 属性值、CSS 属性或两个 HTML 标签之间。

实施强大的加密协议

如果应用得当,加密技术可以保护信息的机密性、完整性和可用性。

算法

程序员在加密传输中和静态存储的数据时,必须使用当前且强大的算法。AES 被公认为对称加密的黄金标准,其认证模式和 256 位密钥提供了高等级的安全性。对于非对称加密,使用安全曲线的 ECC 或启用随机填充且密钥至少为 2048 位的 RSA,可提供强健的安全性。

为了保护密码,必须应用哈希算法,并在哈希过程中向密码添加盐值(一个独特的、随机生成的字符串)。哈希算法是一种单向数学函数,它将数据转换为唯一的、更短的、固定长度的值,该值无法被解码或反向还原。现代哈希算法包括 Argon2id  和 scrypt

开发者必须采用可靠、受支持且持续维护的加密库实现,例如 Bouncy CastleLibsodiumOpenSSL  和 Tink,而不是自己创建加密算法。

密钥与密钥管理

密钥不得硬编码到源代码中、不得提交到版本控制系统、不得存储在环境变量中,也不得暴露在日志中。密钥管理解决方案和技术可以帮助自动化密钥管理生命周期——从生成、分发、存储到使用、轮换、撤销和销毁。

传输层保护

在传输层保护方面,软件工程团队必须使用诸如超文本传输安全协议 (HTTPS) 或 HTTP 严格传输安全协议 (HSTS) 以及最新版本的 TLS 等协议。必须禁用对敏感数据的缓存,并避免不必要地存储敏感数据。

身份验证与授权

身份验证与授权是验证实体身份并确保该实体拥有适当访问权限等级的关键安全编码实践。

身份验证

多重身份验证 (MFA) 是针对密码相关攻击的最佳防御手段之一。其他机制包括登录限流(以防止黑客猜测密码次数过多)和账户锁定(在多次登录失败后,在一定时间内阻止登录尝试)。

对于无密码身份验证,开发者可以考虑诸如 OpenID Connect (OIDC) 和安全断言标记语言 (SAML) 等协议。FIDOFIDO2 开放标准通过通行密钥促进无密码认证,并可用于认证应用程序、在线服务和网站。

会话管理

一旦身份验证会话建立,就必须通过安全的会话 ID 或令牌来维护该会话。会话 ID 必须使用强密码学安全的伪随机数生成器生成。与任何其他用户输入一样,会话 ID 或令牌在处理之前必须经过验证,并滤除无效值。

为每个会话设置过期超时时间,可以限制恶意行为者劫持活动会话并发起攻击的持续时间。软件工程团队可以使用 Web 开发框架提供的内置会话管理功能。

授权

程序员可以采用诸如 OAuth 等授权协议,该协议与 OIDC 身份验证协议协同工作。在访问控制方面,基于角色的访问控制 (RBAC) 是一种流行模型,用户根据其预定义角色被授予访问权限。其他可能更强大并支持更细粒度权限的选项包括基于属性的访问控制 (ABAC) 和基于关系的访问控制 (ReBAC)。ABAC 分析行为、对象和用户的属性(例如用户名、资源类型和时间点)以决定是否授予访问权限。ReBAC 根据资源之间的关系授予访问权限。

 

即使有了协议和访问控制模型,仍必须在每个请求上验证权限,并对实体尝试访问的每个对象执行访问控制检查。默认拒绝访问和应用最小权限也是授权方面至关重要的安全编码原则。

建立健全的日志记录和安全的错误处理机制

日志和错误信息可以成为帮助恶意行为者策划攻击的丰富信息源。这意味着日志和错误都必须谨慎处理。

日志记录

应用程序错误、与配置更改及管理员或特权操作相关的系统事件,以及身份验证、授权、输入验证和会话管理领域的失败事件,都必须记录在日志中,因为这些可能表示入侵企图。必须包含足够的信息,例如用户详细信息(身份、角色和权限)以及错误或事件的上下文(目标、操作和结果),以辅助分析和调试

日志必须写入只读介质,并存储在具有受限访问权限和内置篡改检测功能的安全位置。如果需要将日志发送到其他系统,则必须使用安全的传输协议。

敏感数据不得记录在日志中,必须从日志中清除或删除。任何其他被视为关键的信息,例如数据库连接字符串、文件路径、内部网络名称和地址、会话 ID 或令牌,都必须加密、哈希或脱敏处理。

日志库必须定期更新,以确保安全漏洞得到修补,正如影响广泛部署的开源 Log4j 日志库的 Log4Shell 漏洞所示,该漏洞允许黑客在受影响的系统上运行几乎任何他们想要的代码。

错误处理

错误处理与日志记录相辅相成,因为有关错误的信息通常出现在日志中。而未处理的错误可能成为威胁参与者的入口点。

开发者可以考虑创建一个全局错误处理程序,为意外错误返回通用的响应或错误代码,然后在服务器端记录有关错误的更多详细信息。这样可以在安全处理错误的同时避免向黑客泄露信息,并为程序员提供必要的调查线索。

全面安全测试

嵌入到源代码中的所有安全措施都必须经过验证。QA 和开发团队可以参考 OWASP 的 Web 安全测试指南 和应用程序安全验证标准 ,作为测试代码安全性的基础。自动化工具也可以辅助这一过程。

静态应用程序安全测试 (SAST)

静态应用安全测试 (SAST) 应用预定义的规则来精确定位代码中表明可能存在漏洞的模式。SAST 有时被称为“白盒”测试,而 SAST 工具也被称为静态代码分析器,因为它们无需运行应用程序即可扫描代码。

SAST 工具擅长标记常见的代码漏洞,并能确定其所发现漏洞的确切行号和文件。它们还能与大多数 IDE 和 CI/CD 环境无缝集成。然而,它们容易产生误报。

动态应用程序安全测试 (DAST)

动态应用程序安全测试 (DAST) 采用由外而内的方式,在应用程序的运行时环境中通过模拟攻击来评估应用程序,以模仿真实世界中威胁参与者的行为。因此,DAST 通常被称为黑匣,因为测试人员无需了解或访问系统的内部工作原理或源代码。DAST 通常比 SAST 产生更少的误报。

将 SAST 和 DAST 结合使用,可以更全面地揭示潜在漏洞。为了进行更全面的安全测试,SAST 和 DAST 可以与其他方法结合使用,例如交互式应用安全测试(IAST,它同时评估代码上下文和运行时行为以实时报告漏洞)和软件成分分析(SCA,它分析软件以确保其组件安全且为最新版本)。

将安全作为代码审查的一部分

大多数代码审查关注质量,检查代码是否符合风格指南、逻辑问题、最优流程以及测试和边缘情况的覆盖范围。但安全性也必须成为代码审查过程的一部分。

安全代码审查充当静态代码分析器之后的下一道防线。人工代码审查者提供领域专业知识、判断力以及对自动化工具常常遗漏的代码安全漏洞的洞察力。

为了采用更结构化的方法,代码审查者可以参考 OWASP 的安全代码审查速查表

AI 学院

成为 AI 专家

获取相关知识,以确定 AI 投资的优先级,从而推动业务增长。立即开始观看我们的免费 AI 学院视频,引领 AI 在组织中的未来应用。

作者

Rina Diane Caballar

Staff Writer

IBM Think

Cole Stryker

Staff Editor, AI Models

IBM Think

相关解决方案
IBM Bob

借助您的 AI 合作伙伴 Bob,加速软件交付,实现安全的意图感知型开发。

深入了解 IBM® Bob
AI 编码解决方案

利用可信的 AI 驱动型工具优化软件开发工作,最大限度地减少编写代码、调试、代码重构或代码补全的时间,从而拓展创新空间。

深入了解 AI 编码解决方案
AI 咨询与服务

通过增加 AI 重塑关键工作流程和运营,最大限度提升体验、实时决策能力和商业价值。

深入了解 AI 咨询服务
采取后续步骤

利用生成式 AI 和高级自动化技术加速创建企业就绪代码。Bob 通过建模增强开发人员技能,简化并自动执行开发与现代化工作。

  1. 了解 IBM Bob
  2. 深入了解 AI 编码解决方案