mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-04-22 23:08:53 +02:00
feat: Add RegexPatternUtils for centralized regex management, file naming funcs, UtilityClass annotation (#4218)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
This commit is contained in:
@@ -25,6 +25,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.common.util.RegexPatternUtils;
|
||||
import stirling.software.common.util.RequestUriUtils;
|
||||
import stirling.software.proprietary.config.AuditConfigurationProperties;
|
||||
|
||||
@@ -323,7 +324,10 @@ public class AuditUtils {
|
||||
return AuditEventType.SETTINGS_CHANGED;
|
||||
} else if (cls.contains("file")
|
||||
|| path.startsWith("/file")
|
||||
|| path.matches("(?i).*/(upload|download)/.*")) {
|
||||
|| RegexPatternUtils.getInstance()
|
||||
.getUploadDownloadPathPattern()
|
||||
.matcher(path)
|
||||
.matches()) {
|
||||
return AuditEventType.FILE_OPERATION;
|
||||
}
|
||||
}
|
||||
@@ -387,7 +391,10 @@ public class AuditUtils {
|
||||
return AuditEventType.SETTINGS_CHANGED;
|
||||
} else if (cls.contains("file")
|
||||
|| path.startsWith("/file")
|
||||
|| path.matches("(?i).*/(upload|download)/.*")) {
|
||||
|| RegexPatternUtils.getInstance()
|
||||
.getUploadDownloadPathPattern()
|
||||
.matcher(path)
|
||||
.matches()) {
|
||||
return AuditEventType.FILE_OPERATION;
|
||||
} else {
|
||||
return AuditEventType.PDF_PROCESS;
|
||||
|
||||
@@ -27,6 +27,7 @@ import stirling.software.common.model.ApplicationProperties;
|
||||
import stirling.software.common.model.ApplicationProperties.Security.OAUTH2;
|
||||
import stirling.software.common.model.ApplicationProperties.Security.SAML2;
|
||||
import stirling.software.common.model.oauth2.KeycloakProvider;
|
||||
import stirling.software.common.util.RegexPatternUtils;
|
||||
import stirling.software.common.util.UrlUtils;
|
||||
import stirling.software.proprietary.audit.AuditEventType;
|
||||
import stirling.software.proprietary.audit.AuditLevel;
|
||||
@@ -250,6 +251,9 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
||||
* @return a sanitised <code>String</code>
|
||||
*/
|
||||
private String sanitizeInput(String input) {
|
||||
return input.replaceAll("[^a-zA-Z0-9 ]", "");
|
||||
return RegexPatternUtils.getInstance()
|
||||
.getInputSanitizePattern()
|
||||
.matcher(input)
|
||||
.replaceAll("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.common.model.ApplicationProperties;
|
||||
import stirling.software.common.util.GeneralUtils;
|
||||
import stirling.software.common.util.RegexPatternUtils;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@@ -117,7 +118,11 @@ public class KeygenLicenseVerifier {
|
||||
// Remove the footer
|
||||
encodedPayload = encodedPayload.replace(CERT_SUFFIX, "");
|
||||
// Remove all newlines
|
||||
encodedPayload = encodedPayload.replaceAll("\\r?\\n", "");
|
||||
encodedPayload =
|
||||
RegexPatternUtils.getInstance()
|
||||
.getEncodedPayloadNewlinePattern()
|
||||
.matcher(encodedPayload)
|
||||
.replaceAll("");
|
||||
|
||||
byte[] payloadBytes = Base64.getDecoder().decode(encodedPayload);
|
||||
String payload = new String(payloadBytes);
|
||||
|
||||
@@ -36,6 +36,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.common.model.ApplicationProperties;
|
||||
import stirling.software.common.util.GeneralUtils;
|
||||
import stirling.software.common.util.RegexPatternUtils;
|
||||
import stirling.software.proprietary.security.model.api.admin.SettingValueResponse;
|
||||
import stirling.software.proprietary.security.model.api.admin.UpdateSettingValueRequest;
|
||||
import stirling.software.proprietary.security.model.api.admin.UpdateSettingsRequest;
|
||||
@@ -444,7 +445,8 @@ public class AdminSettingsController {
|
||||
"legal");
|
||||
|
||||
// Pattern to validate safe property paths - only alphanumeric, dots, and underscores
|
||||
private static final Pattern SAFE_KEY_PATTERN = Pattern.compile("^[a-zA-Z0-9._]+$");
|
||||
private static final Pattern SAFE_KEY_PATTERN =
|
||||
RegexPatternUtils.getInstance().getPattern("^[a-zA-Z0-9._]+$");
|
||||
private static final int MAX_NESTING_DEPTH = 10;
|
||||
|
||||
// Security: Generic error messages to prevent information disclosure
|
||||
|
||||
@@ -25,6 +25,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import stirling.software.common.model.enumeration.Role;
|
||||
import stirling.software.common.util.RegexPatternUtils;
|
||||
|
||||
@Component
|
||||
public class UserBasedRateLimitingFilter extends OncePerRequestFilter {
|
||||
@@ -143,6 +144,6 @@ public class UserBasedRateLimitingFilter extends OncePerRequestFilter {
|
||||
}
|
||||
|
||||
private static String stripNewlines(final String s) {
|
||||
return s.replaceAll("[\n\r]", "");
|
||||
return RegexPatternUtils.getInstance().getNewlineCharsPattern().matcher(s).replaceAll("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,8 +75,11 @@ public class CustomUserDetailsService implements UserDetailsService {
|
||||
*/
|
||||
private AuthenticationType determinePreferredSSOType() {
|
||||
// Check what SSO types are enabled and prefer in order: OAUTH2 > SAML2 > fallback to OAUTH2
|
||||
boolean oauth2Enabled = securityProperties.getOauth2() != null && securityProperties.getOauth2().getEnabled();
|
||||
boolean saml2Enabled = securityProperties.getSaml2() != null && securityProperties.getSaml2().getEnabled();
|
||||
boolean oauth2Enabled =
|
||||
securityProperties.getOauth2() != null
|
||||
&& securityProperties.getOauth2().getEnabled();
|
||||
boolean saml2Enabled =
|
||||
securityProperties.getSaml2() != null && securityProperties.getSaml2().getEnabled();
|
||||
|
||||
if (oauth2Enabled) {
|
||||
return AuthenticationType.OAUTH2;
|
||||
|
||||
@@ -31,6 +31,7 @@ import stirling.software.common.model.ApplicationProperties;
|
||||
import stirling.software.common.model.enumeration.Role;
|
||||
import stirling.software.common.model.exception.UnsupportedProviderException;
|
||||
import stirling.software.common.service.UserServiceInterface;
|
||||
import stirling.software.common.util.RegexPatternUtils;
|
||||
import stirling.software.proprietary.model.Team;
|
||||
import stirling.software.proprietary.security.database.repository.AuthorityRepository;
|
||||
import stirling.software.proprietary.security.database.repository.UserRepository;
|
||||
@@ -480,13 +481,18 @@ public class UserService implements UserServiceInterface {
|
||||
// Checks whether the simple username is formatted correctly
|
||||
// Regular expression for user name: Min. 3 characters, max. 50 characters
|
||||
boolean isValidSimpleUsername =
|
||||
username.matches("^[a-zA-Z0-9](?!.*[-@._+]{2,})[a-zA-Z0-9@._+-]{1,48}[a-zA-Z0-9]$");
|
||||
RegexPatternUtils.getInstance()
|
||||
.getUsernameValidationPattern()
|
||||
.matcher(username)
|
||||
.matches();
|
||||
|
||||
// Checks whether the email address is formatted correctly
|
||||
// Regular expression for email addresses: Max. 320 characters, with RFC-like validation
|
||||
boolean isValidEmail =
|
||||
username.matches(
|
||||
"^(?=.{1,320}$)(?=.{1,64}@)[A-Za-z0-9](?:[A-Za-z0-9_.+-]*[A-Za-z0-9])?@[^-][A-Za-z0-9-]+(?:\\\\.[A-Za-z0-9-]+)*(?:\\\\.[A-Za-z]{2,})$");
|
||||
RegexPatternUtils.getInstance()
|
||||
.getEmailValidationPattern()
|
||||
.matcher(username)
|
||||
.matches();
|
||||
|
||||
List<String> notAllowedUserList = new ArrayList<>();
|
||||
notAllowedUserList.add("ALL_USERS".toLowerCase());
|
||||
|
||||
@@ -7,13 +7,16 @@ import java.util.stream.Collectors;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.common.util.RegexPatternUtils;
|
||||
|
||||
/** Redacts any map values whose keys match common secret/token patterns. */
|
||||
@Slf4j
|
||||
public final class SecretMasker {
|
||||
|
||||
private static final Pattern SENSITIVE =
|
||||
Pattern.compile(
|
||||
"(?i)(password|token|secret|api[_-]?key|authorization|auth|jwt|cred|cert)");
|
||||
RegexPatternUtils.getInstance()
|
||||
.getPattern(
|
||||
"(?i)(password|token|secret|api[_-]?key|authorization|auth|jwt|cred|cert)");
|
||||
|
||||
private SecretMasker() {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user