Skip to content

Conversation

arvi18
Copy link

@arvi18 arvi18 commented Apr 26, 2025

The timeout value may be overflowed if users set a large expiration time.

sessionExpirationTimeNanos = authenticationEndNanos + 1000 * 1000 * sessionLifetimeMs;

Fixed it by throwing exception if the value is overflowed.

Committer Checklist (excluded from commit message)

  • Verify design and implementation
  • Verify test coverage and CI build status
  • Verify documentation (including upgrade notes)

Summary by CodeRabbit

  • Bug Fixes

    • Safer handling of session/token expiration math to prevent silent overflows and ensure predictable expiration behavior for very large lifetimes.
    • Overflows now produce capped or explicit error outcomes instead of incorrect timestamps.
  • Tests

    • Added tests validating large-expiration scenarios and time-conversion edge cases (including overflow behavior).
  • Chores

    • Improved test helpers and cleanup to isolate large-expiration tests and maintain test reliability.

@arvi18
Copy link
Author

arvi18 commented Apr 26, 2025

This PR is being marked as stale since it has not had any activity in 90 days. If you
would like to keep this PR alive, please leave a comment asking for a review. If the PR has
merge conflicts, update it with the latest from the base branch.

If you are having difficulty finding a reviewer, please reach out on the [mailing list](https://kafka.apache.org/contact).

If this PR is no longer valid or desired, please feel free to close it. If no activity occurs in the next 30 days, it will be automatically closed.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Hello @arvi18, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

Summary of Changes

This pull request addresses a potential overflow issue in the calculation of SASL session expiration time. The issue arises when a large session lifetime is configured, potentially leading to an ArithmeticException. To resolve this, I've implemented a change that uses Math.addExact and Utils.msToNs to perform the calculation, which throws an exception if an overflow occurs. Additionally, I've added a test case to verify the fix and ensure that the channel closes when a large re-authentication value is used.

Highlights

  • Overflow Prevention: The core change involves replacing the direct multiplication and addition with Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse)) to prevent potential overflow when calculating clientSessionReauthenticationTimeNanos in SaslClientAuthenticator.java and sessionExpirationTimeNanos in SaslServerAuthenticator.java.
  • Utility Function: A new utility function msToNs is introduced in Utils.java to convert milliseconds to nanoseconds, throwing an IllegalArgumentException if an arithmetic overflow occurs during the conversion.
  • Test Case: A new test case testReauthenticateWithLargeReauthValue is added in SaslAuthenticatorTest.java to simulate the overflow scenario and verify that the connection channel is closed as expected.

Changelog

Click here to see the changelog
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java
    • Replaced direct calculation of clientSessionReauthenticationTimeNanos with Math.addExact and Utils.msToNs to prevent overflow.
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java
    • Replaced direct calculation of sessionExpirationTimeNanos with Math.addExact and Utils.msToNs to prevent overflow.
  • clients/src/main/java/org/apache/kafka/common/utils/Utils.java
    • Added msToNs utility function to convert milliseconds to nanoseconds with overflow check.
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java
    • Added needLargeExpiration flag to control the lifetime of the token.
    • Added testReauthenticateWithLargeReauthValue test case to verify overflow handling during re-authentication with a large re-authentication value.
    • Modified createClientConnection to use createCustomClientConnection.
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticatorTest.java
    • Added testSessionWontExpireWithLargeExpirationTime test case to verify the overflow exception is thrown when a large expiration time is configured.
  • clients/src/test/java/org/apache/kafka/common/utils/UtilsTest.java
    • Added testMsToNs test case to verify the msToNs utility function.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.


In nanoseconds' dance,
Overflow's a risky chance,
Guard with Math's embrace,
Exceptions find their place,
Code's safety, we enhance.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request addresses a potential overflow issue in the calculation of SASL session expiration time. The fix involves using Math.addExact and Utils.msToNs to prevent overflow and throwing an exception if overflow occurs. Additionally, a test case is added to verify the fix. Overall, the changes seem reasonable and well-structured.

Summary of Findings

  • Exception handling: The code throws an IllegalArgumentException when an arithmetic overflow occurs during the conversion of milliseconds to nanoseconds. While this addresses the immediate issue, consider whether a more specific exception type might be appropriate to provide better context to callers.
  • Test coverage: The added test case testReauthenticateWithLargeReauthValue in SaslAuthenticatorTest.java effectively tests the overflow scenario. However, consider adding additional test cases with different large values to ensure robustness.

Merge Readiness

The pull request addresses a critical issue and includes a test case to verify the fix. However, before merging, it's recommended to consider the exception type and add more test cases for robustness. I am unable to approve this pull request, and users should have others review and approve this code before merging.

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));

Comment on lines 1706 to 1711
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);
}

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
}
}

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));

Copy link

coderabbitai bot commented Apr 26, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Switches session-expiration arithmetic to overflow-checked operations via Utils.msToNs and Math.addExact, adds ms-to-ns helper, and expands tests to cover extremely large expiration values and related client/server test helpers and assertions.

Changes

Cohort / File(s) Summary
Client session expiration update
clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java
Replace direct addition of nanos with Math.addExact(authenticationEndNanos, Utils.msToNs(sessionLifetimeMsToUse)) to perform overflow-checked addition.
Server session expiration update with overflow handling
clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java
Use Math.addExact(..., Utils.msToNs(retvalSessionLifetimeMs)) wrapped in try/catch; on ArithmeticException log a warning and cap sessionExpirationTimeNanos to Long.MAX_VALUE.
Time conversion utility
clients/src/main/java/org/apache/kafka/common/utils/Utils.java
Add NANOS_PER_MILLISECOND and public msToNs(long) using Math.multiplyExact with overflow handling.
Client authenticator tests & helpers
clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java
Add needLargeExpiration flag, testReauthenticateWithLargeReauthValue, helpers to build client connections without SASL_AUTHENTICATE header, AlternateLoginCallbackHandler adjustments, and teardown reset.
Server authenticator overflow test
clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticatorTest.java
Add testSessionWontExpireWithLargeExpirationTime asserting overflow during ms→ns conversion yields ArithmeticException (propagated/validated).
Utils unit tests
clients/src/test/java/org/apache/kafka/common/utils/UtilsTest.java
Add testMsToNs asserting 1ms→1_000_000ns, 0→0, and Long.MAX_VALUE input triggers IllegalArgumentException on overflow.

Sequence Diagram(s)

sequenceDiagram
    participant Authenticator
    participant Utils
    participant Logger

    note over Authenticator,Utils #e6f7ff: Compute session expiration (new flow)
    Authenticator->>Utils: msToNs(sessionLifetimeMs)
    Utils-->>Authenticator: nanos (Math.multiplyExact) or throw ArithmeticException
    Authenticator->>Authenticator: Math.addExact(authenticationEndNanos, nanos)
    alt no overflow
        Authenticator->>Authenticator: set sessionExpirationTimeNanos
    else multiply or add overflow
        Authenticator->>Logger: warn about overflow
        Authenticator->>Authenticator: set sessionExpirationTimeNanos = Long.MAX_VALUE
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

A rabbit counts the milliseconds bright,
Converts to nanos with careful might,
When giant numbers try to creep,
We catch the tumble, guard the heap.
Thump-thump — tests hop safe tonight.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title includes the JIRA ticket reference and clearly identifies that the pull request addresses an overflow issue in the SASL session expiration time calculation, directly summarizing the main change. Although the phrasing “will be overflowed when calculation” is slightly awkward, it remains fully related to the changeset and communicates the primary intent of the fix.
Description Check ✅ Passed The description succinctly explains the overflow problem and the implemented fix, including a code snippet for context, which demonstrates the core change. However, it does not summarize the testing strategy or reference the substantial new unit tests added to verify overflow behavior. Including details about the test scenarios and outcomes would complete the required template guidance on test coverage and rationale.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch clone-KAFKA-14604

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@visz11
Copy link
Collaborator

visz11 commented Apr 28, 2025

@coderabbitai full review

Copy link

coderabbitai bot commented Apr 28, 2025

✅ Actions performed

Full review triggered.

@visz11
Copy link
Collaborator

visz11 commented Sep 15, 2025

/refacto-test-arvi

Copy link

refacto-visz bot commented Sep 15, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

Copy link

refacto-visz bot commented Sep 15, 2025

Code Review: Overflow Protection in Authentication Session Calculations

👍 Well Done
Arithmetic Overflow Protection

Added explicit overflow checking prevents system failures from large timestamp calculations.

Comprehensive Test Coverage

New test cases verify correct handling of large expiration values.

Utils Method Extraction

Created reusable msToNs utility method improving maintainability and error handling.

📌 Files Processed
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticatorTest.java
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java
  • clients/src/main/java/org/apache/kafka/common/utils/Utils.java
  • clients/src/test/java/org/apache/kafka/common/utils/UtilsTest.java
📝 Additional Comments
clients/src/main/java/org/apache/kafka/common/utils/Utils.java (5)
Consistent Exception Handling

Method wraps ArithmeticException in IllegalArgumentException, creating inconsistent exception handling patterns. Consider standardizing on either using runtime exceptions directly or consistently wrapping them throughout the codebase for better error handling predictability.

Standards:

  • ISO-IEC-25010-Reliability-Maturity
  • ISO-IEC-25010-Functional-Appropriateness
  • DbC-Exception-Handling
Constant Factor Extraction

The conversion factor 1000 * 1000 is used directly in the code. Extracting this as a named constant (e.g., NANOS_PER_MILLISECOND = 1_000_000) would improve readability and maintainability while making the conversion intent clearer.

Standards:

  • Algorithm-Correctness-Readability
  • Logic-Verification-Maintainability
Utility Method Caching

The constant multiplication factor (1000 * 1000) is computed each time the method is called. For frequently called utility methods, this could be optimized by using a pre-computed constant. This would eliminate repeated multiplication operations.

Standards:

  • ISO-IEC-25010-Performance-Efficiency-Resource-Utilization
  • Optimization-Pattern-Constant-Computation
  • Algorithmic-Complexity-Constant-Time
Error Message Security

The error message includes the exact value that caused the overflow, which could potentially leak timing information in certain contexts. Consider using a generic error message that doesn't include the specific value to reduce information leakage about internal timing calculations.

Standards:

  • CWE-209
  • OWASP-A04
  • NIST-SSDF-PW.4
Utility Method Documentation

The Javadoc for msToNs utility method could be enhanced with information about the specific exception thrown and when it might occur. More detailed documentation improves maintainability by providing clearer usage guidance.

Standards:

  • Clean-Code-Comments
  • Maintainability-Quality-Documentation

* 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

retvalSessionLifetimeMs = zeroIfNegative(Math.min(credentialExpirationMs - authenticationEndMs, connectionsMaxReauthMs));

sessionExpirationTimeNanos = authenticationEndNanos + 1000 * 1000 * 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

Comment on lines +1710 to +1711
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
}
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 +1114 to +1116
assertEquals(1000000, Utils.msToNs(1));
assertEquals(0, Utils.msToNs(0));
assertThrows(IllegalArgumentException.class, () -> Utils.msToNs(Long.MAX_VALUE));
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

* 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.

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

Comment on lines +1114 to +1116
assertEquals(1000000, Utils.msToNs(1));
assertEquals(0, Utils.msToNs(0));
assertThrows(IllegalArgumentException.class, () -> Utils.msToNs(Long.MAX_VALUE));
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 +1637 to +1641
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");
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

@visz11
Copy link
Collaborator

visz11 commented Sep 15, 2025

/refacto-test-arvi

Copy link

refacto-visz bot commented Sep 15, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

Copy link

refacto-visz bot commented Sep 15, 2025

Code Review: Authentication Session Overflow Protection

👍 Well Done
Arithmetic Overflow Protection

Added proper overflow detection using Math.addExact and Utils.msToNs to prevent authentication session calculation errors.

Comprehensive Test Coverage

Created test cases specifically targeting large expiration values to verify handling of edge cases.

📌 Files Processed
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticatorTest.java
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java
  • clients/src/main/java/org/apache/kafka/common/utils/Utils.java
  • clients/src/test/java/org/apache/kafka/common/utils/UtilsTest.java
📝 Additional Comments
clients/src/main/java/org/apache/kafka/common/utils/Utils.java (3)
Constant Extraction Needed

The magic number 1000 * 1000 (representing nanoseconds per millisecond) should be extracted as a named constant. This improves code readability and maintainability while reducing the risk of inconsistent time unit conversion throughout the codebase.

Standards:

  • ISO-IEC-25010-Functional-Appropriateness
  • ISO-IEC-25010-Maintainability
  • DbC-Clarity
Error Message Enhancement

The error message could be enhanced to include the maximum supported millisecond value. This would provide better diagnostics for troubleshooting and help callers understand the limits of the conversion function.

Standards:

  • ISO-IEC-25010-Reliability-Maturity
  • ISO-IEC-25010-Usability-Operability
  • SRE-Error-Handling
Error Message Security

The error message includes the exact value that caused the overflow, which could potentially expose sensitive timing information in error logs. Consider using a generic error message without including the specific timeMs value in production environments.

Standards:

  • CWE-209
  • OWASP-A04
clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java (3)
Refactor Duplicate Code

The refactoring extracts the channel builder creation but introduces code duplication in createCustomClientConnection. The method replicates logic from saslChannelBuilderWithoutHeader when withSaslAuthenticateHeader is true, violating DRY principles.

Standards:

  • Algorithm-Correctness-Code-Duplication
  • Logic-Verification-Maintainability
  • Business-Rule-Code-Structure
Improve Test Isolation

Using static state (needLargeExpiration) for test configuration creates potential test interdependence. If test execution order changes or parallel execution is enabled, tests could interfere with each other, leading to non-deterministic test results.

Standards:

  • Logic-Verification-Test-Isolation
  • Algorithm-Correctness-State-Management
  • Business-Rule-Testing
Test Coverage Enhancement

The added test verifies handling of large re-authentication values but could be enhanced to test more edge cases. Consider adding tests for values just below overflow threshold and for negative values that might be provided by malicious authentication tokens.

Standards:

  • CWE-190
  • OWASP-A07
  • NIST-SSDF-RV.1

retvalSessionLifetimeMs = zeroIfNegative(Math.min(credentialExpirationMs - authenticationEndMs, connectionsMaxReauthMs));

sessionExpirationTimeNanos = authenticationEndNanos + 1000 * 1000 * 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 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

* 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.

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

Comment on lines +1637 to +1641
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");
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

*/
public static long msToNs(long timeMs) {
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

Comment on lines +1637 to +1641
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");
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 +295 to +296
assertEquals(ArithmeticException.class, t.getCause().getClass());
assertEquals("Cannot convert " + Long.MAX_VALUE + " millisecond to nanosecond due to arithmetic overflow",
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

* 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.

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

Comment on lines +2112 to +2133
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());
}
};
}
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

Comment on lines 1707 to 1710
try {
return Math.multiplyExact(1000 * 1000, timeMs);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
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

@visz11
Copy link
Collaborator

visz11 commented Sep 15, 2025

/refacto-test-arvi

Copy link

refacto-visz bot commented Sep 24, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

Copy link

refacto-visz bot commented Sep 24, 2025

Code Review: Authentication Session Overflow Protection

👍 Well Done
Arithmetic Overflow Protection

Added proper overflow detection using Math.addExact and Utils.msToNs to prevent arithmetic overflow in session calculations.

Comprehensive Test Coverage

Added thorough test cases for large expiration values to verify overflow handling.

📌 Files Processed
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticatorTest.java
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java
  • clients/src/main/java/org/apache/kafka/common/utils/Utils.java
  • clients/src/test/java/org/apache/kafka/common/utils/UtilsTest.java
📝 Additional Comments
clients/src/main/java/org/apache/kafka/common/utils/Utils.java (2)
Error Message Improvement

The error message could be more actionable by suggesting a maximum safe value for timeMs. Adding information about the maximum convertible value would help developers understand the limits and avoid trial-and-error troubleshooting.

Standards:

  • ISO-IEC-25010-Functional-Correctness-Appropriateness
  • SRE-Error-Messages
Safe Conversion Utility

Well-implemented utility function for safe millisecond to nanosecond conversion with proper overflow detection. The function correctly uses Math.multiplyExact to detect arithmetic overflow and provides a clear error message, preventing silent failures in authentication timing calculations.

Standards:

  • CWE-190
  • OWASP-A02
  • NIST-SSDF-PW.1
clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java (1)
Proactive Overflow Prevention

While the code correctly detects overflow, it would be better to proactively check if sessionLifetimeMsToUse is too large before attempting the conversion. This would allow for a more graceful fallback to a maximum safe value rather than exception propagation.

Standards:

  • Algorithm-Correctness-Boundary-Conditions
  • Logic-Verification-Defensive-Programming
clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java (1)
Consistent Error Handling

Similar to the client authenticator, the server code doesn't handle the potential IllegalArgumentException from Utils.msToNs. Both client and server should implement consistent error handling strategies for time calculation overflows to ensure system stability.

Standards:

  • Algorithm-Correctness-Exception-Handling
  • Logic-Verification-Error-Paths
  • Business-Rule-Consistency
clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticatorTest.java (1)
Error Handling Improvement

While the test correctly verifies the overflow error message, consider adding a test for graceful error handling in production code. The current implementation throws an exception, but in production this could lead to connection termination rather than a more graceful fallback to a safe maximum value.

Standards:

  • CWE-755
  • OWASP-A04

@@ -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.

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

@@ -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));
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

@@ -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.

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

@@ -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));
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

Comment on lines 1706 to 1712
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);
}
}
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

Co-authored-by: refacto-visz[bot] <230139763+refacto-visz[bot]@users.noreply.github.com>
@visz11
Copy link
Collaborator

visz11 commented Oct 6, 2025

/refacto-visz

1 similar comment
@visz11
Copy link
Collaborator

visz11 commented Oct 6, 2025

/refacto-visz

Copy link

refacto-visz bot commented Oct 6, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed79212 and ffa68e2.

📒 Files selected for processing (6)
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java (1 hunks)
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java (1 hunks)
  • clients/src/main/java/org/apache/kafka/common/utils/Utils.java (1 hunks)
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java (7 hunks)
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticatorTest.java (1 hunks)
  • clients/src/test/java/org/apache/kafka/common/utils/UtilsTest.java (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java (1)
clients/src/main/java/org/apache/kafka/common/utils/Utils.java (1)
  • Utils (93-1716)
clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java (1)
clients/src/main/java/org/apache/kafka/common/utils/Utils.java (1)
  • Utils (93-1716)
clients/src/test/java/org/apache/kafka/common/utils/UtilsTest.java (1)
clients/src/main/java/org/apache/kafka/common/utils/Utils.java (1)
  • Utils (93-1716)
clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java (3)
clients/src/main/java/org/apache/kafka/common/config/SaslConfigs.java (1)
  • SaslConfigs (21-230)
clients/src/test/java/org/apache/kafka/test/TestUtils.java (1)
  • TestUtils (84-708)
clients/src/main/java/org/apache/kafka/common/security/JaasContext.java (1)
  • JaasContext (39-217)
🔇 Additional comments (7)
clients/src/test/java/org/apache/kafka/common/utils/UtilsTest.java (1)

1112-1117: Good coverage on the new converter.

The test hits both normal and overflow paths, so once the converter compiles, this will catch regressions. Nice.

clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java (1)

693-695: Overflow-safe addition looks good.

Using Math.addExact with the shared Utils.msToNs helper is the right fix here.

clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java (1)

684-685: Server-side overflow handling aligned.

Mirroring the client change keeps the session expiration math consistent and safe.

clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticatorTest.java (1)

272-298: Nice guardrail for extreme expirations.

The test validates both the wrapped exception type and message when the conversion overflows, so we’ll notice if the helper regresses.

clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java (3)

2065-2098: LGTM! Good refactoring to extract helper method.

The extraction of saslChannelBuilderWithoutHeader() improves code maintainability by consolidating the logic for creating channel builders that don't use SASL_AUTHENTICATE headers. The implementation follows existing patterns and makes the codebase more DRY.


2100-2138: LGTM! Well-designed helper method.

The createCustomClientConnection() method effectively consolidates client connection setup with configurable SASL_AUTHENTICATE header behavior. The parameterized design makes the intent clear at call sites and reduces code duplication across tests.


2582-2586: LGTM! Appropriate use of conditional lifetime.

The conditional token lifetime logic correctly supports both the overflow test scenario (Long.MAX_VALUE) and normal test scenarios (1 second for quick refresh). The implementation is clean and the flag usage is appropriate for test control.

Comment on lines +1708 to +1714
public static long msToNs(long timeMs) {
try {
return Math.multiplyExact(NANOS_PER_MILLISECOND, timeMs);
} catch (ArithmeticException e) {
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix duplicate catch causing compilation failure.

The method currently declares two identical catch (ArithmeticException e) blocks, leaving the first one empty. This does not compile (duplicate exception parameter). Collapse them into a single catch that wraps the overflow into the IllegalArgumentException.

     public static long msToNs(long timeMs) {
         try {
             return Math.multiplyExact(NANOS_PER_MILLISECOND, timeMs);
-        } catch (ArithmeticException e) {
-        } 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 + " millisecond to nanosecond due to arithmetic overflow", e);
+        }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static long msToNs(long timeMs) {
try {
return Math.multiplyExact(NANOS_PER_MILLISECOND, timeMs);
} catch (ArithmeticException e) {
} 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(NANOS_PER_MILLISECOND, timeMs);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
}
}
🤖 Prompt for AI Agents
In clients/src/main/java/org/apache/kafka/common/utils/Utils.java around lines
1708 to 1714, there are two identical catch blocks for ArithmeticException (one
empty and one that throws an IllegalArgumentException) which causes a
duplicate-catch compilation error; replace the two catches with a single catch
(ArithmeticException e) that throws new IllegalArgumentException("Cannot convert
" + timeMs + " millisecond to nanosecond due to arithmetic overflow", e) so the
overflow is wrapped and the code compiles.

Copy link

refacto-visz bot commented Oct 6, 2025

Code Review: Authentication Session Timing Overflow Protection

👍 Well Done
Overflow Protection Implementation

Proper use of Math.addExact and Utils.msToNs prevents arithmetic overflow in session timing calculations

📁 Selected files for review (6)
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticatorTest.java
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java
  • clients/src/main/java/org/apache/kafka/common/utils/Utils.java
  • clients/src/test/java/org/apache/kafka/common/utils/UtilsTest.java
🎯 Custom Instructions
✅ Applied Instructions
Organization Guidelines
  • Reuse code wherever possible and avoid redundant code by refactoring with utils and static method across application

Scope: All files

❌ Unapplied Instructions
portal-backend

Reason: Repository 'portal-backend' does not match current PR repository

refacto-api

Reason: Repository 'refacto-api' does not match current PR repository

pr-reviewer

Reason: Repository 'pr-reviewer' does not match current PR repository

mypy

Reason: Repository 'mypy' does not match current PR repository

bazel

Reason: Repository 'bazel' does not match current PR repository

devd-client

Reason: Repository 'devd-client' does not match current PR repository

📝 Additional Comments
clients/src/main/java/org/apache/kafka/common/utils/Utils.java (1)
Magic Number Usage

Magic number 1000000 used for nanoseconds per millisecond conversion without named constant. Violates organization guideline for code reusability by not extracting reusable constants. Extract NANOS_PER_MILLISECOND constant to improve maintainability and enable reuse across application.

Standards:

  • Org-Guideline-Reuse code wherever possible and avoid redundant code by refactoring with utils and static method across application
  • ISO-IEC-25010-Reliability-Maturity
clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java (1)
Missing Exception Handling

The code calls Utils.msToNs which can throw IllegalArgumentException but lacks exception handling. If sessionLifetimeMsToUse is extremely large, the unhandled exception could propagate causing unexpected authentication failures. Consider adding try-catch to handle overflow gracefully.

Standards:

  • CWE-755
  • OWASP-A06
  • NIST-SSDF-PW.8
clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java (1)
Missing Exception Handling

The code calls Utils.msToNs which can throw IllegalArgumentException but lacks exception handling. If retvalSessionLifetimeMs is extremely large, the unhandled exception could propagate causing unexpected authentication failures. Consider adding try-catch to handle overflow gracefully.

Standards:

  • CWE-755
  • OWASP-A06
  • NIST-SSDF-PW.8
clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java (1)
Test Method Organization

Test method handles multiple setup, action, and verification phases in single method. Extract setup and verification logic into helper methods to improve test readability and maintainability. This would make test flow clearer and support better code reuse across similar test scenarios.

Standards:

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

@@ -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.

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

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

Choose a reason for hiding this comment

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

Duplicate Exception Catch

Duplicate catch block for ArithmeticException creates unreachable code. Second catch block will never execute because first catch handles same exception type. This violates control flow logic and creates dead code that could confuse maintainers.

Standards
  • Algorithm-Correctness-Control-Flow
  • Logic-Verification-Dead-Code-Elimination
  • Business-Rule-Exception-Handling

@@ -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.

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

Comment on lines +1709 to +1711
try {
return Math.multiplyExact(NANOS_PER_MILLISECOND, timeMs);
} catch (ArithmeticException e) {
Copy link

Choose a reason for hiding this comment

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

Exception Control Flow

Exception handling for control flow creates performance overhead in hot authentication paths. Stack frame creation and exception object allocation add latency when processing large volumes of authentication requests, especially when timeMs approaches overflow thresholds.

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

Comment on lines +1637 to +1641
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");
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

Comment on lines +2116 to +2132
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());
}
};
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

@visz11
Copy link
Collaborator

visz11 commented Oct 6, 2025

/refacto-visz

Copy link

refacto-visz bot commented Oct 6, 2025

PR already reviewed at the latest commit: ffa68e2.
Please try again with new changes.

…icator/SaslServerAuthenticator.java

Co-authored-by: refacto-visz[bot] <230139763+refacto-visz[bot]@users.noreply.github.com>
@visz11
Copy link
Collaborator

visz11 commented Oct 6, 2025

/refacto-visz

Copy link

refacto-visz bot commented Oct 6, 2025

Refacto is reviewing this PR. Please wait for the review comments to be posted.

Copy link

refacto-visz bot commented Oct 6, 2025

Code Review: Authentication Overflow Protection

👍 Well Done
Overflow Protection Added

Math.addExact prevents authentication timing corruption improving session security reliability.

📁 Selected files for review (6)
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java
  • clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticatorTest.java
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java
  • clients/src/main/java/org/apache/kafka/common/utils/Utils.java
  • clients/src/test/java/org/apache/kafka/common/utils/UtilsTest.java
🎯 Custom Instructions
✅ Applied Instructions
Organization Guidelines
  • Reuse code wherever possible and avoid redundant code by refactoring with utils and static method across application

Scope: All files

❌ Unapplied Instructions
portal-backend

Reason: Repository 'portal-backend' does not match current PR repository

refacto-api

Reason: Repository 'refacto-api' does not match current PR repository

pr-reviewer

Reason: Repository 'pr-reviewer' does not match current PR repository

mypy

Reason: Repository 'mypy' does not match current PR repository

bazel

Reason: Repository 'bazel' does not match current PR repository

devd-client

Reason: Repository 'devd-client' does not match current PR repository

📝 Additional Comments
clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslClientAuthenticator.java (2)
Missing Overflow Protection

Client authentication timing calculation lacks exception handling for overflow scenarios. When Utils.msToNs throws IllegalArgumentException, authentication process crashes instead of gracefully handling large session lifetimes.

Standards:

  • ISO-IEC-25010-Reliability
  • SRE-Fault-Tolerance
  • DbC-Exception-Safety
Duplicated Overflow Logic

Identical overflow protection pattern appears in both SaslClientAuthenticator and SaslServerAuthenticator without shared utility method. This duplication increases maintenance burden when authentication timing logic needs updates across multiple authentication components.

Standards:

  • Clean-Code-DRY
  • Refactoring-Extract-Method
  • SOLID-DRY
clients/src/main/java/org/apache/kafka/common/utils/Utils.java (1)
Exception Control Flow

Exception handling for overflow detection creates performance overhead in hot authentication paths. Stack frame creation and exception object allocation add latency when processing high-volume authentication requests, especially when timeMs approaches overflow thresholds requiring frequent validation.

Standards:

  • ISO-IEC-25010-Performance-Time-Behaviour
  • Algorithm-Opt-Exception-Avoidance
  • Google-Core-Web-Vitals-Server-Response
clients/src/test/java/org/apache/kafka/common/security/authenticator/SaslAuthenticatorTest.java (2)
Test Timeout Inefficiency

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

Standards:

  • ISO-IEC-25010-Performance-Time-Behaviour
  • Algorithm-Opt-Timeout-Handling
  • Google-Core-Web-Vitals-Test-Performance
Test Builder Duplication

SaslChannelBuilder creation logic duplicated between header and non-header test scenarios without extracting common construction pattern. This creates maintenance overhead when channel builder configuration needs updates across test methods.

Standards:

  • Refactoring-Extract-Method
  • Clean-Code-Functions

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

Choose a reason for hiding this comment

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

Compilation Error Vulnerability

Duplicate catch blocks prevent compilation, breaking overflow protection in authentication timing calculations. This compilation failure disables the entire security fix for arithmetic overflow vulnerabilities. Critical system security depends on this utility function compiling correctly.

        try {
            return Math.multiplyExact(NANOS_PER_MILLISECOND, timeMs);
        } catch (ArithmeticException e) {
            throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
        }
Commitable Suggestion
Suggested change
} catch (ArithmeticException e) {
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
try {
return Math.multiplyExact(NANOS_PER_MILLISECOND, timeMs);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Cannot convert " + timeMs + " millisecond to nanosecond due to arithmetic overflow", e);
}
Standards
  • CWE-754
  • OWASP-A06

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ffa68e2 and 75949b4.

📒 Files selected for processing (1)
  • clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java (1)
clients/src/main/java/org/apache/kafka/common/utils/Utils.java (1)
  • Utils (93-1716)

Comment on lines +684 to +689
try {
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
} catch (IllegalArgumentException e) {
log.warn("Session lifetime too large, setting to maximum allowed value", e);
sessionExpirationTimeNanos = Long.MAX_VALUE;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Fix logger reference and complete exception handling.

Two critical issues in the overflow handling code:

  1. Compilation error: Line 687 references log (lowercase) but the logger is defined as LOG (uppercase) at line 94.
  2. Incomplete exception handling: The catch block only handles IllegalArgumentException from Utils.msToNs, but Math.addExact throws ArithmeticException on addition overflow. If the addition overflows (even when the conversion doesn't), the exception will propagate uncaught.

Apply this diff to fix both issues:

                 try {
                     sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
-                } catch (IllegalArgumentException e) {
-                    log.warn("Session lifetime too large, setting to maximum allowed value", e);
+                } catch (IllegalArgumentException | ArithmeticException e) {
+                    LOG.warn("Session lifetime too large, setting to maximum allowed value", e);
                     sessionExpirationTimeNanos = Long.MAX_VALUE;
                 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
} catch (IllegalArgumentException e) {
log.warn("Session lifetime too large, setting to maximum allowed value", e);
sessionExpirationTimeNanos = Long.MAX_VALUE;
}
try {
sessionExpirationTimeNanos = Math.addExact(authenticationEndNanos, Utils.msToNs(retvalSessionLifetimeMs));
} catch (IllegalArgumentException | ArithmeticException e) {
LOG.warn("Session lifetime too large, setting to maximum allowed value", e);
sessionExpirationTimeNanos = Long.MAX_VALUE;
}
🤖 Prompt for AI Agents
In
clients/src/main/java/org/apache/kafka/common/security/authenticator/SaslServerAuthenticator.java
around lines 684 to 689, fix the logger reference and complete exception
handling for overflow: replace the lowercase `log` with the proper `LOG`, and
catch both the conversion IllegalArgumentException and any ArithmeticException
from Math.addExact (either combine into a multi-catch IllegalArgumentException |
ArithmeticException or add a separate catch for ArithmeticException) so the
overflow is handled and sessionExpirationTimeNanos is set to Long.MAX_VALUE with
the exception logged via LOG.warn(..., e).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants