Safeguard
Application Security•

CWE-585 Empty Synchronized Block in Java: Why It Is a Smell

An empty synchronized block protects nothing and often marks a half-removed lock. Here is how CWE-585 happens and how to fix it.

Safeguard Security Team
3 min read

CWE-585 is an empty synchronized block in Java. It looks like thread safety. It is not.

MITRE says an empty synchronized block does not actually accomplish any synchronization and may indicate a troubled section of code. A common origin: the code inside was no longer needed, it was commented out, and the block was left behind.

How it happens

MITRE's example is as short as it gets:

synchronized (this) { }

The thread waits until nobody else holds the lock, then immediately releases it. It may be part of intended behavior, since it acts like a barrier. But the code after the block is not protected. Nothing stops another thread from changing the shared data a moment later.

A more realistic case:

// Vulnerable: lock taken, nothing protected
synchronized (lock) {
    // balance -= amount;   (commented out during refactor)
}
balance -= amount;          // now runs unprotected

This is the dangerous version. Someone moved the update outside the block, and a race condition appeared.

What an attacker gains

MITRE lists quality degradation and other effects. The hazard is a race condition on shared data. Races can produce inconsistent balances, duplicated actions or data shown to the wrong user, and they are exploitable by sending concurrent requests.

How to find it

MITRE says automated static analysis can find some instances. Many linters flag empty synchronized statements. Review diffs that comment out code inside a lock, and run concurrency tests with parallel callers.

How to fix it

MITRE's mitigation: when you find an empty synchronized statement, or one with the code commented out, work out what the original intent was and whether the block is still needed.

  1. If the block is needed, put the guarded code inside it.
  2. If it is not needed, delete it.
  3. If you really want a barrier, use a clearer tool such as a CountDownLatch or a lock with documented intent.
// Fixed: the critical section is inside the lock
synchronized (lock) {
    balance -= amount;
}

The free in-browser scan at gold.safeguard.sh/scan lists the dependencies in your manifest. No login is needed, the file stays on your machine, and it handles up to 100 dependencies.

Quick check

Does an empty synchronized block protect anything?

No. The code after it is unguarded.

What should I do when I find one?

Find out what it was meant to protect, then either restore the guarded code inside it or remove the block.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.