C语言安全编码指南:MISRA C、CERT C、CWE 与 C Secure 标准对比与Perforce QAC应用详解
如今,软件安全是重中之重。任何的安全漏洞都不能被忽视——尤其是开发嵌入式系统软件时,您的代码必须安全可靠,且没有编码错误。 提及软件安全,您可能想到的是密码和访问控制,或者是病毒、欺骗攻击(spoofing)和网络钓鱼攻击,这些是常见的安全问题。而数据加密和身份验证协议等安全功能可以缓解这些漏洞。 但即使已经实施了这些安全功能,软件仍可能受到攻击。 为确保软件安全,您需要从源头——代码层面——进行着手。否则,编码错误将会危及您的应用程序。 据软件工程研究所(SEI)估计,高达90%的已报告安全事件是源于软件代码或设计中的漏洞被利用。这些漏洞使黑客能够访问私人数据或未经授权的控制系统。 可见,一个简单的编码错误就可能引发黑客攻击威胁——黑客可能会控制您的计算机、智能家居设备、家庭娱乐设备甚至是汽车。更糟糕的是,黑客甚至可能控制核电站 为说明这种情况可能如何发生,我们来看一个例子。缓冲区溢出是C语言编程中常见的安全漏洞。 当数据被写入到已分配内存的边界之外时,就会发生缓冲区溢出。 例如: 此处声明了一个10字节的数组(索引范围0到9)。但程序随后试图向数组边界外的一个字节写入字符。若程序后续使用了数组相邻的内存区域,则会导致意外行为。 这已经够糟糕了,而情况可能会进一步恶化——缓冲区溢出可能使黑客获得系统控制权。 黑客可以利用缓冲区溢出漏洞进行攻击,致使程序崩溃、数据损坏,或直接窃取信息。 程序运行时会使用一块称为“栈”的内存区域。当前执行函数作用域内的变量将存储在栈中。函数调用的地址也会被存储,以便返回语句能返回到正确的位置。 当函数返回到调用函数时,程序将从上次中断的地方继续执行。因此,如果栈中的返回地址被篡改为指向某些恶意的替代指令,那么,这些指令将在函数返回时被执行。 如果程序正在接收数据——且未设置检查机制来确保输入缓冲区不会溢出——那么就有可能设计一个包含恶意代码的输入或“有效负载”。这种恶意代码会溢出输入缓冲区,并将栈中的返回地址覆盖为恶意代码的地址。 预防缓冲区溢出等安全漏洞至关重要。而实现这一目标的方法,就是确保在编码时就杜绝可被利用的漏洞。 毕竟,如果窗户敞开着,加装再坚固的门锁也毫无意义。因此,提高安全性的关键,就是确保代码安全。 编写安全的代码至关重要。在C语言编程中,有四个关键信息来源可帮助您确保代码安全。 您可以从通用缺陷枚举(CWE)中识别安全弱点。 什么是CWE? CWE是由社区开发的C语言常见软件安全弱点列表,由MITRE公司维护。该列表可用作弱点识别、缓解和预防的基线。 CWE软件安全弱点列表 CWE列表对弱点进行了优先级排序。其中的“Top 25”(前25)条是综合了二十多个不同机构的意见评选出来的。他们根据弱点出现的频率和重要性对其进行评估。CWE中列出的(C语言程序中的)许多弱点都与缓冲区溢出有关。 这份Top 25列表还附带了一组有效的“强效缓解措施”。这些措施可帮助开发者减少甚至彻底消除Top 25中的整类安全弱点,同时也有助于应对CWE列表中记录的其他800多个弱点。 CWE致力于从源头遏制漏洞,其实现方式是教育设计人员、程序员和测试人员如何在软件发布前就消除常见错误。 您可以将CERT C编码标准应用于您的代码。 什么是CERT C? CERT C编码标准由软件工程研究所(SEI)的CERT部门发布。SEI是卡内基梅隆大学运营的研发中心,它的资金主要来源于美国国防部和国土安全部。 CERT C安全规则 安全编码专家会持续在维基平台上完善CERT C指南。每项指南包括: – 标题 – 描述 – 不合规代码示例 – 合规解决方案示例 该指南涵盖编码和实现错误,以及低级设计错误。其目标是消除不安全的编码实践和可能导致漏洞的未定义行为。 缺陷可能较为轻微,也可能不会影响软件的性能或运行结果,但它仍可能被攻击者利用,从而导致重大的安全漏洞。 您可以应用ISO/IEC TS 17961:2013 “C Secure” 编码规则。 什么是ISO/IEC TS 17961:2013? ISO/IEC TS 17961:2013制定了一套编码规则,这些规则使静态代码分析工具能够诊断超出语言标准要求的不安全代码。 C Secure编码规则 ISO/IEC TS 179671:2013包含了C语言安全编码的规则,每条规则都包含示例。 C Secure旨在制定可以自动强制执行的安全编码规则,用于检测C语言编程中的安全缺陷。要被视作安全缺陷,软件漏洞必须能被恶意用户或攻击者的行为触发。 实施这些规则的分析工具必须能够有效发现安全编码错误,且不会产生过多的误报。 您也可以使用MISRA来确保C语言的安全编码。 什么是MISRA? MISRA为安全相关系统的开发提供最佳实践指南。其C语言编码标准已被多个行业广泛采用。 MISRA C 安全规则 MISRA C:2012 修订版1于2016年发布。该版本为C语言编程提供了额外的安全指南,包括新的规则和指令,并附有合规和不合规的代码示例。 这些指南可用于预防导致安全问题和安全漏洞的编码错误。 MISRA C安全规则是嵌入式系统的理想选择。这是因为MISRA C的安全性可与其它C语言安全编码标准相媲美。此外,MISRA C在嵌入式系统行业中深受信赖,更是汽车行业首选的编码标准。 MISRA C安全规则可防止编码错误和安全漏洞,例如缓冲区溢出。 以下是MISRA C安全规则的示例: 此规则与以下CERT C规则作用相同: 两者都与C语言中的多个CWE漏洞相关,其中之一是: 遵循MISRA C规则或CERT规则可确保代码安全,并规避CWE中的常见漏洞。这是因为写入越界指针(或指针操作数)可能导致缓冲区溢出,从而产生易受攻击的代码;而读取越界指针(或指针操作数)则可能意外泄露信息给黑客。 因此,通过确保遵循这些规则,将避免严重的编码错误。您可以使用静态代码分析工具(如Perforce QAC)来强制执行MISRA和CERT规则。 MISRA C编码标准也适用于软件安全性比功能安全性更受重视的环境。 事实上,MISRA针对MISRA C:2012标准发布了两个附录,以帮助开发者将MISRA规则映射到C Secure和CERT C标准。 MISRA C:2012 – 附录2展示了每条MISRA规则如何映射到ISO/IEC TS 17961:2013中的C Secure规则。 C Secure中的每条规则都对应MISRA C中的一条规则或指令。任何完全支持MISRA C的静态代码分析工具(如Perforce QAC),也将符合C Secure标准。因此,您可以灵活互换使用这些标准以确保安全。 MISRA C:2012 – 附录3展示了每条规则如何映射到CERT C规则。 MISRA C对CERT C的覆盖:60%规则,20%指令,15%超出范围,5%未覆盖。 CERT C是为C11设计的。MISRA C:2012是为C99设计的。 在CERT C规范中,有15条特定于C11的规则超出了MISRA C:2012的范围。而在(MISRA C:2012范围内的)CERT C规则中,只有四条未被覆盖。因此,MISRA C覆盖了CERT C中的大部分安全规则。 注:使用Perforce QAC可自动检测这四条规则的全部违规情况。 MISRA编码标准为确保C语言代码的安全性提供了一套最佳实践准则。采用MISRA安全规则是保障软件整体安全性的明智之选。 如果您需要采用一种编码标准,以增强对软件安全性的信心,建议考虑MISRA C标准。该C语言编码规范内容全面,并已在安全与关键任务项目中被证明行之有效。 您可以借助Perforce QAC 自动执行MISRA规则(适用于C或C++语言),这将大幅减少手动代码审查所需的时间,从而释放开发资源,确保项目按时交付,同时提升软件质量。 Perforce QAC 主要通过以下机制帮助开发人员高效编写安全代码: Perforce中国授权合作伙伴——上海龙智编码错误危及软件安全
安全漏洞示例:C语言中的缓冲区溢出
为说明这种情况可能如何发生,我们来看一个例子。缓冲区溢出是C语言编程中常见的安全漏洞。char buff[10];
buff[10] = 'a';缓冲区溢出如何招致黑客攻击?
预防安全漏洞至关重要
确保C语言代码安全的四种方法
1. CWE
2. CERT C
CERT C将漏洞定义为:一组允许攻击者违反明确或隐含安全策略的条件。
3. ISO/IEC TS 17961:2013 "C Secure"
4. MISRA C
为什么MISRA C安全规则是嵌入式系统的理想选择?
MISRA C安全规则示例
MISRA C 规则 18.1
“对指针操作数进行算术运算后得到的指针,其地址应指向与该指针操作数相同的数组内的元素。”
ARR30-C
“请勿创建或使用越界指针或数组下标。”
CWE-119:对内存缓冲区边界内的操作限制不当
“该软件在内存缓冲区上执行操作,但可能读取或写入超出缓冲区预期边界范围的内存位置。”
MISRA C与其他标准的比较


将MISRA安全规则应用于您的代码
使用Perforce QAC编写安全代码
1. 精准定位违规代码,即时修复
2. 风险分级,聚焦核心
3. 闭环管理,审计无忧