CodeQL 文档

检查时使用时间竞争条件

ID: java/toctou-race-condition
Kind: problem
Security severity: 7.7
Severity: warning
Precision: medium
Tags:
   - security
   - external/cwe/cwe-367
Query suites:
   - java-security-extended.qls
   - java-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

通常,需要在使用资源之前检查其状态。如果并发访问资源,则需要以原子方式执行检查和使用,否则资源的状态可能会在检查和使用之间发生变化。这会导致“检查时使用时间”(TOCTOU)竞争条件。

在 Java 中,类可以呈现状态检查方法和操作方法,这些方法是同步的。这可以防止多个线程同时执行这些方法,但它不能防止在单独方法调用之间发生状态变化。

建议

在调用需要对对象保持一致视图的一系列方法时,请确保在监视器上进行同步,以防止在您的操作期间对对象进行任何其他访问。

如果使用的类具有精心设计的接口,那么在对象本身进行同步将防止其状态发生不适当的更改。

示例

以下示例显示了一个具有就绪状态的资源,以及只有在资源就绪时才有效的操作。

在错误的情况下,调用者检查就绪状态然后采取行动,但没有在两个调用之间进行同步,因此另一个线程可能会更改就绪状态。

在正确的情况下,调用者共同地在资源上同步检查和使用,因此没有其他线程可以在使用之前修改状态。

class Resource {
	public synchronized boolean isReady() { ... }

	public synchronized void setReady(boolean ready) { ... }
	
	public synchronized void act() { 
		if (!isReady())
			throw new IllegalStateException();
		...
	}
}
	
public synchronized void bad(Resource r) {
	if (r.isReady()) {
		// r might no longer be ready, another thread might
		// have called setReady(false)
		r.act();
	}
}

public synchronized void good(Resource r) {
	synchronized(r) {
		if (r.isReady()) {
			r.act();
		}
	}
}

参考资料

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