Skip to content

Fix CodeQL warning-severity alerts: weak salt PRNG, unsafe DCL, thread-unsafe date formats - #789

Merged
vharseko merged 1 commit into
OpenIdentityPlatform:masterfrom
vharseko:fix-codeql-warning-tier1
Jul 30, 2026
Merged

Fix CodeQL warning-severity alerts: weak salt PRNG, unsafe DCL, thread-unsafe date formats#789
vharseko merged 1 commit into
OpenIdentityPlatform:masterfrom
vharseko:fix-codeql-warning-tier1

Conversation

@vharseko

Copy link
Copy Markdown
Member

Triaged the 241 open warning-severity CodeQL alerts and fixed the six that are genuine defects. The remaining clusters are either mechanical hardening (missing default: in enum switches, resource leaks in installer/upgrade tooling) or false positives (intentional non-short-circuit &, dead-but-harmless constant checks) and are left for follow-ups.

Changes

  • Sha2Crypt (java/random-used-once) — crypt salts were generated with a fresh java.util.Random per character. java.util.Random is a linear congruential generator whose output is predictable from observed values (CWE-338), which is not acceptable for a password salt. Replaced with a single shared SecureRandom. Reached from sha256Crypt/sha512Crypt, i.e. the live password hashing path.
  • GSSAPISASLMechanismHandler (java/unsafe-double-checked-locking-init-order) — loginContext was assigned before login() ran, so a thread passing the unsynchronized outer null check could obtain a context whose login had not completed. The context is now published only after login() returns.
  • CommonAudit (java/unused-format-argument) — String.format("... configuration entry:", config.dn()) had no placeholder, silently dropping the DN from the trace log.
  • ConfigFromConnection (java/thread-unsafe-dateformat) — the shared static SimpleDateFormat/DateFormat fields are replaced by newUtcParser()/newDateFormatter() factory methods. This also fixes a latent bug: setTimeZone("UTC") sat in an instance initializer operating on a static field, so utcParser parsed in the default time zone until the first ConfigFromConnection instance was constructed. Call sites in RootMonitoringPanel, ServerDescriptor and Utilities are updated.
  • BaseDNCellRenderer (java/reference-equality-on-strings) — the not-available sentinels were compared with == against public static (non-final) String fields; this only worked by reference coincidence. Switched to equals() and made the sentinels final.
  • AsynchronousTextWriter (java/dereferenced-value-may-be-null) — writer.writeRecord() was called unconditionally at one point and null-checked a few lines later. The class already dereferences writer unconditionally in flush(), getBytesWritten() and the writer thread, and all five call sites pass a freshly constructed writer, so the constructor now rejects null and the two vestigial checks are removed.

Verification

  • mvn -o -pl opendj-server-legacy -am compile — passes.
  • opendj-server-legacy disables surefire (tests run through failsafe against a real server), so the unit-test route does not cover these classes. The Sha2Crypt change was verified directly against the built classes: $5$/$6$ round-trip over 200 iterations, salt shape (8 chars from B64T), and 2000 consecutive salts all distinct.

Note for reviewers: Sha2Crypt deliberately zeroes the key array passed to it (Arrays.fill(keyBytes, (byte) 0), upstream commons-codec behaviour), so any test calling it twice must supply a fresh password array each time.

…d-unsafe date formats

* Sha2Crypt: generate crypt salts from a shared SecureRandom instead of
  instantiating a non-cryptographic java.util.Random for every character.
* GSSAPISASLMechanismHandler: publish the login context only after login()
  has completed, so a concurrent reader cannot obtain an unusable context.
* CommonAudit: add the missing format specifier so the configuration entry
  DN is actually written to the trace log.
* ConfigFromConnection: replace the shared static SimpleDateFormat and
  DateFormat fields with factory methods. This also fixes the UTC time zone
  being applied from an instance initializer, which left the parser using the
  default time zone until the first instance was created.
* BaseDNCellRenderer: compare the not-available sentinels with equals()
  rather than reference equality, and make the sentinels final.
* AsynchronousTextWriter: reject a null wrapped writer in the constructor and
  drop the two remaining null checks, which contradicted the unconditional
  dereferences elsewhere in the class.
@vharseko vharseko added security Security fixes / CodeQL code-scanning alerts concurrency Thread-safety / race-condition bugs bug java Pull requests that update java code labels Jul 30, 2026
@vharseko
vharseko requested a review from maximthomas July 30, 2026 09:49
@vharseko
vharseko merged commit 90cce51 into OpenIdentityPlatform:master Jul 30, 2026
17 checks passed
@vharseko
vharseko deleted the fix-codeql-warning-tier1 branch July 30, 2026 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug concurrency Thread-safety / race-condition bugs java Pull requests that update java code security Security fixes / CodeQL code-scanning alerts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants