CodeQL 文档

用户控制的数据在数字强制转换中

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

单击以在 CodeQL 代码库中查看查询

将用户控制的数字值强制转换为更窄的类型会导致值被截断,除非输入得到验证。

缩窄转换可能会导致意外的结果。例如,将正整数 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");
		}
	}
}

参考资料

  • ©GitHub, Inc.
  • 条款
  • 隐私