Reject empty Basic auth passwords in BasicAuthMiddleware - #185
Conversation
Port the light-4j BasicAuthHandler fixes: reject empty passwords before local or LDAP validation, use a constant-time password comparison, handle short Authorization headers without exceptions, and stop logging credentials or submitted usernames. Refs networknt/light-4j#2804 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Note
Copilot was unable to run its full agentic suite in this review.
Copilot review overview
Review effort: Lite
Findings: 2
Open (2)
What changed in this PR
This PR hardens Basic authentication handling in the Lambda middleware by rejecting empty passwords and safely handling malformed/short Authorization headers without risking substring bounds errors.
Changes:
- Add a test user with an empty configured password and new unit tests for empty passwords and short/malformed auth headers.
- Update
BasicAuthMiddlewareto use safer prefix detection (regionMatches) and reduce sensitive data in logs. - Compare Basic passwords using
MessageDigest.isEqualand explicitly reject empty supplied passwords.
| File | Description |
|---|---|
| src/test/resources/config/basic-auth.yml | Adds a test user with an empty configured password to validate rejection behavior. |
| src/test/java/com/networknt/aws/lambda/middleware/security/BasicAuthMiddlewareTest.java | Adds regression tests for empty configured passwords and malformed/short Authorization headers. |
| src/main/java/com/networknt/aws/lambda/handler/middleware/security/BasicAuthMiddleware.java | Hardens auth header parsing and Basic auth validation; reduces sensitive logging. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Code review(xhigh · 10 findings) I reported 10 findings on PR #185. None of them is a blocker, and the fix holds up: I ran the two new tests against the old BasicAuthMiddleware. The empty-password test returned 200 instead of 401, and the short-header test threw StringIndexOutOfBoundsException, so both tests do catch the bugs the PR fixes. The most important findings:
The rest are lower priority:
|
|
Copilot reviewed your latest commit (404c006). It has one open finding; the two from its first review are marked resolved. Open finding: a Bearer header with no token is let through (BasicAuthMiddleware.java:73, rated High) The bug is real, but less serious than "High" suggests. execute sends a bare Bearer or Bearer header straight to handleBearerToken. When allowBearerToken is on, that method only checks the path, so the request succeeds. Why it's not really an authentication bypass:
It's still worth fixing. It's a single check, and it would make execute reject bare Bearer headers the same way it now rejects bare Basic headers and the way UnifiedSecurityMiddleware already does: AuthorizationScheme scheme = AuthorizationScheme.parse(auth); That would sit just before the BASIC/BEARER dispatch. I'd also add a test with basic-auth-bearer.yml (where allowBearerToken is true) checking that Bearer and Bearer both return ERR12003. Mentioned in Copilot's summary but not filed as a finding: "use the sanitized path in the returned status." The log now strips line breaks from the path, but new Status(NOT_AUTHORIZED_REQUEST_PATH, requestPath, ...) still puts the raw path in the response body. That's low risk, since the path only goes back to the client who sent it. Using the cleaned-up path in both places would still keep them consistent, and it costs one line. Do you want me to make both changes and add the test on issue2804-basic-auth? I'd leave them uncommitted for you to check. |
|
Both Copilot items are fixed on issue2804-basic-auth. The changes aren't committed.
Results: mvn -o test finished with 95 run, 0 failures, 0 errors and 4 skipped. git diff --check is clean. The impact checks on execute and handleBasicAuth both came back LOW risk. Not changed: the path-denial errors for the anonymous and bearer users still log and return the raw path. Copilot only flagged the Basic one, but the same one-line fix applies to both if you want them consistent. |


Summary
Ports the light-4j
BasicAuthHandlerfixes from networknt/light-4j#2805 (issue networknt/light-4j#2804) toBasicAuthMiddleware:password: ""andenableAD: falseauthenticated with a blank password, and AD-delegated users relied on the directory refusing unauthenticated binds.MessageDigest.isEqual.Authorizationheaders withoutsubstringexceptions.maskHalfString) and attacker-supplied usernames.testEmptyConfiguredPasswordIsRejected,testShortMalformedAuthorizationHeadersAreRejected.The
LdapUtilhardening (filter escaping, connection cleanup, timeouts) arrives with a later light-4j dependency bump; the middleware guard already blocks empty passwords before LDAP.Test plan
BasicAuthMiddlewareTestpasses (10 tests)🤖 Generated with Claude Code