用户控制的数据在数字强制转换中¶
ID: java/tainted-numeric-cast
Kind: path-problem
Security severity: 9.0
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-197
- external/cwe/cwe-681
Query suites:
- java-code-scanning.qls
- java-security-extended.qls
- java-security-and-quality.qls
将用户控制的数字值强制转换为更窄的类型会导致值被截断,除非输入得到验证。
缩窄转换可能会导致意外的结果。例如,将正整数 128
强制转换为 byte
类型会产生负值 -128
。
推荐¶
通过以下操作之一来防止用户控制的算术数据的意外截断
验证用户输入。
在强制转换表达式上定义一个保护,以便只有在已知输入在结果类型的范围内时才执行强制转换。
避免强制转换为更窄的类型,而是继续使用更宽的类型。
示例¶
在本示例中,从标准输入中读取一个值并将其放入 long
中。由于该值是用户控制的值,因此它可能非常大。因此,将该值强制转换为更窄的类型可能会导致意外截断。 scaled2
示例使用一个保护来避免此问题,并在执行强制转换之前检查输入范围。如果该值过大而无法强制转换为 int
类型,则会将其拒绝为无效。
class Test {
public static void main(String[] args) throws IOException {
{
long data;
BufferedReader readerBuffered = new BufferedReader(
new InputStreamReader(System.in, "UTF-8"));
String stringNumber = readerBuffered.readLine();
if (stringNumber != null) {
data = Long.parseLong(stringNumber.trim());
} else {
data = 0;
}
// AVOID: potential truncation if input data is very large,
// for example 'Long.MAX_VALUE'
int scaled = (int)data;
//...
// GOOD: use a guard to ensure no truncation occurs
int scaled2;
if (data > Integer.MIN_VALUE && data < Integer.MAX_VALUE)
scaled2 = (int)data;
else
throw new IllegalArgumentException("Invalid input");
}
}
}
参考资料¶
SEI CERT Java 编码标准:NUM12-J. 确保数值类型转换为更窄类型时不会导致数据丢失或误解.
常见弱点枚举:CWE-197.
常见弱点枚举:CWE-681.