Python通用编程规范-09 安全编程规范

本文详细介绍了Python编程中关于异常处理、运行环境和其他安全方面的重要规范。禁止异常抑制,避免在异常中泄露敏感信息,确保方法异常时恢复对象状态,生产代码移除调试入口点,使用标准API而非系统命令,避免第三方源下载软件包,不在日志中保存敏感信息,不硬编码敏感信息,使用安全随机数,以及在代码发布前记录开发者信息和注释,对外来数据进行转义处理,以增强代码的安全性和可靠性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

9.1 异常行为

9.1.1 禁止抑制或者忽略已检查异常

说明: 编码人员常常会通过一个空的或者无意义的except块来抑制捕获的已检查异常。每一个except块都应该确保程序只会在继续有效的情况下才会继续运行下去。因此,except块必须要么从异常情况中恢复,要么重新抛出适合当前except块上下文的另一个异常以允许最邻近的外层try-except语句块来进行恢复工作。异常会打断应用原本预期的控制流程。例如,try块中位于异常发生点之后的任何表达式和语句都不会被执行。因此,异常必须被妥当处理。许多抑制异常的理由都是不合理的。例如,当对客户端从潜在问题恢复过来不抱期望时,一种好的做法是让异常被广播出来,而不是去捕获和抑制这个异常。

# 【错误示例】: 下面代码假设获取客户端输入的Email地址,在使用之前对Email进行数据格式的合法性校验。
try:
    # to_do
    pass
except Exception as ex:
    import traceback

    traceback.print_exc()
# 错误示例中, except 块只是简单地将异常堆栈轨迹打印出来。
# 虽然打印异常的堆栈轨迹对于定位问题是有帮助的,但是最终的程序运行逻辑等同于抑制异常。
# 注意,即使这个错误示例在发生异常时会打印一个堆栈轨迹,但是程序会继续运行,如同异常从未被抛出过。
# 换句话说,除了try块中位于异常发生点之后的表达式和语句不会被执行之外,发生的异常不会影响程序的其他行为。

# 【正确示例1】:
validFlag = False
while not validFlag:
    try:
        # If requested file does not exist, throws FileNotFoundException
        # If requested file exists, sets validFlag to true
        validFlag = True
        pass
    except FileNotFoundException:
        import traceback
        traceback.print_exc()


# 【正确示例2】:
# 继承Exception Reporter并过滤敏感异常。有时候异常必须对用户隐藏。
# 在这种情况下,一种可行的方式是继承Exception类,并且在重写默认的str方法的基础上,增加一个filter()方法。
class MyExceptionReporter(Exception):
    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return filter(self.msg)

    def filter(self):
        # Sanitize sensitive data or replace sensitive exceptions with non-sensitive exceptions (whitelist)
        # Return non-sensitive exception
        pass

例外情况:

  1. 在资源释放失败不会影响程序后续行为的情况下,释放资源时发生的异常可以被抑制。释放资源的例子包括关闭文件、网络套接字、线程等等。这些资源通常是在except或者fianlly块中被释放,并且在后续的程序运行中都不会再被使用。因此,除非资源被耗尽,否则不会有其他途径使得这些异常会影响程序后续的行为。在充分处理了资源耗尽问题的情况下,只需对异常进行净化和记录日志(以备日后改进)就足够了;在这种情况下没必要做其他额外的错误处理。
  2. 如果在特定的抽象层次上不可能从异常情况中恢复过来,则在那个层级的代码就不用处理这个异常,而是应该抛出一个合适的异常,让更高层次的代码去捕获处理,并尝试恢复。对于这种情况,最通常的实现方法是省略掉except语句块,允许异常被广播出去。

9.1.2 禁止在异常中泄露敏感信息

说明: 敏感数据的范围应该基于应用场景以及产品威胁分析的结果来确定。典型的敏感数据包括口令、银行账号、个人信息、通讯记录、密钥等。如果在传递异常的时候未对其中的敏感信息进行过滤常常会导致信息泄露,而这可能帮助攻击者尝试发起进一步的攻击。攻击者可以通过构造恶意的输入参数来发掘应用的内部结构和机制。不管是异常中的文本消息,还是异常本身的类型都可能泄露敏感信息。例如,对于IOError异常,其中的异常消息会透露文件系统的结构信息,而通过异常本身的类型,可以得知所请求的文件不存在。因此,当异常会被传递到信任边界以外时,必须同时对敏感的异常消息和敏感的异常类型进行过滤。

# 【错误示例】:
import sys
if len(sys.argv) != 2:
    print("Invalid file")
else:
    try:
        open(sys.argv[1], "r")
    except MyError as e:
        # Log the exception
        pass
# 如果传入一个文件名后,程序返回一个异常,则暗示该文件不存在,而如果不抛出异常则说明该文件是存在的。
# 使得系统面临暴力攻击的风险,攻击者可以多次传入不同的文件名进行暴力碰撞来发现有效文件。

# 【正确示例】:
import sys
if len(sys.argv) != 2:
    print ("Invalid file")
else
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值