Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ public void setAuthenticationEndAndSessionReauthenticationTimes(long nowNanos) {
double pctToUse = pctWindowFactorToTakeNetworkLatencyAndClockDriftIntoAccount + RNG.nextDouble()
* pctWindowJitterToAvoidReauthenticationStormAcrossManyChannelsSimultaneously;
sessionLifetimeMsToUse = (long) (positiveSessionLifetimeMs * pctToUse);
clientSessionReauthenticationTimeNanos = authenticationEndNanos + 1000 * 1000 * sessionLifetimeMsToUse;
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arithmetic Overflow Vulnerability

Direct multiplication without overflow checking can cause arithmetic overflow when large session lifetime values are used. This could lead to incorrect re-authentication timing calculations, potentially causing premature session expiration or authentication failures.

Suggested change
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Standards
  • CWE-190
  • OWASP-A04
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Duplication

The same overflow handling pattern is duplicated in SaslClientAuthenticator and SaslServerAuthenticator. Consider extracting a common helper method that both classes can use for session expiration time calculation to improve maintainability.

Standards
  • Clean-Code-DRY
  • Maintainability-Quality-Duplication
  • Design-Pattern-Extract-Method

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Client Authentication Overflow

Client-side session re-authentication time calculation is vulnerable to arithmetic overflow when large session lifetimes are used. This could lead to premature session expiration or authentication failures. The fix properly handles this by using Math.addExact and a new Utils.msToNs method with overflow detection.

Suggested change
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Standards
  • CWE-190
  • OWASP-A07
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method Extraction Opportunity

The calculation of session expiration time appears in both SaslClientAuthenticator and SaslServerAuthenticator classes with identical logic. This duplication creates maintenance burden where changes must be made in multiple places consistently.

Standards
  • Clean-Code-DRY
  • Refactoring-Extract-Method
  • Maintainability-Quality-Duplication

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Time Calculation Overflow

Direct multiplication of milliseconds to nanoseconds can cause arithmetic overflow with large session lifetimes. This could lead to authentication timing vulnerabilities where sessions expire prematurely or never expire due to integer overflow. The fix correctly uses Math.addExact and a new utility method to detect overflow.

Suggested change
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Standards
  • CWE-190
  • CWE-682
  • OWASP-A06

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Exception Handling

The code calls Utils.msToNs which can throw IllegalArgumentException, but there's no exception handling. If sessionLifetimeMsToUse is very large, the exception will propagate up the call stack potentially causing unexpected behavior in authentication logic.

Standards
  • Algorithm-Correctness-Exception-Handling
  • Logic-Verification-Error-Flow
  • Business-Rule-Robustness

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate Code Pattern

Similar overflow protection code was added to both SaslClientAuthenticator and SaslServerAuthenticator. The pattern of converting milliseconds to nanoseconds with overflow protection appears in multiple places, suggesting an opportunity for a more comprehensive time utility class.

Standards
  • Clean-Code-DRY
  • Design-Pattern-Utility-Class
  • Maintainability-Quality-Reusability

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integer Overflow Vulnerability in Session Expiration Calculation

Integer overflow when calculating session expiration time can lead to premature session expiration or authentication bypass. When sessionLifetimeMsToUse is very large, multiplying by 1000*1000 causes overflow, potentially setting expiration to a negative or small value. This could allow attackers to bypass authentication controls.

Suggested change
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Standards
  • CWE-190
  • OWASP-A07
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Authentication Session Overflow

The calculation of session expiration time can cause arithmetic overflow when large values are used. This could lead to incorrect session expiration timing, potentially causing authentication failures or premature session termination affecting system availability.

                clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Commitable Suggestion
Suggested change
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Standards
  • CWE-190
  • OWASP-A02
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Authentication Session Overflow

Direct arithmetic calculation of session expiration time is vulnerable to integer overflow when large values are used. This can cause premature session expiration or authentication failures when millisecond values approach Long.MAX_VALUE, potentially leading to service disruption or authentication bypass.

                try {
                    clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
                } catch (IllegalArgumentException e) {
                    log.warn("Session re-authentication time calculation failed due to overflow. Using max possible value.", e);
                    clientSessionReauthenticationTimeNanos = Long.MAX_VALUE;
                }
Commitable Suggestion
Suggested change
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
try {
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
} catch (IllegalArgumentException e) {
log.warn("Session re-authentication time calculation failed due to overflow. Using max possible value.", e);
clientSessionReauthenticationTimeNanos = Long.MAX_VALUE;
}
Standards
  • CWE-190
  • OWASP-A07
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method Extraction Opportunity

The calculation for clientSessionReauthenticationTimeNanos now uses a utility method for ms-to-ns conversion, but the error handling is still tied to this specific usage. Moving the entire time calculation to a dedicated utility method would further improve maintainability and reusability.

Standards
  • Clean-Code-Functions
  • Maintainability-Quality-DRY

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Authentication Timing Overflow

The authentication session timing calculation is vulnerable to arithmetic overflow when using large millisecond values. This could lead to premature session expiration or authentication bypass when manipulating session lifetimes. The fix properly addresses this by using Math.addExact and Utils.msToNs to detect and prevent overflow.

                clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Commitable Suggestion
Suggested change
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Standards
  • CWE-190
  • OWASP-A07
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arithmetic Overflow Risk

Direct multiplication of large millisecond values can cause arithmetic overflow. When sessionLifetimeMsToUse is large (e.g., Long.MAX_VALUE), this calculation overflows causing incorrect session expiration times and potential authentication failures.

                clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Commitable Suggestion
Suggested change
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Standards
  • ISO-IEC-25010-Reliability-Fault-Tolerance
  • ISO-IEC-25010-Functional-Correctness-Precision
  • DbC-Input-Validation
  • SRE-Error-Handling

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Authentication Session Overflow

Direct arithmetic calculation of session expiration time can cause integer overflow with large millisecond values. This could lead to premature session expiration or authentication failures when using long-lived tokens, potentially causing service disruption or authentication bypass.

                clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Commitable Suggestion
Suggested change
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
Standards
  • CWE-190
  • OWASP-A02
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Exception Handling

The code now correctly uses Math.addExact and Utils.msToNs to detect overflow, but doesn't handle the potential IllegalArgumentException that Utils.msToNs can throw. If sessionLifetimeMsToUse is too large, the exception will propagate up the call stack without proper handling.

Standards
  • Algorithm-Correctness-Exception-Handling
  • Logic-Verification-Error-Paths
  • Business-Rule-Robustness

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Authentication Timing Overflow

Direct arithmetic multiplication of large millisecond values can cause integer overflow leading to incorrect session expiration timing. This could result in premature session expiration or authentication bypass when session lifetimes approach Long.MAX_VALUE. The fix properly uses Math.addExact and Utils.msToNs to detect overflow conditions.

                try {
                    clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
                } catch (IllegalArgumentException e) {
                    log.warn("Session lifetime too large, setting to maximum allowed value", e);
                    clientSessionReauthenticationTimeNanos = Long.MAX_VALUE;
                }
Commitable Suggestion
Suggested change
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
try {
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
} catch (IllegalArgumentException e) {
log.warn("Session lifetime too large, setting to maximum allowed value", e);
clientSessionReauthenticationTimeNanos = Long.MAX_VALUE;
}
Standards
  • CWE-190
  • CWE-682
  • OWASP-A07
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate Code Pattern

Identical overflow protection pattern duplicated in both SaslClientAuthenticator and SaslServerAuthenticator classes. This violates DRY principle and creates maintenance burden where changes must be synchronized across multiple locations. Extract common session expiration calculation logic into shared utility method.

                clientSessionReauthenticationTimeNanos = Utils.calculateExpirationTimeNanos(authenticationEndNanos, sessionLifetimeMsToUse, log);
Commitable Suggestion
Suggested change
clientSessionReauthenticationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse));
clientSessionReauthenticationTimeNanos = Utils.calculateExpirationTimeNanos(authenticationEndNanos, sessionLifetimeMsToUse, log);
Standards
  • Org-Guideline-Reuse code wherever possible and avoid redundant code by refactoring with utils and static method across application
  • Clean-Code-DRY
  • Refactoring-Extract-Method

log.debug(
"Finished {} with session expiration in {} ms and session re-authentication on or after {} ms",
authenticationOrReauthenticationText(), positiveSessionLifetimeMs, sessionLifetimeMsToUse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ else if (!maxReauthSet)
else
retvalSessionLifetimeMs = zeroIfNegative(Math.min(credentialExpirationMs - authenticationEndMs, connectionsMaxReauthMs));

sessionExpirationTimeNanos = authenticationEndNanos + 1000 * 1000 * retvalSessionLifetimeMs;
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the change in SaslClientAuthenticator.java, this change uses Math.addExact and Utils.msToNs to prevent potential overflow. This is consistent and correct.

Suggested change
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Authentication Timing Overflow

Server-side authentication expiration calculation is vulnerable to arithmetic overflow with large session lifetime values. This could cause incorrect session expiration timing, potentially leading to authentication failures or premature session termination.

Suggested change
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
Standards
  • CWE-190
  • OWASP-A04
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Authentication Session Calculation

Direct arithmetic calculation of session expiration time is vulnerable to integer overflow when large values (like Long.MAX_VALUE) are used. This could cause premature session expiration or authentication failures. The fix properly handles this by using Math.addExact and a new Utils.msToNs method with overflow detection.

Suggested change
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
Standards
  • CWE-190
  • OWASP-A07
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Server Authentication Overflow

Direct multiplication of milliseconds to nanoseconds can cause arithmetic overflow with large session lifetimes. This could lead to authentication timing vulnerabilities where sessions expire prematurely or never expire due to integer overflow. The fix correctly uses Math.addExact and a new utility method to detect overflow.

Suggested change
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
Standards
  • CWE-190
  • CWE-682
  • OWASP-A06

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Exception Handling

The code calls Utils.msToNs which can throw IllegalArgumentException, but there's no exception handling. If retvalSessionLifetimeMs is very large, the exception will propagate up the call stack potentially causing unexpected behavior in authentication logic.

Standards
  • Algorithm-Correctness-Exception-Handling
  • Logic-Verification-Error-Flow
  • Business-Rule-Robustness

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integer Overflow Vulnerability in Session Expiration Calculation

Integer overflow when calculating session expiration time can lead to premature session termination or authentication bypass. When retvalSessionLifetimeMs is very large, multiplying by 1000*1000 causes overflow, potentially setting expiration to a negative or small value. This could allow attackers to bypass authentication controls.

Suggested change
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
Standards
  • CWE-190
  • OWASP-A07
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Server Authentication Overflow

The server-side calculation of session expiration time is vulnerable to arithmetic overflow with large session lifetime values. This could lead to incorrect authentication session timing calculations, potentially causing authentication failures or security control bypass.

                sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
Commitable Suggestion
Suggested change
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
Standards
  • CWE-190
  • OWASP-A02
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Server Authentication Overflow

Server-side session expiration calculation is vulnerable to integer overflow when large millisecond values are used. This can cause authentication sessions to expire incorrectly or fail to expire at all, potentially leading to authentication failures or unauthorized access.

                try {
                    sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
                } catch (IllegalArgumentException e) {
                    log.warn("Session expiration time calculation failed due to overflow. Using max possible value.", e);
                    sessionExpirationTimeNanos = Long.MAX_VALUE;
                }
Commitable Suggestion
Suggested change
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
try {
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
} catch (IllegalArgumentException e) {
log.warn("Session expiration time calculation failed due to overflow. Using max possible value.", e);
sessionExpirationTimeNanos = Long.MAX_VALUE;
}
Standards
  • CWE-190
  • OWASP-A07
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Server Authentication Overflow

Server-side session expiration calculation is vulnerable to arithmetic overflow when handling large millisecond values. This could lead to incorrect session timing calculations allowing sessions to remain valid longer than intended. The fix properly addresses this by using Math.addExact and Utils.msToNs to detect and prevent overflow.

                sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
Commitable Suggestion
Suggested change
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
Standards
  • CWE-190
  • OWASP-A07
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arithmetic Overflow Risk

Direct multiplication of large millisecond values can cause arithmetic overflow. When retvalSessionLifetimeMs is large (e.g., Long.MAX_VALUE), this calculation overflows causing incorrect session expiration times and potential authentication failures.

                sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
Commitable Suggestion
Suggested change
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
Standards
  • ISO-IEC-25010-Reliability-Fault-Tolerance
  • ISO-IEC-25010-Functional-Correctness-Precision
  • DbC-Input-Validation
  • SRE-Error-Handling

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Server Authentication Overflow

Direct calculation of session expiration time without overflow protection can cause arithmetic overflow with large values. This could lead to incorrect session expiration times, potentially causing premature disconnection of authenticated clients or authentication state inconsistency.

                sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
Commitable Suggestion
Suggested change
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
Standards
  • CWE-190
  • OWASP-A02
  • NIST-SSDF-PW.1

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent Error Handling

The error handling approach differs between client and server authenticators. SaslServerAuthenticator directly propagates the IllegalArgumentException from Utils.msToNs() while SaslClientAuthenticator catches and handles it in the test. This inconsistency makes maintenance and debugging more difficult.

Standards
  • Clean-Code-Error-Handling
  • Maintainability-Quality-Consistency

}

if (credentialExpirationMs != null) {
Expand Down
13 changes: 13 additions & 0 deletions clients/src/main/java/org/apache/kafka/common/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -1697,4 +1697,17 @@ public static ConfigDef mergeConfigs(List<ConfigDef> configDefs) {
public interface ThrowingRunnable {
void run() throws Exception;
}

/**
* convert millisecond to nanosecond, or throw exception if overflow
* @param timeMs the time in millisecond
* @return the converted nanosecond
*/
public static long msToNs(long timeMs) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistent Method Naming

The method name 'msToNs' uses abbreviations inconsistently with other time conversion methods in the codebase. Consider using a more explicit name like 'millisToNanos' for better readability and consistency with other time conversion methods.

Standards
  • Clean-Code-Naming
  • Maintainability-Quality-Consistency

Comment on lines 1701 to 1708
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add JavaDoc Documentation

The JavaDoc comment should include @throws documentation for the IllegalArgumentException that can be thrown. This improves API documentation completeness and helps callers understand exception handling requirements.

Standards
  • Clean-Code-Documentation
  • Maintainability-Quality-API-Documentation

try {
return Math.multiplyExact(1000 * 1000, timeMs);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential Integer Overflow

The multiplication 1000 * 1000 is performed first before multiplying with timeMs, which could lead to integer overflow for large timeMs values. Reordering to Math.multiplyExact(timeMs, 1000 * 1000) would be safer to catch overflow earlier.

Suggested change
return Math.multiplyExact(1000 * 1000, timeMs);
return Math.multiplyExact(timeMs, 1000L * 1000L);
Standards
  • ISO-IEC-25010-Reliability-Maturity
  • ISO-IEC-25010-Functional-Correctness-Appropriateness
  • DbC-Precondition

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic Number Usage

The code uses magic numbers (1000 * 1000) for millisecond to nanosecond conversion. Extract these values to named constants to improve code readability and maintainability, making the intent clearer and facilitating future modifications.

Standards
  • Clean-Code-Magic-Numbers
  • Maintainability-Quality-Readability

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract Magic Number

The magic number '1000 * 1000' represents nanoseconds per millisecond but lacks context. Extracting this to a named constant would improve code readability and maintainability by making the conversion factor's purpose explicit.

    /**
     * Number of nanoseconds in a millisecond
     */
    private static final long NANOS_PER_MILLISECOND = 1000 * 1000;

    /**
     * convert millisecond to nanosecond, or throw exception if overflow
     * @param timeMs the time in millisecond
     * @return the converted nanosecond
     */
    public static long msToNs(long timeMs) {
        try {
            return Math.multiplyExact(NANOS_PER_MILLISECOND, timeMs);
        } catch (ArithmeticException e) {
            throw new IllegalArgumentException("Cannot convert " + timeMs + " milliseconds to nanoseconds due to arithmetic overflow", e);
        }
    }
Commitable Suggestion
Suggested change
return Math.multiplyExact(1000 * 1000, timeMs);
/**
* Number of nanoseconds in a millisecond
*/
private static final long NANOS_PER_MILLISECOND = 1000 * 1000;
/**
* convert millisecond to nanosecond, or throw exception if overflow
* @param timeMs the time in millisecond
* @return the converted nanosecond
*/
public static long msToNs(long timeMs) {
try {
return Math.multiplyExact(NANOS_PER_MILLISECOND, timeMs);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " milliseconds to nanoseconds due to arithmetic overflow", e);
}
}
Standards
  • Clean-Code-Magic-Numbers
  • Maintainability-Quality-Readability

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract Magic Numbers

The magic number 1000 * 1000 representing nanoseconds per millisecond should be extracted as a named constant. This improves code readability and maintainability by making the conversion factor's purpose explicit.

    /**
     * Number of nanoseconds in a millisecond
     */
    private static final long NANOSECONDS_PER_MILLISECOND = 1000 * 1000;

    /**
     * convert millisecond to nanosecond, or throw exception if overflow
     * @param timeMs the time in millisecond
     * @return the converted nanosecond
     */
    public static long msToNs(long timeMs) {
        try {
            return Math.multiplyExact(NANOSECONDS_PER_MILLISECOND, timeMs);
        } catch (ArithmeticException e) {
            throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
        }
    }
Commitable Suggestion
Suggested change
return Math.multiplyExact(1000 * 1000, timeMs);
/**
* Number of nanoseconds in a millisecond
*/
private static final long NANOSECONDS_PER_MILLISECOND = 1000 * 1000;
/**
* convert millisecond to nanosecond, or throw exception if overflow
* @param timeMs the time in millisecond
* @return the converted nanosecond
*/
public static long msToNs(long timeMs) {
try {
return Math.multiplyExact(NANOSECONDS_PER_MILLISECOND, timeMs);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
}
}
Standards
  • Clean-Code-Meaningful-Names
  • Maintainability-Quality-Constants

} catch (ArithmeticException e) {
Comment on lines 1708 to 1712
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defensive Boundary Check

The method relies solely on exception handling to detect overflow. Adding an explicit boundary check (timeMs > Long.MAX_VALUE / (1000 * 1000)) before multiplication would improve performance for edge cases by avoiding exception creation and provide clearer intent about the mathematical constraints.

Standards
  • Algorithm-Correctness-Boundary-Checks
  • Mathematical-Accuracy-Overflow-Prevention

throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
Comment on lines 1709 to 1713
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defensive Boundary Check

Adding a boundary check before the multiplication could prevent the exception entirely for known large values. For values exceeding Long.MAX_VALUE/1_000_000, an early check would be more efficient than throwing and catching exceptions, which have performance overhead.

Standards
  • ISO-IEC-25010-Performance-Efficiency-Time-Behavior
  • Optimization-Pattern-Early-Validation
  • Exception-Handling-Performance-Impact

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential Overflow Risk

The multiplication order creates unnecessary intermediate overflow risk. Calculating '1000 * 1000' first creates an intermediate value of 1,000,000 before multiplying by timeMs. Changing to 'Math.multiplyExact(timeMs, 1000L * 1000L)' would prevent potential overflow for smaller timeMs values.

Standards
  • Algorithm-Correctness-Numeric-Overflow
  • Mathematical-Accuracy-Calculation-Order
  • Logic-Verification-Boundary-Conditions

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded Error Message

Error message is hardcoded and not internationalized. For a core utility method, this could make troubleshooting more difficult in non-English environments and violates internationalization best practices.

Standards
  • ISO-IEC-25010-Functional-Correctness-Appropriateness
  • SRE-Error-Handling

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error Message Clarity

The multiplication order (1000 * 1000 first, then result * timeMs) could cause intermediate overflow for large timeMs values. Reordering to (timeMs * 1000) * 1000 would provide better overflow protection by handling the largest value first.

Standards
  • ISO-IEC-25010-Performance-Efficiency-Fault-Tolerance
  • Optimization-Pattern-Numeric-Calculation
  • Algorithmic-Complexity-Overflow-Protection

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent Error Message

Error message uses singular 'millisecond' regardless of the timeMs value. For values other than 1, this creates grammatically incorrect error messages. Consistent error messaging improves troubleshooting and system observability.

Standards
  • ISO-IEC-25010-Functional-Correctness-Appropriateness
  • SRE-Error-Handling

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exception Message Clarity

The multiplication order (1000 * 1000 first, then result * timeMs) could cause intermediate overflow for large timeMs values that would otherwise convert successfully. Reversing multiplication order (timeMs * 1000, then result * 1000) would handle larger input ranges before overflow.

Standards
  • ISO-IEC-25010-Performance-Efficiency-Resource-Utilization
  • Optimization-Pattern-Numeric-Range-Maximization
  • Algorithmic-Complexity-Overflow-Prevention

Comment on lines 1709 to 1713
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error Message Clarity

The msToNs utility method could be improved by using a named constant for the conversion factor (1000 * 1000) to enhance readability. Additionally, the error message could provide guidance on how to handle large time values.

Standards
  • Clean-Code-Naming
  • Maintainability-Quality-Constants

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exception Message Clarity

The exception message uses singular 'millisecond' when referring to a potentially plural value. This inconsistency could cause confusion during troubleshooting. Using 'milliseconds' would be more accurate for all possible timeMs values.

        } catch (ArithmeticException e) {
            throw new IllegalArgumentException("Cannot convert " + timeMs + " milliseconds to nanoseconds due to arithmetic overflow", e);
        }
Commitable Suggestion
Suggested change
return Math.multiplyExact(1000 * 1000, timeMs);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " milliseconds to nanoseconds due to arithmetic overflow", e);
}
Standards
  • ISO-IEC-25010-Performance-Efficiency-Maturity
  • Error-Handling-Best-Practices
  • Diagnostic-Message-Clarity

}
Comment on lines 1708 to 1714

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The msToNs method converts milliseconds to nanoseconds and throws an IllegalArgumentException if an arithmetic overflow occurs. Consider using a more specific exception type, such as ArithmeticException, to provide better context to callers.

Suggested change
public static long msToNs(long timeMs) {
try {
return Math.multiplyExact(1000 * 1000, timeMs);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
}
public static long msToNs(long timeMs) {
try {
return Math.multiplyExact(1000 * 1000, timeMs);
} catch (ArithmeticException e) {
throw e; // re-throw the ArithmeticException
}
}

Comment on lines +1713 to +1714
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect Error Message

The error message uses plural 'milliseconds' but singular 'nanosecond'. This inconsistency in plurality creates a grammatical error. The message should use either both singular or both plural forms for consistency.

Standards
  • Logic-Verification-Error-Handling
  • Business-Rule-Message-Consistency

Comment on lines 1709 to 1714
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uncaught Arithmetic Exception

The multiplication 1000 * 1000 is performed before the multiplyExact call, bypassing overflow protection for that operation. This could lead to undetected overflow in the initial calculation before multiplyExact is applied to the result.

Suggested change
try {
return Math.multiplyExact(1000 * 1000, timeMs);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
}
try {
return Math.multiplyExact(Math.multiplyExact(1000, 1000), timeMs);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
}
Standards
  • ISO-IEC-25010-Reliability-Maturity
  • ISO-IEC-25010-Functional-Correctness-Appropriateness
  • DbC-Precondition-Validation

}
Comment on lines 1708 to 1715
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Utility Method Naming

The utility method 'msToNs' uses abbreviated naming that reduces readability. While common in some contexts, fully descriptive method names like 'millisecondsToNanoseconds' improve code self-documentation, especially for utility methods that may be used across the codebase.

Standards
  • Clean-Code-Meaningful-Names
  • Maintainability-Quality-Naming
  • Clean-Code-Functions

Comment on lines 1701 to 1715
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Utility Method Documentation

The Javadoc could be improved with more details about the exception thrown and when overflow might occur. Adding information about the IllegalArgumentException and potential overflow scenarios would make the method's behavior more predictable for developers.

Standards
  • Clean-Code-Documentation
  • Maintainability-Quality-API

Comment on lines 1708 to 1715
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential Exception Handling

The exception handling converts an ArithmeticException to IllegalArgumentException which may be unexpected by callers. This could lead to incorrect error handling if callers are specifically handling ArithmeticException but not IllegalArgumentException.

Standards
  • ISO-IEC-25010-Reliability-Fault-Tolerance
  • ISO-IEC-25010-Functional-Correctness-Appropriateness
  • SRE-Error-Handling

Comment on lines 1708 to 1715
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exception Handling Overhead

Using exception handling for control flow creates performance overhead in hot paths. The try-catch block adds runtime overhead when processing large volumes of authentication requests, especially when timeMs approaches Long.MAX_VALUE.

    public static long msToNs(long timeMs) {
        // Check if multiplication would overflow
        if (timeMs > 0 && Long.MAX_VALUE / (1000 * 1000) < timeMs) {
            throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow");
        }
        if (timeMs < 0 && Long.MIN_VALUE / (1000 * 1000) > timeMs) {
            throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow");
        }
        return 1000 * 1000 * timeMs;
    }
Commitable Suggestion
Suggested change
public static long msToNs(long timeMs) {
try {
return Math.multiplyExact(1000 * 1000, timeMs);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
}
}
public static long msToNs(long timeMs) {
// Check if multiplication would overflow
if (timeMs > 0 && Long.MAX_VALUE / (1000 * 1000) < timeMs) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow");
}
if (timeMs < 0 && Long.MIN_VALUE / (1000 * 1000) > timeMs) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow");
}
return 1000 * 1000 * timeMs;
}
Standards
  • ISO-IEC-25010-Performance-Efficiency-Time-Behavior
  • Optimization-Pattern-Control-Flow
  • Exception-Handling-Performance

Comment on lines 1708 to 1715
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overflow Detection Improvement

The multiplication order in msToNs() creates intermediate overflow risk. Calculating 1000*1000 first creates an intermediate result that could overflow when multiplied by large timeMs values. Reordering to Math.multiplyExact(timeMs, 1000L) and then multiplying by 1000L would provide better overflow protection.

    /**
     * convert millisecond to nanosecond, or throw exception if overflow
     * @param timeMs the time in millisecond
     * @return the converted nanosecond
     */
    public static long msToNs(long timeMs) {
        try {
            // First multiply by 1000L to get microseconds, then by 1000L again to get nanoseconds
            // This avoids potential intermediate overflow issues
            return Math.multiplyExact(Math.multiplyExact(timeMs, 1000L), 1000L);
        } catch (ArithmeticException e) {
            throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
        }
    }
Commitable Suggestion
Suggested change
public static long msToNs(long timeMs) {
try {
return Math.multiplyExact(1000 * 1000, timeMs);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
}
}
/**
* convert millisecond to nanosecond, or throw exception if overflow
* @param timeMs the time in millisecond
* @return the converted nanosecond
*/
public static long msToNs(long timeMs) {
try {
// First multiply by 1000L to get microseconds, then by 1000L again to get nanoseconds
// This avoids potential intermediate overflow issues
return Math.multiplyExact(Math.multiplyExact(timeMs, 1000L), 1000L);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
}
}
Standards
  • CWE-190
  • OWASP-A04
  • NIST-SSDF-PW.1

Comment on lines 1708 to 1715
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exception Handling Overhead

Using exception handling for control flow can introduce performance overhead. The try-catch block creates additional stack frames and exception objects when overflow occurs. For frequently called utility methods, consider using a bounds check before multiplication instead of relying on exceptions.

Standards
  • ISO-IEC-25010-Performance-Efficiency-Time-Behavior
  • Optimization-Pattern-Exception-Avoidance
  • Algorithmic-Complexity-Constant-Time

}
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ public class SaslAuthenticatorTest {
private static final long CONNECTIONS_MAX_REAUTH_MS_VALUE = 100L;
private static final int BUFFER_SIZE = 4 * 1024;
private static Time time = Time.SYSTEM;
private static boolean needLargeExpiration = false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve Variable Naming

The variable name 'needLargeExpiration' could be more descriptive. Consider renaming to 'useLargeExpirationForTesting' or 'enableLargeExpirationTest' to better communicate its purpose in controlling test behavior for specific scenarios.

Standards
  • Clean-Code-Naming
  • Maintainability-Quality-Readability


private NioEchoServer server;
private Selector selector;
Expand All @@ -178,6 +179,7 @@ public void setup() throws Exception {

@AfterEach
public void teardown() throws Exception {
needLargeExpiration = false;
if (server != null)
this.server.close();
if (selector != null)
Expand Down Expand Up @@ -1607,6 +1609,42 @@ public void testCannotReauthenticateWithDifferentPrincipal() throws Exception {
server.verifyReauthenticationMetrics(0, 1);
}

@Test
public void testReauthenticateWithLargeReauthValue() throws Exception {
// enable it, we'll get a large expiration timestamp token
needLargeExpiration = true;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arithmetic Overflow Risk

The test enables large expiration values (Long.MAX_VALUE) which triggers arithmetic overflow in time calculations. This test correctly validates the fix for overflow conditions that could cause system instability in production when handling authentication tokens with extremely large expiration times.

        needLargeExpiration = true; // Enable large expiration to test overflow handling
Commitable Suggestion
Suggested change
needLargeExpiration = true;
needLargeExpiration = true; // Enable large expiration to test overflow handling
Standards
  • ISO-IEC-25010-Performance-Efficiency-Fault-Tolerance
  • Algorithmic-Complexity-Boundary-Conditions
  • Optimization-Pattern-Error-Handling

String node = "0";
Comment on lines +1612 to +1616
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test Method Organization

The test method is relatively long and handles multiple steps. Consider extracting setup, action, and verification phases into helper methods to improve test readability and maintainability. This would make the test flow clearer and easier to maintain.

Standards
  • Clean-Code-Functions
  • Maintainability-Quality-Testing
  • Refactoring-Extract-Method

SecurityProtocol securityProtocol = SecurityProtocol.SASL_SSL;

configureMechanisms(OAuthBearerLoginModule.OAUTHBEARER_MECHANISM,
List.of(OAuthBearerLoginModule.OAUTHBEARER_MECHANISM));
// set a large re-auth timeout in server side
saslServerConfigs.put(BrokerSecurityConfigs.CONNECTIONS_MAX_REAUTH_MS_CONFIG, Long.MAX_VALUE);
Comment on lines +1615 to +1622
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential Connection Loss

Test uses Long.MAX_VALUE for CONNECTIONS_MAX_REAUTH_MS_CONFIG which triggers arithmetic overflow. This causes connection termination as shown in the test's verification logic. In production, similar overflow could cause unexpected connection drops affecting system availability.

Suggested change
needLargeExpiration = true;
String node = "0";
SecurityProtocol securityProtocol = SecurityProtocol.SASL_SSL;
configureMechanisms(OAuthBearerLoginModule.OAUTHBEARER_MECHANISM,
List.of(OAuthBearerLoginModule.OAUTHBEARER_MECHANISM));
// set a large re-auth timeout in server side
saslServerConfigs.put(BrokerSecurityConfigs.CONNECTIONS_MAX_REAUTH_MS_CONFIG, Long.MAX_VALUE);
needLargeExpiration = true;
// Use a large but safe value that won't cause overflow when converted to nanoseconds
long safeMaxReauthMs = Long.MAX_VALUE / (1000 * 1000);
saslServerConfigs.put(BrokerSecurityConfigs.CONNECTIONS_MAX_REAUTH_MS_CONFIG, safeMaxReauthMs);
Standards
  • ISO-IEC-25010-Performance-Efficiency-Reliability
  • Optimization-Pattern-Boundary-Testing
  • Algorithmic-Complexity-Edge-Case-Handling

server = createEchoServer(securityProtocol);

// set to default value for sasl login configs for initialization in ExpiringCredentialRefreshConfig
saslClientConfigs.put(SaslConfigs.SASL_LOGIN_REFRESH_WINDOW_FACTOR, SaslConfigs.DEFAULT_LOGIN_REFRESH_WINDOW_FACTOR);
saslClientConfigs.put(SaslConfigs.SASL_LOGIN_REFRESH_WINDOW_JITTER, SaslConfigs.DEFAULT_LOGIN_REFRESH_WINDOW_JITTER);
saslClientConfigs.put(SaslConfigs.SASL_LOGIN_REFRESH_MIN_PERIOD_SECONDS, SaslConfigs.DEFAULT_LOGIN_REFRESH_MIN_PERIOD_SECONDS);
saslClientConfigs.put(SaslConfigs.SASL_LOGIN_REFRESH_BUFFER_SECONDS, SaslConfigs.DEFAULT_LOGIN_REFRESH_BUFFER_SECONDS);
saslClientConfigs.put(SaslConfigs.SASL_LOGIN_CALLBACK_HANDLER_CLASS, AlternateLoginCallbackHandler.class);

createCustomClientConnection(securityProtocol, OAuthBearerLoginModule.OAUTHBEARER_MECHANISM, node, true);

// channel should be not null before sasl handshake
assertNotNull(selector.channel(node));

TestUtils.waitForCondition(() -> {
selector.poll(1000);
// this channel should be closed due to session timeout calculation overflow
return selector.channel(node) == null;
}, "channel didn't close with large re-authentication value");
Comment on lines +1637 to +1641
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential Exception Overhead

The test waits for an exception to occur inside the poll operation, which may cause performance overhead in test execution. Exception-based control flow can introduce latency due to stack trace generation and exception handling machinery.

Standards
  • ISO-IEC-25010-Performance-Efficiency-Time-Behavior
  • Optimization-Pattern-Exception-Handling
  • Performance-Testing-Efficiency

Comment on lines +1637 to +1641
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exception Handling Missing

TestUtils.waitForCondition lacks exception handling for timeout scenarios. If the channel doesn't close as expected, the test will fail with a timeout exception without clear diagnostic information, making troubleshooting difficult.

Suggested change
TestUtils.waitForCondition(() -> {
selector.poll(1000);
// this channel should be closed due to session timeout calculation overflow
return selector.channel(node) == null;
}, "channel didn't close with large re-authentication value");
try {
TestUtils.waitForCondition(() -> {
selector.poll(1000);
// this channel should be closed due to session timeout calculation overflow
return selector.channel(node) == null;
}, "channel didn't close with large re-authentication value");
} catch (InterruptedException e) {
throw new AssertionError("Test interrupted while waiting for channel to close: " + e.getMessage(), e);
}
Standards
  • ISO-IEC-25010-Reliability-Fault-Tolerance
  • ISO-IEC-25010-Functional-Correctness-Appropriateness
  • SRE-Error-Handling

Comment on lines +1637 to +1641
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Error Handling

The test asserts channel closure but doesn't verify the specific error condition. Without checking logs or exception type, it cannot confirm whether the channel closed due to the expected overflow error or some other unrelated issue.

Standards
  • Algorithm-Correctness-Exception-Handling
  • Logic-Verification-Test-Validation
  • Business-Rule-Error-Verification

Comment on lines +1637 to +1641
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Error Handling

The TestUtils.waitForCondition doesn't handle timeout exceptions. If the condition never satisfies (channel doesn't close), the test will hang indefinitely rather than failing with a clear timeout message.

Standards
  • ISO-IEC-25010-Reliability-Fault-Tolerance
  • ISO-IEC-25010-Functional-Correctness-Appropriateness
  • SRE-Error-Handling

Comment on lines +1637 to +1641
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incomplete Error Handling

The test expects channel closure on overflow but doesn't verify the specific error. Without validating the exact exception type or error message, the test might pass for wrong reasons. This could mask authentication bypass vulnerabilities if channel closes for unrelated reasons.

Standards
  • CWE-390
  • OWASP-A07
  • NIST-SSDF-PW.8

Comment on lines +1637 to +1641
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Error Handling

The waitForCondition test doesn't handle the case where the condition never becomes true. If the channel doesn't close as expected, the test will hang until it times out rather than failing with a clear error message. This reduces test reliability.

Standards
  • ISO-IEC-25010-Reliability-Fault-Tolerance
  • ISO-IEC-25010-Functional-Correctness-Appropriateness
  • SRE-Error-Handling

Comment on lines +1637 to +1641
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test Timeout Risk

TestUtils.waitForCondition lacks timeout exception handling for scenarios where channel doesn't close as expected. Test execution performance degrades when condition never satisfies, causing indefinite waiting rather than failing with clear timeout diagnostics.

Standards
  • ISO-IEC-25010-Performance-Efficiency-Time-Behavior
  • Optimization-Pattern-Timeout-Handling
  • Test-Performance-Reliability


// ensure metrics are as expected
server.verifyAuthenticationMetrics(0, 0);
server.verifyReauthenticationMetrics(0, 0);
}

@Test
public void testCorrelationId() {
SaslClientAuthenticator authenticator = new SaslClientAuthenticator(
Expand Down Expand Up @@ -1936,7 +1974,7 @@ private void createClientConnection(SecurityProtocol securityProtocol, String sa
if (enableSaslAuthenticateHeader)
createClientConnection(securityProtocol, node);
else
createClientConnectionWithoutSaslAuthenticateHeader(securityProtocol, saslMechanism, node);
createCustomClientConnection(securityProtocol, saslMechanism, node, false);
}

private NioEchoServer startServerApiVersionsUnsupportedByClient(final SecurityProtocol securityProtocol, String saslMechanism) throws Exception {
Expand Down Expand Up @@ -2024,15 +2062,13 @@ protected void enableKafkaSaslAuthenticateHeaders(boolean flag) {
return server;
}

private void createClientConnectionWithoutSaslAuthenticateHeader(final SecurityProtocol securityProtocol,
final String saslMechanism, String node) throws Exception {

final ListenerName listenerName = ListenerName.forSecurityProtocol(securityProtocol);
final Map<String, ?> configs = Collections.emptyMap();
final JaasContext jaasContext = JaasContext.loadClientContext(configs);
final Map<String, JaasContext> jaasContexts = Collections.singletonMap(saslMechanism, jaasContext);

SaslChannelBuilder clientChannelBuilder = new SaslChannelBuilder(ConnectionMode.CLIENT, jaasContexts,
private SaslChannelBuilder saslChannelBuilderWithoutHeader(
final SecurityProtocol securityProtocol,
final String saslMechanism,
final Map<String, JaasContext> jaasContexts,
final ListenerName listenerName
) {
return new SaslChannelBuilder(ConnectionMode.CLIENT, jaasContexts,
securityProtocol, listenerName, false, saslMechanism,
null, null, null, time, new LogContext(), null) {

Expand All @@ -2059,6 +2095,42 @@ protected void setSaslAuthenticateAndHandshakeVersions(ApiVersionsResponse apiVe
};
}
};
}

private void createCustomClientConnection(
final SecurityProtocol securityProtocol,
final String saslMechanism,
String node,
boolean withSaslAuthenticateHeader
) throws Exception {

final ListenerName listenerName = ListenerName.forSecurityProtocol(securityProtocol);
final Map<String, ?> configs = Collections.emptyMap();
final JaasContext jaasContext = JaasContext.loadClientContext(configs);
final Map<String, JaasContext> jaasContexts = Collections.singletonMap(saslMechanism, jaasContext);

SaslChannelBuilder clientChannelBuilder;
if (!withSaslAuthenticateHeader) {
clientChannelBuilder = saslChannelBuilderWithoutHeader(securityProtocol, saslMechanism, jaasContexts, listenerName);
} else {
clientChannelBuilder = new SaslChannelBuilder(ConnectionMode.CLIENT, jaasContexts,
securityProtocol, listenerName, false, saslMechanism,
null, null, null, time, new LogContext(), null) {

@Override
protected SaslClientAuthenticator buildClientAuthenticator(Map<String, ?> configs,
AuthenticateCallbackHandler callbackHandler,
String id,
String serverHost,
String servicePrincipal,
TransportLayer transportLayer,
Subject subject) {

return new SaslClientAuthenticator(configs, callbackHandler, id, subject,
servicePrincipal, serverHost, saslMechanism, transportLayer, time, new LogContext());
}
};
Comment on lines +2116 to +2132
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract Common Method

SaslChannelBuilder creation with header duplicates similar logic to saslChannelBuilderWithoutHeader method. Extract common channel builder creation pattern into reusable helper method to improve code symmetry and reduce duplication. This aligns with organization guideline for code reuse.

Standards
  • Org-Guideline-Reuse code wherever possible and avoid redundant code by refactoring with utils and static method across application
  • Refactoring-Extract-Method
  • Maintainability-Quality-Symmetry

}
Comment on lines +2112 to +2133
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract Common Method

The SaslChannelBuilder creation with header could be extracted into a separate method similar to saslChannelBuilderWithoutHeader. This would improve code symmetry, reduce duplication, and make the createCustomClientConnection method more concise and easier to maintain.

Standards
  • Clean-Code-Functions
  • Refactoring-Extract-Method
  • Maintainability-Quality-Symmetry

clientChannelBuilder.configure(saslClientConfigs);
this.selector = NetworkTestUtils.createSelector(clientChannelBuilder, time);
InetSocketAddress addr = new InetSocketAddress("localhost", server.port());
Expand Down Expand Up @@ -2507,10 +2579,11 @@ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallback
+ ++numInvocations;
String headerJson = "{" + claimOrHeaderJsonText("alg", "none") + "}";
/*
* Use a short lifetime so the background refresh thread replaces it before we
* If we're testing large expiration scenario, use a large lifetime.
* Otherwise, use a short lifetime so the background refresh thread replaces it before we
* re-authenticate
*/
String lifetimeSecondsValueToUse = "1";
String lifetimeSecondsValueToUse = needLargeExpiration ? String.valueOf(Long.MAX_VALUE) : "1";
String claimsJson;
try {
claimsJson = String.format("{%s,%s,%s}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,35 @@ public void testSessionExpiresAtTokenExpiry() throws IOException {
}
}

@Test
public void testSessionWontExpireWithLargeExpirationTime() throws IOException {
String mechanism = OAuthBearerLoginModule.OAUTHBEARER_MECHANISM;
SaslServer saslServer = mock(SaslServer.class);
MockTime time = new MockTime(0, 1, 1000);
// set a Long.MAX_VALUE as the expiration time
Duration largeExpirationTime = Duration.ofMillis(Long.MAX_VALUE);

try (
MockedStatic<?> ignored = mockSaslServer(saslServer, mechanism, time, largeExpirationTime);
MockedStatic<?> ignored2 = mockKafkaPrincipal("[principal-type]", "[principal-name");
TransportLayer transportLayer = mockTransportLayer()
) {

SaslServerAuthenticator authenticator = getSaslServerAuthenticatorForOAuth(mechanism, transportLayer, time, largeExpirationTime.toMillis());

mockRequest(saslHandshakeRequest(mechanism), transportLayer);
authenticator.authenticate();

when(saslServer.isComplete()).thenReturn(false).thenReturn(true);
mockRequest(saslAuthenticateRequest(), transportLayer);

Throwable t = assertThrows(IllegalArgumentException.class, () -> authenticator.authenticate());
assertEquals(ArithmeticException.class, t.getCause().getClass());
assertEquals("Cannot convert " + Long.MAX_VALUE + " millisecond to nanosecond due to arithmetic overflow",
Comment on lines +295 to +296
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent Error Message

The test expects a specific error message that doesn't match the actual implementation in Utils.msToNs(). The test checks for "arithmetic overflow" while the implementation throws "due to arithmetic overflow", which will cause the test to fail.

Standards
  • Logic-Verification-Test-Correctness
  • Algorithm-Correctness-Error-Messaging
  • Business-Rule-Consistency

Comment on lines +295 to +296
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Test Coverage

The test verifies the exception class and message but doesn't validate the actual exception propagation path. The test should verify that the exception is properly wrapped in IllegalArgumentException as shown in the error message, not just check the cause.

            assertEquals(IllegalArgumentException.class, t.getClass());
            assertEquals(ArithmeticException.class, t.getCause().getClass());
            assertEquals("Cannot convert " + Long.MAX_VALUE + " millisecond to nanosecond due to arithmetic overflow",
Commitable Suggestion
Suggested change
assertEquals(ArithmeticException.class, t.getCause().getClass());
assertEquals("Cannot convert " + Long.MAX_VALUE + " millisecond to nanosecond due to arithmetic overflow",
assertEquals(IllegalArgumentException.class, t.getClass());
assertEquals(ArithmeticException.class, t.getCause().getClass());
assertEquals("Cannot convert " + Long.MAX_VALUE + " millisecond to nanosecond due to arithmetic overflow",
Standards
  • Algorithm-Correctness-Exception-Handling
  • Logic-Verification-Test-Completeness

t.getMessage());
Comment on lines +294 to +297
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Exception Handling

The test verifies exception type and message but doesn't verify the complete exception chain. The test should also verify that the ArithmeticException is properly wrapped inside the IllegalArgumentException to ensure proper exception propagation.

Standards
  • ISO-IEC-25010-Reliability-Fault-Tolerance
  • ISO-IEC-25010-Functional-Correctness-Appropriateness
  • SRE-Error-Handling

Comment on lines +294 to +297
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve Error Handling

Test verifies exception handling but doesn't check if the connection is properly terminated after overflow. In production, a failed authentication due to overflow should ensure the connection is closed securely. Consider enhancing the test to verify proper connection termination to prevent potential authentication bypass.

Standards
  • CWE-755
  • OWASP-A07
  • NIST-SSDF-PW.8

}
}

private SaslServerAuthenticator getSaslServerAuthenticatorForOAuth(String mechanism, TransportLayer transportLayer, Time time, Long maxReauth) {
Map<String, ?> configs = Collections.singletonMap(BrokerSecurityConfigs.SASL_ENABLED_MECHANISMS_CONFIG,
Collections.singletonList(mechanism));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,13 @@ public void testTryAll() throws Throwable {
assertEquals(expected, recorded);
}

@Test
public void testMsToNs() {
assertEquals(1000000, Utils.msToNs(1));
assertEquals(0, Utils.msToNs(0));
assertThrows(IllegalArgumentException.class, () -> Utils.msToNs(Long.MAX_VALUE));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test case verifies that an IllegalArgumentException is thrown when msToNs is called with Long.MAX_VALUE. Consider adding additional test cases with different large values to ensure robustness.

        assertThrows(IllegalArgumentException.class, () -> Utils.msToNs(Long.MAX_VALUE));
        assertThrows(IllegalArgumentException.class, () -> Utils.msToNs(Long.MAX_VALUE - 1));
        assertThrows(IllegalArgumentException.class, () -> Utils.msToNs(Long.MAX_VALUE / 2));

Comment on lines +1114 to +1116
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent Test Values

The test verifies positive and zero cases but lacks testing for negative values. Since the msToNs method doesn't explicitly prohibit negative values, the test should verify correct handling of negative millisecond inputs to ensure complete logical coverage.

Standards
  • Logic-Verification-Test-Coverage
  • Algorithm-Correctness-Edge-Cases

Comment on lines +1114 to +1116
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boundary Value Testing

Test only checks extreme values (0, 1, Long.MAX_VALUE) but misses important boundary cases. Adding tests for values near overflow threshold (Long.MAX_VALUE/1_000_000) would better verify the reliability of the msToNs method under edge conditions.

Standards
  • ISO-IEC-25010-Reliability-Maturity
  • ISO-IEC-25010-Functional-Correctness-Appropriateness
  • SRE-Testing-Reliability

Comment on lines +1115 to +1116
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test Coverage Enhancement

Test coverage for msToNs() only verifies extreme values (0 and Long.MAX_VALUE). Adding tests for boundary values (e.g., Long.MAX_VALUE/1000000) would ensure robust overflow detection across the full range of potential inputs.

Standards
  • ISO-IEC-25010-Performance-Efficiency-Reliability
  • Test-Coverage-Optimization
  • Boundary-Value-Testing

}
Comment on lines +1112 to +1117
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consolidate Test Cases

Consider using parameterized tests to improve test maintainability. Using JUnit's @ParameterizedTest would allow adding more test cases without duplicating test structure, making the test more maintainable and extensible.

Standards
  • Clean-Code-Testing
  • Maintainability-Quality-Test-Organization


private Callable<Void> recordingCallable(Map<String, Object> recordingMap, String success, TestException failure) {
return () -> {
if (success == null)
Expand Down
Loading