Python 糟糕的练习和幸运的逃脱或真正的安全--评估fstring

Python 糟糕的练习和幸运的逃脱或真正的安全--评估fstring,python,Python,其中一个新开发人员已经加入了一些代码,可以执行以下操作: var_name = eval('f"' + format_string + '"', kwargs) 只是澄清一下,kwargs是外部提供的,但是format\u string由代码库控制 我不喜欢它,因为它看起来非常容易被破解。然而,我做不到。字符串格式\u string是一个格式为“我吃了一头{cow}”的字符串 有人举过例子吗?我不想仅仅因为“感觉它错了”就把它扔掉。如果这是真正安全的,并且从表面上看,这可能

其中一个新开发人员已经加入了一些代码,可以执行以下操作:

var_name = eval('f"' + format_string + '"', kwargs)
只是澄清一下,
kwargs
是外部提供的,但是
format\u string
由代码库控制

我不喜欢它,因为它看起来非常容易被破解。然而,我做不到。字符串
格式\u string
是一个格式为
“我吃了一头{cow}”
的字符串

有人举过例子吗?我不想仅仅因为“感觉它错了”就把它扔掉。如果这是真正安全的,并且从表面上看,这可能是因为字符串内容从未得到评估;只有格式,没有其他,那太好了。我只是有点偏执

我试过这样的例子

y = "{moo}"
moo = "print(5)"
eval('f"' + y + '"')
但我无法让任何代码真正从字符串中退出并运行。 注意我不是黑客。这是我第一次尝试

需要澄清的是,这里的问题是:


代码安全吗?如果不安全,有人能提供一个将执行的示例输入吗?我发现几乎不可能找到这样一个例子,我认为它是安全的,因为它只生成一个字符串。

我想它是有效的,如果
格式化\u字符串
不是来自用户(因此它生成一个已知的安全f字符串),它在技术上是安全的,只是脆弱;你有信心不会犯错误吗?但这是一种非常奇怪的方式。更明智的解决方案是:

var_name = format_string.format_map(kwargs)  # or .format(**kwargs)
对于简单的命名占位符,其行为相同。这在技术上并不灵活,因为f-string可以执行任意代码来填充它们的占位符,而
str.format
仅按位置或名称进行替换,但在您的示例中,您不需要更多,并且在不需要时涉及整个
eval
机制有点愚蠢

您的尝试不起作用的原因是它只是在
print(5)
中替换并返回结果字符串,而不是执行
print
本身;如果您这样做了:

print(eval('f"' + y + '"'))

你会看到
eval
生成的字符串
'print(5)

我想它可以工作,如果
format\u string
不是来自用户(因此它生成了一个已知的安全f字符串),它在技术上是安全的,只是易碎;你有信心不会犯错误吗?但这是一种非常奇怪的方式。更明智的解决方案是:

var_name = format_string.format_map(kwargs)  # or .format(**kwargs)
对于简单的命名占位符,其行为相同。这在技术上并不灵活,因为f-string可以执行任意代码来填充它们的占位符,而
str.format
仅按位置或名称进行替换,但在您的示例中,您不需要更多,并且在不需要时涉及整个
eval
机制有点愚蠢

您的尝试不起作用的原因是它只是在
print(5)
中替换并返回结果字符串,而不是执行
print
本身;如果您这样做了:

print(eval('f"' + y + '"'))

您将看到
eval
生成的字符串
'print(5)

注意,格式字符串的名称解析是在源代码编译时完成的–在
eval
中使用f字符串意味着它只能访问全局变量。这是否真的可以利用取决于
format\u string
kwargs
是否由外部提供–请编辑您的问题以澄清这一点。为了澄清问题的答案:代码
var\u name=eval('f“+format\u string+”,kwargs)
既不安全也不安全,它是不完整的。它是否安全取决于
format_string
kwargs
的来源。这个问题在指定之前无法回答。请注意,格式字符串的名称解析是在源代码编译时完成的–在
eval
中使用f字符串意味着它只能访问全局变量。这是否真的可以利用取决于
format\u string
kwargs
是否由外部提供–请编辑您的问题以澄清这一点。为了澄清问题的答案:代码
var\u name=eval('f“+format\u string+”,kwargs)
既不安全也不安全,它是不完整的。它是否安全取决于
format_string
kwargs
的来源。这个问题在被要求具体说明之前是无法回答的。