CANN Python 安全编码规范

适用场景:Python 代码(测试脚本、工具脚本等)

说明:Python 安全编码规范适用于所有 Python 代码,包括测试脚本、工具脚本等。

快速索引

规范编号 规范名称 类别 严重级别
1.1 文件头注释包含 COPYRIGHT 和 LICENSE 声明 文件头
2.1 除法和模运算除零保护 数值安全
3.1 禁止通过异常泄露敏感数据 异常处理
4.1 产品代码不要包含调试入口点 调试与隐私
4.2 正式代码不包含个人隐私信息 调试与隐私
4.3 禁止包含未公开的公网地址 调试与隐私
4.4 禁止在界面、日志中暴露不必要信息 调试与隐私
5.1 创建文件时指定合适权限 文件操作
5.2 外部文件路径必须校验和规范化 文件操作
5.3 禁止使用 tempfile.mktemp 文件操作
5.4 临时文件使用完毕及时删除 文件操作
5.5 解压文件必须进行安全检查 文件操作
6.1 禁止使用 pickle.load 加载外部数据 序列化
6.2 禁止序列化未加密的敏感数据 序列化
6.3 禁止使用 yaml.load 函数 序列化
6.4 禁止使用 jsonpickle 模块 序列化
7.1 禁止使用 eval 和 exec 执行不可信代码 命令执行
7.2 禁止使用 OS 命令解析器调用系统命令 命令执行
7.3 避免在命令解析器中使用通配符 命令执行
7.4 禁止使用 subprocess 的 shell=True 命令执行
8.1 外部数据禁止使用 .format() 格式化 格式化
8.2 禁止直接使用外部数据拼接 XML XML安全
8.3 禁止解析不可信的 XML 实体 XML安全
9.1 禁止直接使用外部数据记录日志 日志安全
9.2 禁止在生产代码中使用 assert 日志安全
10.1 敏感对象发送出信任区域前签名加密 密码学
10.2 安全场景必须使用安全随机数 密码学
10.3 必须使用 SSLSocket 进行安全数据交互 网络安全

说明

本规范是 CANN 开源社区的 Python 安全编码规范,涉及数值运算安全、输入与数据验证、文件与系统操作安全、加密与通信安全、特定格式处理安全、隐私保护等。

适用范围

CANN 相关开源仓的 Python 代码安全检视。


1. 文件头注释

规则 1.1 文件头注释应该包含COPYRIGHT和LICENSE声明

**【描述】**在每个源文件的开头添加COPYRIGHT和LICENSE声明,确保代码的合法性和可追溯性。这有助于保护代码的知识产权,并明确使用条款。

举例:

#
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
# This file is a part of the CANN Open Software.
# Licensed under CANN Open Software License Agreement Version 1.0 (the "License").
# Please refer to the License for details. You may not use this file except in compliance with the License.
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
# See LICENSE in the root of the software repository for the full text of the License.
#

2. 数值运算安全

规则 2.1 对除法运算和模运算中的除数为0的情况做相应保护

**【描述】**在进行除法运算或取模运算时,应先检查除数是否为0,以防止程序因除零错误而崩溃。可以通过条件语句或异常处理来实现。


3. 异常处理

规则 3.1 禁止通过异常泄露敏感数据

**【描述】**在捕获和处理异常时,不应将敏感数据(如密码、密钥等)包含在异常消息中,以防止这些信息被意外泄露。


4. 调试与隐私

规则 4.1 产品代码不要包含任何调试入口点

**【描述】**发布的产品代码中不应包含用于调试的入口点或特殊功能,以确保代码的安全性和稳定性。调试代码应在开发环境中单独管理。

规则 4.2 正式发布的代码及注释内容要合法合规,不要有个人隐私信息

**【描述】**正式发布的代码和注释内容要合法合规;不应包含开发者的个人隐私信息(如身份证号码、手机号码等),以保护个人隐私。

规则 4.3 代码中禁止包含用户界面不可见、或是资料未公开的公网地址

**【描述】**代码中不应硬编码公网地址,以防止因地址变更导致的问题或因公网地址引起的质疑。对于公开的公网地址应该存储在配置文件或数据库中。

**【例外】**对于标准协议中必须指定公网地址的场景例外。

规则 4.4 禁止在用户界面、日志中暴露不必要信息

**【描述】**在用户界面和日志中不应暴露不必要的信息,特别是敏感信息,以防止信息泄露和滥用。


5. 文件操作安全

规则 5.1 在多用户系统中创建文件时应根据需要指定合适的权限

**【描述】**在多用户系统中创建文件时,应根据实际需求设置合适的文件权限,以确保文件的安全性和访问控制。

规则 5.2 使用外部数据构造的文件路径前必须进行校验,校验前必须对文件路径进行规范化处理

**【描述】**在使用外部数据生成文件路径之前,应对路径进行规范化处理(如去除多余的路径分隔符),并进行校验,以防止路径遍历攻击。

规则 5.3 禁止使用tempfile.mktemp创建临时文件

【描述】tempfile.mktemp 函数存在安全风险,因为它不会创建文件,只返回一个路径,可能导致竞态条件。应使用 tempfile.TemporaryFiletempfile.NamedTemporaryFile 来创建临时文件。

规则 5.4 临时文件使用完毕应及时删除

**【描述】**临时文件在使用完毕后应立即删除,以释放系统资源并防止数据泄露。

规则 5.5 解压文件必须进行安全检查

**【描述】**在解压文件之前,应对压缩文件进行安全检查,确保其中不包含恶意文件或路径遍历攻击。


6. 序列化与反序列化

规则 6.1 禁止使用pickle.load、_pickle.load和shelve模块加载外部数据

【描述】pickleshelve 模块存在安全风险,因为它们可以执行任意代码。应使用更安全的序列化方法,如 json

规则 6.2 禁止序列化未加密的敏感数据

**【描述】**在序列化敏感数据时,应使用加密算法进行加密,以防止数据在传输过程中被窃取。

规则 6.3 禁止使用yaml模块的load函数

【描述】yaml.load 函数存在安全风险,因为它可以执行任意代码。应使用 yaml.safe_load 来替代。

规则 6.4 禁止使用jsonpickle模块的encode/decode或dumps/loads函数

【描述】jsonpickle 模块存在安全风险,因为它可以执行任意代码。应使用更安全的序列化方法,如 json


7. 命令执行安全

规则 7.1 禁止使用eval和exec函数执行不可信代码

【描述】evalexec 函数可以执行任意代码,存在严重的安全风险。应避免使用这些函数处理不可信的数据。

规则 7.2 禁止使用OS命令解析器或"危险函数"调用系统命令

**【描述】**应避免使用 os.systemos.popen 等函数直接调用系统命令,因为它们存在注入攻击的风险。应使用 subprocess 模块的更安全方法。

规则 7.3 避免在命令解析器中使用通配符

**【描述】**在命令解析器中使用通配符(如 *)可能会导致意外的行为和安全问题。应尽量避免使用通配符,明确指定文件名或路径。

规则 7.4 禁止使用subprocess模块中的shell=True选项

【描述】subprocess 模块的 shell=True 选项会通过系统 shell 执行命令,存在注入攻击的风险。应使用 shell=False 并传递命令列表。


8. 格式化与XML安全

规则 8.1 不受信任的外部数据禁止使用.format()进行格式化

**【描述】**在使用 str.format 方法时,应避免使用不受信任的外部数据,以防止格式字符串注入攻击。可以使用 f-stringstr.format_map 方法。

规则 8.2 禁止直接使用外部数据来拼接XML

**【描述】**直接使用外部数据拼接 XML 可能会导致 XML 注入攻击。应使用 XML 库提供的安全方法来构建 XML 文档。

规则 8.3 禁止在处理XML数据时解析不可信的实体

**【描述】**在处理 XML 数据时,应禁用外部实体解析,以防止 XXE(XML External Entity)攻击。


9. 日志安全

规则 9.1 禁止直接使用外部数据记录日志

**【描述】**直接使用外部数据记录日志可能泄露敏感信息。应对外部数据进行过滤和清理后再记录日志。

规则 9.2 禁止在生产版本的业务代码中使用assert

【描述】assert 语句在生产环境中会被忽略,不应依赖于 assert 进行错误处理。应使用条件语句和异常处理来确保代码的健壮性。


10. 密码学与网络安全

规则 10.1 将敏感对象发送出信任区域前进行签名并加密

**【描述】**在将敏感对象发送到非信任区域(如网络传输)之前,应对其进行数字签名和加密,以确保数据的完整性和保密性。

规则 10.2 安全场景下必须使用密码学意义上的安全随机数

**【描述】**在涉及安全性的场景中(如生成密钥、令牌等),应使用密码学安全的随机数生成器,以防止被预测和攻击。

规则 10.3 必须使用ssl.SSLSocket代替socket.Socket来进行安全数据交互

**【描述】**在进行网络通信时,应使用 ssl.SSLSocket 而不是普通的 socket.Socket,以确保数据传输的安全性。