📜  格式化参数的可疑参数类型 (1)

📅  最后修改于: 2023-12-03 14:55:41.158000             🧑  作者: Mango

格式化参数的可疑参数类型

在进行字符串格式化时,程序员需要非常注意传递的参数类型。如果传递的参数类型与预期不符,就会发生程序错误或安全漏洞。其中,格式化参数的可疑参数类型尤其需要重视。

##何谓格式化参数的可疑参数类型?

格式化字符串时使用的 % 符号,是格式化参数的标记,有多种格式化标记可供选择,如 %d、%s、%f 等。这些标记会告诉编译器该用什么类型的数据格式填充到字符串中。而在 Python 的字符串格式化中,我们通常会使用 str.format() 函数,它可以传入多个参数进行格式化,但是亦有不完全遵循语法规则的情况,譬如只传入了一个参数或传入了多个超过对应格式标记数目的参数。这其中就存在着格式化参数的可疑类型。例如下面的代码段:

url = "http://www.{0}.{1}".format("example", "com", "extra")
print(url)

在这个代码段中,虽然使用了花括号标记的格式化字符串,但是在使用 str.format() 函数时,却不小心传入了额外的参数,这个错误在编译期并不会报错,而是在运行时抛出异常。这种情况就是“格式化参数的可疑参数类型”。

事实上,任何不符合格式化字符串规则的参数类型,都是可疑参数类型。

可疑参数类型的危害

恶意攻击者可以利用可疑参数类型进行字符串格式化攻击,从而破坏系统的安全性。

例如,如果在格式化字符串中,使用了 %s 标记表示将字符串格式的数据填充到字符串中,但是传入的实参中是整数类型时,可能会引发隐患。攻击者可以通过精心的构造,传入一些非法数据,从而触发错误并破坏系统。

如何避免可疑参数类型?

为了避免可疑参数类型造成的安全问题,我们应该提高对格式化字符串的使用规范性,保证参数与标记的一一对应,并尽量约束可传入参数的类型。

###使用 f-string 进行格式化

Python 3.6 之后,推出了 f-string 格式化字符串功能,使用起来更为方便、直观,同时还强制要求参数类型与标记一一对应,从而避免了可疑参数类型。

name = "alice"
age = 18
print(f"My name is {name}, and I am {age} years old.")

对比上述示例和之前的示例,可以发现在 f-string 中,变量使用花括号括起来,而不加 % 标记符。此外,在 {} 中也可以加入表达式以及函数,更具灵活性,还可以直接调用对象的 str() 方法,使代码可读性更强。

###使用类型约束标注

Python 提供了类型约束标注的方式,可以在函数或方法中约束参数类型。在使用格式化字符串时,如果有严格的类型约束,就可以避免可疑参数类型的问题。

def create_url(domain: str, suffix: str) -> str:
    return "http://www.{}.{}".format(domain, suffix)

在上述函数中,使用了类型约束标注,约束了两个参数的类型均为 str。如果传入的实参类型不匹配,就会在编译期触发错误,从而避免了可疑参数类型的问题。

总之,在使用格式化字符串时,我们应该遵循语法规则,以 f-string 或类型约束标注的方式进行约束,这样才能够有效地防止可疑参数类型引发的问题。