diff --git a/guide/SecureCoding.md b/guide/SecureCoding.md index 8693ca89944e37e54fdc6e5d2b38d137fa662825..28cec0f71c08bab8f9bc9ad044d78789e5c9d5e9 100644 --- a/guide/SecureCoding.md +++ b/guide/SecureCoding.md @@ -1,7 +1,3 @@ - - -**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* - - [1.代码风格](#1%E4%BB%A3%E7%A0%81%E9%A3%8E%E6%A0%BC) - [1.1 命名](#11-%E5%91%BD%E5%90%8D) - [NAM.01 使用统一的命名风格](#nam01-%E4%BD%BF%E7%94%A8%E7%BB%9F%E4%B8%80%E7%9A%84%E5%91%BD%E5%90%8D%E9%A3%8E%E6%A0%BC) @@ -118,7 +114,7 @@ - [AST.01 避免在代码中直接使用assert()](#ast01-%E9%81%BF%E5%85%8D%E5%9C%A8%E4%BB%A3%E7%A0%81%E4%B8%AD%E7%9B%B4%E6%8E%A5%E4%BD%BF%E7%94%A8assert) - [AST.02 禁止用断言检测程序在运行期间可能导致的错误,可能发生的错误要用错误处理代码来处理](#ast02-%E7%A6%81%E6%AD%A2%E7%94%A8%E6%96%AD%E8%A8%80%E6%A3%80%E6%B5%8B%E7%A8%8B%E5%BA%8F%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%9C%9F%E9%97%B4%E5%8F%AF%E8%83%BD%E5%AF%BC%E8%87%B4%E7%9A%84%E9%94%99%E8%AF%AF%E5%8F%AF%E8%83%BD%E5%8F%91%E7%94%9F%E7%9A%84%E9%94%99%E8%AF%AF%E8%A6%81%E7%94%A8%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86%E4%BB%A3%E7%A0%81%E6%9D%A5%E5%A4%84%E7%90%86) - [AST.03 禁止在断言内改变运行环境](#ast03-%E7%A6%81%E6%AD%A2%E5%9C%A8%E6%96%AD%E8%A8%80%E5%86%85%E6%94%B9%E5%8F%98%E8%BF%90%E8%A1%8C%E7%8E%AF%E5%A2%83) - - [AST.04 一个断言只用于检查一个错误](#ast04-%E4%B8%80%E4%B8%AA%E6%96%AD%E8%A8%80%E5%8F%AA%E7%94%A8%E4%BA%8E%E6%A3%80%E6%9F%A5%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF) + - [AST.04 一个断言只用于检查一个条件](#ast04-%E4%B8%80%E4%B8%AA%E6%96%AD%E8%A8%80%E5%8F%AA%E7%94%A8%E4%BA%8E%E6%A3%80%E6%9F%A5%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF) - [2.13 函数设计](#213-%E5%87%BD%E6%95%B0%E8%AE%BE%E8%AE%A1) - [2.13.1 输入校验](#2131-%E8%BE%93%E5%85%A5%E6%A0%A1%E9%AA%8C) - [FUD.01 对所有外部数据进行合法性检查](#fud01-%E5%AF%B9%E6%89%80%E6%9C%89%E5%A4%96%E9%83%A8%E6%95%B0%E6%8D%AE%E8%BF%9B%E8%A1%8C%E5%90%88%E6%B3%95%E6%80%A7%E6%A3%80%E6%9F%A5) @@ -1710,7 +1706,8 @@ C标准库,操作系统库,平台库,项目公共库,自己其他的依 ## 2.3 数据类型 - +**【备注】** +社区已有的数据类型有:数值类型、货币类型、布尔类型、字符类型、二进制类型、日期/时间类型、几何类型、网络地址类型、位串类型、文本搜索类型、UUID类型、JSON类型、对象标识符类型、伪类型、列存表支持的数据类型(详情请参见开发者指南数据类型章节)。 ### TYP.01 不要重复定义基础类型 @@ -5372,7 +5369,7 @@ ASSERT(close(fd) == 0); // fd被关闭 -### AST.04 一个断言只用于检查一个错误 +### AST.04 一个断言只用于检查一个条件 **【描述】** 为了更加准确地发现错误的位置,每一条断言只校验一个错误。 @@ -5415,12 +5412,7 @@ int Foo(int *array, size_t size) -### 2.13.1 输入校验 - - - - -#### FUD.01 对所有外部数据进行合法性检查 +### FUD.01 对所有外部数据进行合法性检查 **【描述】** 外部数据的来源包括但不限于:网络、用户输入、命令行、文件(包括程序的配置文件)、环境变量、用户态数据(对于内核程序)、进程间通信(包括管道、消息、共享内存、socket、RPC等,特别需要注意的是设备内部不同单板间通讯也属于进程间通信)、API参数、全局变量。 @@ -8199,55 +8191,97 @@ Linux下的/tmp目录是一个所有用户都可以访问的共享目录,不 ### MEM.01 禁止直接使用malloc申请内存,所以内存申请都需要通过palloc接口从内存上下文申请(工具除外) +**【正例】** +```c +char* Buffer = (char*)palloc(BUFFER_SIZE); +``` +**【反例】** +```c +char* Buffer = (char*)malloc(BUFFER_SIZE); +``` +### MEM.02 使用palloc申请内存时,确认通过MemoryContextSwitchTo切换到正确的内存上下文 -### MEM.02 使用palloc申请内存时,确认通过MemoryContextSwitchTo切换到正确的内存上下文下 - +**【正例】** +```c +MemoryContext oldContext = MemoryContextSwitchTo(u_sess->cache_mem_cxt); +char* Buffer = (char*)palloc(BUFFER_SIZE); +... +(void)MemoryContextSwitchTo(oldContext); +``` ### MEM.03 禁止直接从头TopMemoryContext(g_instance.instance_context,t_thrd.top_mem_cxt,u_sess->top_mem_cxt)上申请内存 - - +**【反例】** +```c +MemoryContext oldContext = MemoryContextSwitchTo(u_sess->top_mem_cxt); +char* Buffer = (char*)palloc(BUFFER_SIZE); +... +(void)MemoryContextSwitchTo(oldContext); +``` ### MEM.04 通过palloc申请的连续内存不能大于1GB,若超过1GB,请使用palloc_huge接口申请内存 - - +**【正例】** +```c +g_instance.ckpt_cxt_ctl->dirty_page_queue = (DirtyPageQueueSlot *)palloc_huge(CurrentMemoryContext, queue_mem_size); +``` ### MEM.05 u_sess->top_mem_cxt及其子内存上下文上申请的内存,禁止通过t_thrd下的变量引用 - +**【反例】** +```c +MemoryContext oldContext = MemoryContextSwitchTo(u_sess->cache_mem_cxt); +t_thrd.log_cxt.plog_md_read_entry = (char*)palloc0(PLOG_ENTRY_MAX_SIZE); +... +(void)MemoryContextSwitchTo(oldContext); +``` ### MEM.06 t_thrd.top_mem_cxt及其子内存上下文上申请的内存,禁止通过u_sess下的变量引用 - - +**【反例】** +```c +u_sess->storage_cxt.LocalBufferDescriptors = (BufferDesc*)MemoryContextAllocZero(THREAD_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), (unsigned int)nbufs * sizeof(BufferDesc)); +``` ### MEM.07 申请的内存需要通过pfree,MemoryContextDelete,MemoryContextReset接口及时释放 - +**【正例】** +```c +MemoryContext oldContext = MemoryContextSwitchTo(u_sess->cache_mem_cxt); +char* Buffer = (char*)palloc(BUFFER_SIZE); +... +(void)MemoryContextSwitchTo(oldContext); +... +pfree(Buffer); +//or +MemoryContextDelete(top_transaction_mem_cxt); +``` ### MEM.08 如果需要使用类,需要继承BaseObject类,创建对象是通过接口 New(ContextName) ClassName(..) - - - - -### MEM.09 禁止使用c++ STL模板库 - - +**【正例】** +```c +New(ContextName) ClassName(..) +class ThreadPoolListener : public BaseObject { +... +} +m_listener = New(CurrentMemoryContext) ThreadPoolListener(this); +... +delete m_listener; +``` @@ -8365,8 +8399,14 @@ catch(std::bad_alloc) } ``` +### C++.08 禁止使用c++ STL模板库 - +**【反例】** +```c +Map indexMap; +indexMap[1]=2; +... +``` ## 2.18 其它 diff --git a/guide/SecurityDesign.md b/guide/SecurityDesign.md index 2af7d5af7ebdedc899a21294076c4e74da6741cd..fe264814cce9261879d538c2df70aeb7d911244d 100644 --- a/guide/SecurityDesign.md +++ b/guide/SecurityDesign.md @@ -54,22 +54,19 @@ ## 4. 数字证书管理 4.1 使用安全随机数生成密钥对,且必须使用至少2048位的RSA密钥对(第三方CA签发证书、与第三方系统对接、兼容老版本等场景可例外)。 -**说明**:在生成密钥对时如果使用不安全的随机数会导致密钥容易被猜测,影响密钥的安全性,所以在生成密钥对时,应使用密码学意义上的安全随机数,保证密钥对的不可预测性。如果产品支持使用硬件随机数接口宜尽量使用硬件接口来产生随机数。 +**说明**:在生成密钥对时如果使用不安全的随机数会导致密钥容易被猜测,影响密钥的安全性,所以在生成密钥对时,应使用密码学意义上的安全随机数,保证密钥对的不可预测性。如果产品支持使用硬件随机数接口宜尽量使用硬件接口来产生随机数。 ## 5. 会话管理 5.1 系统应支持“根据帐号、角色、IP地址、时间等特征来确定是否允许通过认证建立认证后的会话”。 **说明**:防止资源被非必须因素占用;防止非工作时间黑客攻击系统。 -5.2 服务器需要结合sessionid、IP地址以及其他的会话信息对每一个会话进行身份校验,判断该会话是否合法。 -**说明**:防止攻击者使用窃取的会话标识冒充用户。 - -5.3 管理员能查看到当前已成功建立会话的用户信息并能够终止指定用户会话。 +5.2 管理员能查看到当前已成功建立会话的用户信息并能够终止指定用户会话。 **说明**:如果黑客攻击成功可以有办法对其进行制止。 -5.4 当服务器检测到非法会话,则服务器拒绝响应或返回到认证界面,同时需要记录安全日志。 +5.3 当服务器检测到非法会话,则服务器拒绝响应或返回到认证界面,同时需要记录安全日志。 **说明**:防止攻击者使用窃取的会话标识冒充用户。 -5.5 必须设置会话超时机制,在超时过后必须要清除该会话信息。 +5.4 必须设置会话超时机制,在超时过后必须要清除该会话信息。 **说明**:及时回收资源,减少会话劫持的时间窗;会话超时默认指会话空闲超时机制,当会话空闲超过一定时间后,系统应该注销当前会话;会话固定超时机制是指系统在创建会话时,设定了会话的最大可用时间;会话更新超时机制是指会话创建后经过指定的更新超时时间,由系统对当前的会话ID进行更新。 ## 6. 密码算法 @@ -77,10 +74,18 @@ **说明**:私有的非标准的算法不被业界公知和信任,可能存在算法缺陷,无法起到对数据加密保护的作用。 6.2 禁止使用业界已知不安全的加密算法,推荐使用强密码算法。 -**说明**:弱密码算法已经被密码分析者破解或者部分破解,使用不再安全的算法无法起到对数据加密保护的作用。 +**说明**:弱密码算法已经被密码分析者破解或者部分破解,使用不再安全的算法无法起到对数据加密保护的作用。 +**事例**: +| 用途 | 不安全密码算法 | 推荐的强密码算法 | +|-|-|-| +| 对称加密| 分组加密:Blowfish, DES, DESX, RC2, Skipjack, 2TDEA, TEA, 3DES / 流加密:SEAL, CYLINK_MEK, RC4 | 分组加密:AES-GCM(≥128 bits) / 流加密:AES-CTR(≥128 bits), AES-OFB(≥128 bits), chacha20-poly1305 | +| 哈希算法 | SHA0, MD2, MD4, MD5, SHA1(数字签名、Hash-only场景),RIPEMD, RIPEMD-128 | SHA256或以上, SHA3-256或以上 | +| 非对称加密 | RSA (< 2048 bits), ECIES (< 224bits) | RSA(≥3072 bits), ECIES (≥256 bits) | +| 数字签名 | RSA (< 2048 bits), DSA (同X9.42标准DH), ECDSA(<224bits) | RSA(≥3072 bits), DSA(同X9.42标准DH), ECDSA(≥256 bits), EdDSA(≥256 bits) | +| 密钥协商 | DH:L<2048 bits, N*<224 bits / ECDH: ECDH(< 224bits) | DH:L≥3072 bits, N≥256 bits / ECDH: ECDH(≥256 bits) | 6.3 密码算法中使用到的随机数必须是密码学意义上的安全随机数。 -**说明**:随机数是密码学的基础,密钥的随机性确保攻击者无法猜测密钥,也就无法解密密文;盐值的随机性确保攻击者无法执行预计算操作,也就无法构造彩虹表进而还原口令明文;IV的随机性确保攻击者无法找出密文的统计学特性,也就无法进行密文替换攻击或注入攻击。如果随机性无法保证,上面提到的各种攻击都能奏效,系统的安全性就会受到极大威胁。 +**说明**:随机数是密码学的基础,密钥的随机性确保攻击者无法猜测密钥,也就无法解密密文;盐值的随机性确保攻击者无法执行预计算操作,也就无法构造彩虹表进而还原口令明文;IV的随机性确保攻击者无法找出密文的统计学特性,也就无法进行密文替换攻击或注入攻击。如果随机性无法保证,上面提到的各种攻击都能奏效,系统的安全性就会受到极大威胁。推荐的安全随机数生成器:OpenSSL1.1.X的RAND_pri_bytes、OpenSSL FIPS模块中实现的DRBG、JDK的java.security.SecureRandom等。典型的不安全随机数生成器:C标准库函数random()、rand()、Java的java.util.Random。 6.4 对口令进行单向哈希时,必须使用基于口令的密钥派生算法。 **说明**:单纯的口令哈希值,无法防止彩虹表攻击。哈希加盐可以防止彩虹表攻击,但无法防止暴力攻击,安全性仍不足,标准的基于口令密钥派生算法考虑了彩虹表攻击和暴力攻击的防范,更为安全。 @@ -92,9 +97,15 @@ 7.2 密钥的用途需单一化,即一个密钥应只用于一种用途。 ## 8. 隐私保护 -8.1 用于问题定位的日志中记录个人数据遵循最小化原则 +8.1 禁止在未经授权(签订数据转移协议或获得客户的明确同意等)前进行个人数据转移,产品出于定位问题目的从客户网络导出包含个人数据的数据时须对个人数据进行过滤、或匿名化或假名化处理。 + +8.2 涉及个人数据的采集/处理的功能须提供安全保护机制(如认证、权限控制、日志记录等),并通过产品资料向客户公开。 + +8.3 收集或使用个人数据前,必须明确提示用户,并获得用户的同意,并且允许用户随时关闭对个人数据的收集和使用。 + +8.4 个人数据收集范围、使用目的不得超出隐私声明,且遵循最小化原则,当个人数据的采集范围、使用目的发生变更时,应及时更新隐私声明。 **说明**:防止日志中存放了个人数据,但是日志本身的安全性保障不足,导致个人数据泄露。 ## 9. 日志审计 -9.1 日志内容要能支撑事后的审计,记录内容至少包括用户ID、时间、事件类型、被访问资源的名称、访问发起端地址或标识、访问结果。 +9.1 管理面所有对系统产生影响的用户活动、操作指令必须记录日志,日志内容要能支撑事后的审计,记录包括用户ID、时间、事件类型、被访问资源的名称、访问发起端地址或标识、访问结果等;日志要有访问控制,应用系统禁止提供手动删除、修改审计日志的能力。 **说明**:可以帮助回溯历史操作,提高现网问题定位的效率。 \ No newline at end of file