我正在初始化一个可变字符串,然后按如下方式记录它。
NSMutableString* mStr = [[NSMutableString alloc] init];
mStr = (NSMutableString*) someTextFieldIbOutlet.text;
NSLog((NSString *) mStr);
代码工作并运行,但我收到一个奇怪的警告(黄色):
Format string is not a string literal (potentially insecure).
为什么?
答案 0 :(得分:10)
嗯,这里有一些问题。
第一个(而不是您询问的那个)是您正在分配一个新的NSMutableString,然后在将它设置为someTextFieldIbOutlet.text时将其丢弃在第二行。此外,您正在将一个不可变的字符串转换为可变的字符串,该字符串实际上不起作用。相反,将前两行合并如下:
NSMutableString* mStr = [NSMutableString stringWithString:someTextFieldIbOutlet.text];
你得到的实际错误是因为NSLog的第一个参数应该是“format”字符串,它告诉NSLog你想如何格式化后面参数后面的数据。这应该是一个文字字符串(创建类似@"this is a literal string"
),因此不能通过对其进行更改来利用它。
相反,请使用:
NSLog(@"%@", mStr );
在这种情况下,格式字符串为@"%@"
,表示“创建NSString
对象设置为%@
”。 %@
表示下一个参数是一个对象,并用对象的描述替换%@
(在本例中是字符串的值)。
答案 1 :(得分:6)
如果将mStr
设置为%@
,NSLog
会尝试加载对象参数,失败,并且可能会严重崩溃。还有其他格式字符串也会造成严重破坏。
如果您只需要记录没有任何标记文本的字符串,请使用:
NSLog(@"%@", mStr);
答案 2 :(得分:6)
您传递的mStr
用于格式化。如果此字符串来自不受信任的来源,则如果攻击者提供了正确写入的某些输入,则可以将其用于exploit your program。
您应该将代码修改为:
NSLog(@"%@", (NSString *) mStr);
这样,无论mStr
中存储了哪些内容,攻击者都无法使用它来利用您的程序。
这是一个严重的安全问题;从我CVE database的本地存档中,我计算了1999年到2012年初期间520个格式字符串漏洞的实例。