-
Notifications
You must be signed in to change notification settings - Fork 483
fix(security): validate user names on API save path — stored-XSS hardening (chain PR 8) #36356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,9 @@ | |
| import com.dotmarketing.exception.DotDataException; | ||
| import com.dotmarketing.exception.DotSecurityException; | ||
| import com.dotmarketing.util.Logger; | ||
| import com.dotmarketing.util.RegEX; | ||
| import com.dotmarketing.util.UtilMethods; | ||
| import com.liferay.util.SystemProperties; | ||
| import com.liferay.portal.NoSuchUserException; | ||
| import com.liferay.portal.*; | ||
| import com.liferay.portal.ejb.UserUtil; | ||
|
|
@@ -187,6 +189,30 @@ else if (!PwdToolkitUtil.validate(password1) || | |
| } | ||
| } | ||
|
|
||
| /** | ||
| * Validates that user-supplied names do not contain HTML/control metacharacters | ||
| * (e.g. {@code <}, {@code >}, CR/LF). This mirrors the legacy | ||
| * {@code UserLocalManagerImpl} check but is enforced here so it also covers the | ||
| * modern REST/API save path (e.g. {@code PUT /api/v1/users/current}), which would | ||
| * otherwise persist names verbatim and enable stored XSS in the admin UI. | ||
| * | ||
| * The allowed character set is driven by the configurable | ||
| * {@code UserName.regexp.pattern} system property; validation is skipped only when | ||
| * that property is not configured. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟠 [High] Incorrect configuration property retrieval The code uses |
||
| */ | ||
| public static void validateName(final String firstName, final String lastName) throws DotDataException { | ||
| final String pattern = GetterUtil.getString(SystemProperties.get("UserName.regexp.pattern")); | ||
| if (!UtilMethods.isSet(pattern)) { | ||
| return; | ||
| } | ||
| if (UtilMethods.isSet(firstName) && !RegEX.contains(firstName, pattern)) { | ||
| throw new DotDataException("First Name contains invalid characters"); | ||
| } | ||
| if (UtilMethods.isSet(lastName) && !RegEX.contains(lastName, pattern)) { | ||
| throw new DotDataException("Last Name contains invalid characters"); | ||
| } | ||
| } | ||
|
|
||
| public static void validateMaximumLength(final String firstName, final String lastName, final String email) throws DotDataException { | ||
| if (UtilMethods.exceedsMaxLength(firstName, MAX_FIELD_LENGTH)) { | ||
| throw new DotDataException("Length of First Name provided exceeds the maximum limit " + MAX_FIELD_LENGTH); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟠 [High] Potential NullPointerException in user name validation
UserAPIImpl.java line 446 passes userToSave.getFirstName() and getLastName() directly to UserHelper.validateName(). If either returns null, String.matches() will throw NullPointerException. The validation helper does not appear to perform null checks before regex matching in the current PR changes.