Skip to content

Fix #387: Prevent password from matching username#1608

Open
mambax7 wants to merge 2 commits intoXOOPS:masterfrom
mambax7:fix/387-prevent-password-equals-username
Open

Fix #387: Prevent password from matching username#1608
mambax7 wants to merge 2 commits intoXOOPS:masterfrom
mambax7:fix/387-prevent-password-equals-username

Conversation

@mambax7
Copy link
Collaborator

@mambax7 mambax7 commented Feb 17, 2026

Summary

  • Adds a case-insensitive check in XoopsUserUtility::validate() that rejects a password identical to the username
  • Covers both user registration (register.php) and profile edit (edituser.php) since both call XoopsUserUtility::validate()
  • Adds language string _US_PWDEQUALSUNAME to language/english/user.php

Test plan

  • Register a new user with password = username → should be rejected
  • Edit profile and set password = username → should be rejected
  • Register/edit with password ≠ username → should succeed normally

Fixes #387

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced password validation: users can no longer set a password identical to their username (case-insensitive). This now triggers a clear error message during account creation, profile edits, and password changes.

Add a validation check in XoopsUserUtility::validate() that rejects
a password identical to the username (case-insensitive), covering both
registration and profile edit flows.

Add the corresponding language string _US_PWDEQUALSUNAME to
htdocs/language/english/user.php.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 17, 2026 02:10
@coderabbitai
Copy link

coderabbitai bot commented Feb 17, 2026

Walkthrough

Adds a case-insensitive validation that disallows a password equal to the username when a non-empty password is provided; introduces a new language string _US_PWDEQUALSUNAME for the error message.

Changes

Cohort / File(s) Summary
Validation logic (core)
htdocs/class/userutility.php
Adds case-insensitive check in XoopsUserUtility::validate to reject passwords identical to username; appends _US_PWDEQUALSUNAME to errors.
User edit flow
htdocs/edituser.php
After password length/confirmation checks, adds password==username (case-insensitive) validation branch that records _US_PWDEQUALSUNAME and prevents save.
Password change flow
htdocs/modules/profile/changepass.php
Adds same case-insensitive password==username check after new/confirm match; emits _US_PWDEQUALSUNAME on violation.
Language strings
htdocs/language/english/user.php
Adds define('_US_PWDEQUALSUNAME', 'Your password cannot be the same as your username.') for the new validation error.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant User as User (Client)
participant Edit as EditUser Handler
participant Util as XoopsUserUtility
participant Lang as Language / i18n
User->>Edit: submit username + password (or change request)
Edit->>Util: validate(username, password)
Util-->>Util: check password length, confirmation, then compare lowercase(password) == lowercase(username)
alt password == username
Util->>Edit: return error code _US_PWDEQUALSUNAME
Edit->>Lang: fetch _US_PWDEQUALSUNAME message
Edit->>User: display error, abort save
else valid
Util->>Edit: validation OK
Edit->>User: proceed with save / success

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: preventing passwords from matching usernames, which aligns with the core objective of issue #387.
Linked Issues check ✅ Passed The pull request implements the core requirement from issue #387 by adding case-insensitive checks across registration, profile edit, and password change flows with appropriate language strings.
Out of Scope Changes check ✅ Passed All changes are directly related to enforcing the username-password inequality check across the necessary code paths; no unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements a security enhancement to prevent users from setting their password equal to their username during registration and profile editing. The change addresses issue #387 by adding a case-insensitive validation check in the core XoopsUserUtility::validate() method.

Changes:

  • Added case-insensitive password-equals-username check in XoopsUserUtility::validate()
  • Added English language string _US_PWDEQUALSUNAME for the validation error message

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
htdocs/class/userutility.php Added validation logic to reject passwords matching username (case-insensitive)
htdocs/language/english/user.php Added error message constant for password-equals-username validation

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@htdocs/class/userutility.php`:
- Around line 223-224: The condition uses strtolower($pass) without guaranteeing
$pass is not null, causing deprecation/errors; update the conditional in the
user utility check (the branch that appends _US_PWDEQUALSUNAME to $stop) to
ensure $pass is not null (e.g., add $pass !== null) or replace the $pass check
with a null/empty-safe check like !empty($pass) before calling strtolower($pass)
so strtolower is never invoked with a null argument.

- userutility.php: add $pass !== null guard before strtolower($pass)
  to prevent PHP 8.1 deprecation / PHP 9.0 TypeError when $pass is null

- edituser.php: add username=password check to the inline validation
  block that bypasses XoopsUserUtility::validate() (password change
  during profile edit)

- modules/profile/changepass.php: add username=password check to the
  profile module's dedicated change-password page (also bypassed
  XoopsUserUtility::validate())

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@sonarqubecloud
Copy link

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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@htdocs/class/userutility.php`:
- Around line 223-224: Add unit tests exercising the new password≠username rule
in userutility.php: write tests that call the user validation/registration
routine that uses $pass and $uname (the code path where strtolower($pass) ===
strtolower($uname) triggers) and assert that when password equals username
(case-insensitive) the validation fails and returns/contains the
_US_PWDEQUALSUNAME error, and also assert that when password and username differ
validation succeeds; place tests alongside existing registration/profile unit
tests to cover both registration and profile-update flows so this core behavior
is protected from regressions.

In `@htdocs/edituser.php`:
- Around line 64-65: The type cast "(string)" in the conditional using
strtolower((string)$xoopsUser->getVar(...)) violates PSR-12; add a space after
the cast so it reads "(string) $xoopsUser->getVar(...)" in the strtolower call
within the block that sets $errors[] = _US_PWDEQUALSUNAME; ensure the change is
applied to the conditional using strtolower and the getVar invocation.

In `@htdocs/modules/profile/changepass.php`:
- Around line 58-59: The condition in changepass.php uses a type cast without
the PSR-12 required space: replace occurrences like
(string)$GLOBALS['xoopsUser']->getVar('uname', 'n') in the password check (the
elseif that compares $password to
strtolower((string)$GLOBALS['xoopsUser']->getVar(...))) with a space after the
cast so it becomes (string) $GLOBALS['xoopsUser']->getVar(...); ensure the same
spacing rule is applied anywhere else using (string) casts in this file.

Comment on lines +223 to +224
} elseif ($pass !== '' && $pass !== null && $uname !== null && strtolower($pass) === strtolower($uname)) {
$stop .= _US_PWDEQUALSUNAME . '<br>';
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add unit tests for the new password≠username rule.

This is new core validation behavior and should be covered by tests to prevent regressions in registration/profile flows.

Based on learnings: "New functionality has corresponding unit tests".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@htdocs/class/userutility.php` around lines 223 - 224, Add unit tests
exercising the new password≠username rule in userutility.php: write tests that
call the user validation/registration routine that uses $pass and $uname (the
code path where strtolower($pass) === strtolower($uname) triggers) and assert
that when password equals username (case-insensitive) the validation fails and
returns/contains the _US_PWDEQUALSUNAME error, and also assert that when
password and username differ validation succeeds; place tests alongside existing
registration/profile unit tests to cover both registration and profile-update
flows so this core behavior is protected from regressions.

Comment on lines +64 to +65
} elseif (strtolower($password) === strtolower((string)$xoopsUser->getVar('uname', 'n'))) {
$errors[] = _US_PWDEQUALSUNAME;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

PSR-12: add space after type cast.

Type casts should include a space before the variable.

Suggested fix
-            } elseif (strtolower($password) === strtolower((string)$xoopsUser->getVar('uname', 'n'))) {
+            } elseif (strtolower($password) === strtolower((string) $xoopsUser->getVar('uname', 'n'))) {

As per coding guidelines: "**/*.php: Follow PSR-12 coding standard".

📝 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
} elseif (strtolower($password) === strtolower((string)$xoopsUser->getVar('uname', 'n'))) {
$errors[] = _US_PWDEQUALSUNAME;
} elseif (strtolower($password) === strtolower((string) $xoopsUser->getVar('uname', 'n'))) {
$errors[] = _US_PWDEQUALSUNAME;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@htdocs/edituser.php` around lines 64 - 65, The type cast "(string)" in the
conditional using strtolower((string)$xoopsUser->getVar(...)) violates PSR-12;
add a space after the cast so it reads "(string) $xoopsUser->getVar(...)" in the
strtolower call within the block that sets $errors[] = _US_PWDEQUALSUNAME;
ensure the change is applied to the conditional using strtolower and the getVar
invocation.

Comment on lines +58 to +59
} elseif (!empty($password) && strtolower($password) === strtolower((string)$GLOBALS['xoopsUser']->getVar('uname', 'n'))) {
$errors[] = _US_PWDEQUALSUNAME;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

PSR-12: add space after type cast.

Type casts should include a space before the variable.

Suggested fix
-    } elseif (!empty($password) && strtolower($password) === strtolower((string)$GLOBALS['xoopsUser']->getVar('uname', 'n'))) {
+    } elseif (!empty($password) && strtolower($password) === strtolower((string) $GLOBALS['xoopsUser']->getVar('uname', 'n'))) {

As per coding guidelines: "**/*.php: Follow PSR-12 coding standard".

📝 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
} elseif (!empty($password) && strtolower($password) === strtolower((string)$GLOBALS['xoopsUser']->getVar('uname', 'n'))) {
$errors[] = _US_PWDEQUALSUNAME;
} elseif (!empty($password) && strtolower($password) === strtolower((string) $GLOBALS['xoopsUser']->getVar('uname', 'n'))) {
$errors[] = _US_PWDEQUALSUNAME;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@htdocs/modules/profile/changepass.php` around lines 58 - 59, The condition in
changepass.php uses a type cast without the PSR-12 required space: replace
occurrences like (string)$GLOBALS['xoopsUser']->getVar('uname', 'n') in the
password check (the elseif that compares $password to
strtolower((string)$GLOBALS['xoopsUser']->getVar(...))) with a space after the
cast so it becomes (string) $GLOBALS['xoopsUser']->getVar(...); ensure the same
spacing rule is applied anywhere else using (string) casts in this file.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prevent username = password

1 participant

Comments