add XSS content filter to DTOs

This commit is contained in:
2026-04-20 10:45:45 -06:00
parent ea73ab687b
commit b4c9940013
9 changed files with 51 additions and 0 deletions

View File

@@ -1,10 +1,12 @@
package com.petshop.backend.dto.category;
import com.petshop.backend.util.SafeContent;
import jakarta.validation.constraints.NotBlank;
import java.util.Objects;
public class CategoryRequest {
@NotBlank(message = "Category name is required")
@SafeContent
private String categoryName;
private String categoryType;

View File

@@ -1,5 +1,6 @@
package com.petshop.backend.dto.pet;
import com.petshop.backend.util.SafeContent;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@@ -11,6 +12,7 @@ import java.util.Objects;
public class PetRequest {
@NotBlank(message = "Pet name is required")
@SafeContent
private String petName;
@NotBlank(message = "Species is required")

View File

@@ -1,5 +1,6 @@
package com.petshop.backend.dto.product;
import com.petshop.backend.util.SafeContent;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
@@ -8,11 +9,13 @@ import java.util.Objects;
public class ProductRequest {
@NotBlank(message = "Product name is required")
@SafeContent
private String prodName;
@NotNull(message = "Category ID is required")
private Long categoryId;
@SafeContent
private String prodDesc;
@NotNull(message = "Product price is required")

View File

@@ -1,5 +1,6 @@
package com.petshop.backend.dto.service;
import com.petshop.backend.util.SafeContent;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
@@ -10,8 +11,10 @@ import java.util.Set;
public class ServiceRequest {
@NotBlank(message = "Service name is required")
@SafeContent
private String serviceName;
@SafeContent
private String serviceDesc;
@NotNull(message = "Service price is required")

View File

@@ -1,11 +1,13 @@
package com.petshop.backend.dto.store;
import com.petshop.backend.util.SafeContent;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import java.util.Objects;
public class StoreRequest {
@NotBlank(message = "Store name is required")
@SafeContent
private String storeName;
@NotBlank(message = "Address is required")

View File

@@ -1,5 +1,6 @@
package com.petshop.backend.dto.supplier;
import com.petshop.backend.util.SafeContent;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import java.util.Objects;

View File

@@ -1,5 +1,6 @@
package com.petshop.backend.dto.user;
import com.petshop.backend.util.SafeContent;
import com.petshop.backend.entity.User;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
@@ -15,10 +16,12 @@ public class UserRequest {
private String password;
@NotBlank(message = "First name is required")
@SafeContent
@Size(max = 50)
private String firstName;
@NotBlank(message = "Last name is required")
@SafeContent
@Size(max = 50)
private String lastName;

View File

@@ -0,0 +1,17 @@
package com.petshop.backend.util;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = SafeContentValidator.class)
public @interface SafeContent {
String message() default "Content contains prohibited characters or scripts";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@@ -0,0 +1,18 @@
package com.petshop.backend.util;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
public class SafeContentValidator implements ConstraintValidator<SafeContent, String> {
private static final Pattern DANGEROUS = Pattern.compile(
"<script|</script|javascript:|on\\w+\\s*=|<iframe|<object|<embed|<form|<input|<img[^>]+on\\w+",
Pattern.CASE_INSENSITIVE);
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null || value.isBlank()) return true;
return !DANGEROUS.matcher(value).find();
}
}