安全编码,也称为安全编程,是指编写能够抵御来自威胁参与者的网络攻击的源代码的实践。将安全性嵌入代码中有助于限制漏洞,创造出足够健壮和有弹性的软件以抵御网络威胁。
安全编程是安全软件开发生命周期 (SSDLC) 的重要组成部分。与传统 SDLC 仅在测试阶段才将安全性纳入考虑不同,SSDLC 将网络安全融入软件开发过程的每个阶段。代码安全不仅仅是事后的想法、可选的附加项或一个孤立的方面,而是构建安全软件的基本要素。
安全编码也属于应用程序安全的更广泛范畴。安全编程专注于将网络安全融入代码,而应用程序安全则涵盖广泛的安全措施——从硬件防护到基于软件的防御——并贯穿整个 SDLC。
根据 IBM 2026 年 X-Force Threat Intelligence Index,漏洞利用已成为攻击的主要原因。转向更主动和预防性的方法(如安全编码)可以在威胁升级之前捕获它们。
代码中的安全漏洞通常源于软件设计和架构的缺陷、配置错误或编程错误等。恶意行为者经常利用这些漏洞作为攻击的入口点。
以下是安全编程旨在解决的一些典型漏洞,这些漏洞基于开放全球应用程序安全项目 (OWASP) 列出 的 Web 应用程序安全风险:
身份验证失败
访问控制失效
加密失败
注入攻击
不安全的设计
日志记录与告警失败
安全配置错误
软件或数据完整性失败
注入攻击是最常见的安全漏洞类型之一。恶意输入——无论是代码、命令、查询还是脚本——被插入到程序或网页中,以发起恶意软件攻击、修改数据或窃取私密信息等。跨站脚本攻击、跨站请求伪造和服务器端请求伪造是一些常见的注入攻击。
跨站脚本攻击 (XSS) 是在受信任的网站上部署不受信任的代码或脚本,然后由不知情的用户执行。这通常发生在应用程序未能对用户提供的数据进行转义、过滤、清理或验证时。
跨站请求伪造(CSRF 或 XSRF)会从一个已认证的用户向网站发送未授权的请求。它利用网站对已认证用户网页浏览器的信任,通过链接或脚本诱使浏览器向目标网站发送恶意请求。
服务器端请求伪造 (SSRF) 会操纵发送到服务器的 URL。当服务器在未先验证 URL 的情况下接收被操纵的请求时,该请求可用于连接内部服务(如数据库)或读取文件、服务器配置及其他元数据。
不充分或无效的告警和日志可能导致攻击和泄露事件未被发现,使威胁参与者能够造成严重损害。日志记录与告警失败的一些实例包括:关键事件未被记录或记录不一致;日志存储不安全,可能容易被篡改或未经授权访问;对实时或近实时活跃攻击的告警不足;日志消息不清晰或缺乏细节及上下文;以及日志包含敏感数据但未进行脱敏或清洗。
这些失败涉及缺乏针对接受或处理来自外部来源的无效或不可信数据的防护措施。示例包括:自动应用软件更新而未验证其完整性;使用不可信来源的依赖项(如第三方库和插件);以及 CI/CD 流水线在未经验证的情况下拉取代码或其他软件开发工件。
获取有关最重要且最有趣的 AI 新闻的精选洞察分析。订阅我们的每周 Think 时事通讯。请参阅 IBM 隐私声明。
虽然 AI 编码助手可以自动化并加速软件开发,但它们仍然需要指导才能生成安全的代码。程序员必须提供清晰的 提示,不仅要指定功能,还要指定安全要求。例如,像“创建一个登录函数”这样的通用提示可以扩展为“创建一个检查用户输入是否符合预期格式和长度的登录函数”,以包含安全编码指令。开源安全基金会的指南 包含示例指令,以帮助 AI 助手考虑代码安全性。
软件工程团队还可以提供上下文,引导生成式 AI 生成更安全的代码。检索增强生成 (RAG) 将 AI 驱动的开发者工具与内部安全编码标准连接起来。对于没有定义指南的团队,Secure Code Warrior 的 AI 安全规则 可作为生成更安全的 AI 代码的起点。
与 AI 助手一样,AI 编码智能体也需要指导。CodeGuard 项目 提供了一个规则集和技能框架,将安全编码实践直接嵌入到智能体工作流中。AI 编码智能体可以在规划阶段将这些规则和技能作为其目标的一部分,并在执行阶段编写代码时使用它们。
人工智能本身生成的代码可能会引入漏洞,因此准确性和安全性的最终判断仍由人类程序员负责。生成式 AI 措施还必须与以下安全编码最佳实践相结合,以构建多层保护。
安全编码的最佳实践包含多种防御性编程策略,以增强软件安全性。企业可能担心在安全编码与交付速度之间取得平衡。但许多实践在不牺牲快速交付的情况下将安全性集成到代码中,例如将安全融入设计阶段、建立安全编码指南、培训开发者使其能够在编码时识别和修复安全缺陷,以及自动化代码分析和测试以发现漏洞。
虽然无法列举所有现有的安全编码最佳实践,但此列表可作为起点,结合这些实践可以增强组织的安全态势:
遵循安全编码标准
将安全融入设计
验证和净化输入并编码输出
实施强大的加密协议
进行身份验证和授权
建立健全的日志记录和安全的错误处理机制
全面安全测试
将安全作为代码审查的一部分
这些标准作为将安全编码技术有效集成到现有开发工作流中的基本指南。它们为跨软件项目的安全编程提供了共享的基线。
OWASP 开发者指南 是程序员参考的指南,帮助他们导航并编写安全的源代码。该指南概述了与技术无关的安全编码实践,并附有从已归档的 OWASP 安全编码实践快速参考指南中迁移过来的检查清单,突出关键代码安全要点。
OWASP 还提供了一系列速查表 ,用于实施安全编码原则并应对广泛的各种代码漏洞。
SEI CERT 编码标准 由卡内基梅隆大学的软件工程研究所创建,为 Android、C、C++、Java 和 Perl 编程语言提供安全编程指导。这些标准包含规则、建议以及合规代码和不合规代码的示例。规则和建议附有相应的风险评估,按严重性、可能性和修复成本进行分类,以帮助软件工程团队确定工作优先级。
将安全设计构建到系统蓝图中,符合将安全更早地引入软件开发过程的“左移”方法。它甚至在编写第一行代码之前就考虑如何使软件变得安全。
核心的安全编码原则是永不信任任何输入,注入攻击就证明了这一点。服务端验证和净化有助于确保输入在处理之前不存在安全风险。
软件工程团队可以将所有验证和净化逻辑放在一个安全的核心文件或位置中,以保持一致性并便于快速访问和更新。他们还可以使用编程语言和框架内置的验证和净化模块,但这些模块必须定期更新以应对新发现的漏洞。
输入验证用于检查数据类型、格式、长度、范围、尺寸及其他约束条件是否正确。这可能涉及将输入与允许的模式进行匹配,或将其与允许的字符集或值集进行比较。
输出编码使数据能够以文本形式安全显示,从而不会被解释为代码。许多框架自带默认的输出编码保护或自动编码和转义函数。OWASP Java Encoder 支持针对不同上下文的上下文相关输出编码,例如将变量放入 URL、内联 CSS 或内联 JavaScript 中,以及将变量插入 HTML 属性值、CSS 属性或两个 HTML 标签之间。
如果应用得当,加密技术可以保护信息的机密性、完整性和可用性。
程序员在加密传输中和静态存储的数据时,必须使用当前且强大的算法。AES 被公认为对称加密的黄金标准,其认证模式和 256 位密钥提供了高等级的安全性。对于非对称加密,使用安全曲线的 ECC 或启用随机填充且密钥至少为 2048 位的 RSA,可提供强健的安全性。
为了保护密码,必须应用哈希算法,并在哈希过程中向密码添加盐值(一个独特的、随机生成的字符串)。哈希算法是一种单向数学函数,它将数据转换为唯一的、更短的、固定长度的值,该值无法被解码或反向还原。现代哈希算法包括 Argon2id 和 scrypt。
开发者必须采用可靠、受支持且持续维护的加密库实现,例如 Bouncy Castle、Libsodium、OpenSSL 和 Tink,而不是自己创建加密算法。
密钥不得硬编码到源代码中、不得提交到版本控制系统、不得存储在环境变量中,也不得暴露在日志中。密钥管理解决方案和技术可以帮助自动化密钥管理生命周期——从生成、分发、存储到使用、轮换、撤销和销毁。
在传输层保护方面,软件工程团队必须使用诸如超文本传输安全协议 (HTTPS) 或 HTTP 严格传输安全协议 (HSTS) 以及最新版本的 TLS 等协议。必须禁用对敏感数据的缓存,并避免不必要地存储敏感数据。
身份验证与授权是验证实体身份并确保该实体拥有适当访问权限等级的关键安全编码实践。
一旦身份验证会话建立,就必须通过安全的会话 ID 或令牌来维护该会话。会话 ID 必须使用强密码学安全的伪随机数生成器生成。与任何其他用户输入一样,会话 ID 或令牌在处理之前必须经过验证,并滤除无效值。
为每个会话设置过期超时时间,可以限制恶意行为者劫持活动会话并发起攻击的持续时间。软件工程团队可以使用 Web 开发框架提供的内置会话管理功能。
程序员可以采用诸如 OAuth 等授权协议,该协议与 OIDC 身份验证协议协同工作。在访问控制方面,基于角色的访问控制 (RBAC) 是一种流行模型,用户根据其预定义角色被授予访问权限。其他可能更强大并支持更细粒度权限的选项包括基于属性的访问控制 (ABAC) 和基于关系的访问控制 (ReBAC)。ABAC 分析行为、对象和用户的属性(例如用户名、资源类型和时间点)以决定是否授予访问权限。ReBAC 根据资源之间的关系授予访问权限。
即使有了协议和访问控制模型,仍必须在每个请求上验证权限,并对实体尝试访问的每个对象执行访问控制检查。默认拒绝访问和应用最小权限也是授权方面至关重要的安全编码原则。
日志和错误信息可以成为帮助恶意行为者策划攻击的丰富信息源。这意味着日志和错误都必须谨慎处理。
应用程序错误、与配置更改及管理员或特权操作相关的系统事件,以及身份验证、授权、输入验证和会话管理领域的失败事件,都必须记录在日志中,因为这些可能表示入侵企图。必须包含足够的信息,例如用户详细信息(身份、角色和权限)以及错误或事件的上下文(目标、操作和结果),以辅助分析和调试。
日志必须写入只读介质,并存储在具有受限访问权限和内置篡改检测功能的安全位置。如果需要将日志发送到其他系统,则必须使用安全的传输协议。
敏感数据不得记录在日志中,必须从日志中清除或删除。任何其他被视为关键的信息,例如数据库连接字符串、文件路径、内部网络名称和地址、会话 ID 或令牌,都必须加密、哈希或脱敏处理。
日志库必须定期更新,以确保安全漏洞得到修补,正如影响广泛部署的开源 Log4j 日志库的 Log4Shell 漏洞所示,该漏洞允许黑客在受影响的系统上运行几乎任何他们想要的代码。
错误处理与日志记录相辅相成,因为有关错误的信息通常出现在日志中。而未处理的错误可能成为威胁参与者的入口点。
开发者可以考虑创建一个全局错误处理程序,为意外错误返回通用的响应或错误代码,然后在服务器端记录有关错误的更多详细信息。这样可以在安全处理错误的同时避免向黑客泄露信息,并为程序员提供必要的调查线索。
嵌入到源代码中的所有安全措施都必须经过验证。QA 和开发团队可以参考 OWASP 的 Web 安全测试指南 和应用程序安全验证标准 ,作为测试代码安全性的基础。自动化工具也可以辅助这一过程。
静态应用安全测试 (SAST) 应用预定义的规则来精确定位代码中表明可能存在漏洞的模式。SAST 有时被称为“白盒”测试,而 SAST 工具也被称为静态代码分析器,因为它们无需运行应用程序即可扫描代码。
SAST 工具擅长标记常见的代码漏洞,并能确定其所发现漏洞的确切行号和文件。它们还能与大多数 IDE 和 CI/CD 环境无缝集成。然而,它们容易产生误报。
动态应用程序安全测试 (DAST) 采用由外而内的方式,在应用程序的运行时环境中通过模拟攻击来评估应用程序,以模仿真实世界中威胁参与者的行为。因此,DAST 通常被称为黑匣,因为测试人员无需了解或访问系统的内部工作原理或源代码。DAST 通常比 SAST 产生更少的误报。
将 SAST 和 DAST 结合使用,可以更全面地揭示潜在漏洞。为了进行更全面的安全测试,SAST 和 DAST 可以与其他方法结合使用,例如交互式应用安全测试(IAST,它同时评估代码上下文和运行时行为以实时报告漏洞)和软件成分分析(SCA,它分析软件以确保其组件安全且为最新版本)。
大多数代码审查关注质量,检查代码是否符合风格指南、逻辑问题、最优流程以及测试和边缘情况的覆盖范围。但安全性也必须成为代码审查过程的一部分。
安全代码审查充当静态代码分析器之后的下一道防线。人工代码审查者提供领域专业知识、判断力以及对自动化工具常常遗漏的代码安全漏洞的洞察力。
为了采用更结构化的方法,代码审查者可以参考 OWASP 的安全代码审查速查表。
借助您的 AI 合作伙伴 Bob,加速软件交付,实现安全的意图感知型开发。
利用可信的 AI 驱动型工具优化软件开发工作,最大限度地减少编写代码、调试、代码重构或代码补全的时间,从而拓展创新空间。
通过增加 AI 重塑关键工作流程和运营,最大限度提升体验、实时决策能力和商业价值。