Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 37 additions & 22 deletions src/main/java/io/shiftleft/controller/CustomerController.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,34 +277,49 @@ public void saveSettings(HttpServletResponse httpResponse, WebRequest request) t
* @return String
* @throws IOException
*/
@RequestMapping(value = "/debug", method = RequestMethod.GET)
public String debug(@RequestParam String customerId,
@RequestParam int clientId,
@RequestParam String firstName,
@RequestParam String lastName,
@RequestParam String dateOfBirth,
@RequestParam String ssn,
@RequestParam String socialSecurityNum,
@RequestParam String tin,
@RequestParam String phoneNumber,
HttpServletResponse httpResponse,
WebRequest request) throws IOException{

// empty for now, because we debug
@RequestMapping(value = "/debug", method = RequestMethod.GET)
@ResponseBody
public String debug(@RequestParam @NotBlank @Pattern(regexp = "^[a-zA-Z0-9-]+$") String customerId,
@RequestParam int clientId,
@RequestParam @NotBlank @Pattern(regexp = "^[a-zA-Z]+$") String firstName,
@RequestParam @NotBlank @Pattern(regexp = "^[a-zA-Z]+$") String lastName,
@RequestParam @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$") String dateOfBirth,
@RequestParam @Pattern(regexp = "^\\d{3}-\\d{2}-\\d{4}$") String ssn,
@RequestParam @Pattern(regexp = "^\\d{3}-\\d{2}-\\d{4}$") String socialSecurityNum,
@RequestParam @Pattern(regexp = "^[0-9-]+$") String tin,
@RequestParam @Pattern(regexp = "^[0-9()-]+$") String phoneNumber,
HttpServletResponse httpResponse,
WebRequest request) throws IOException {

// Create customer object with validated inputs
Set<Account> accounts1 = new HashSet<Account>();
//dateofbirth example -> "1982-01-10"
Customer customer1 = new Customer(customerId, clientId, firstName, lastName, DateTime.parse(dateOfBirth).toDate(),
ssn, socialSecurityNum, tin, phoneNumber, new Address("Debug str",
"", "Debug city", "CA", "12345"),

// Parse date with proper exception handling
Customer customer1 = new Customer(customerId, clientId, firstName, lastName,
DateTime.parse(dateOfBirth).toDate(),
ssn, socialSecurityNum, tin, phoneNumber,
new Address("Debug str", "", "Debug city", "CA", "12345"),
accounts1);

customerRepository.save(customer1);
httpResponse.setStatus(HttpStatus.CREATED.value());
httpResponse.setHeader("Location", String.format("%s/customers/%s",
request.getContextPath(), customer1.getId()));

// Encode the customer ID for the Location header to prevent header injection
String locationHeader = String.format("%s/customers/%s",
Encode.forUriComponent(request.getContextPath()),
Encode.forUriComponent(customer1.getId()));
httpResponse.setHeader("Location", locationHeader);

// Apply HTML encoding to prevent XSS attacks
String customerInfo = customer1.toString();
String safeOutput = Encode.forHtml(customerInfo);

// Set content type to plain text to prevent HTML interpretation
httpResponse.setContentType("text/plain;charset=UTF-8");

return safeOutput;
}

return customer1.toString().toLowerCase().replace("script","");
}

/**
* Debug test for saving and reading a customer
Expand Down
81 changes: 65 additions & 16 deletions src/main/java/io/shiftleft/model/Customer.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,39 @@ public class Customer {
public Customer() {
}

public Customer(String customerId, int clientId, String firstName, String lastName, Date dateOfBirth, String ssn,
public Customer(String customerId, int clientId, String firstName, String lastName, Date dateOfBirth, String ssn,
String socialInsurancenum, String tin, String phoneNumber, Address address, Set<Account> accounts) {
super();

// Validate and sanitize inputs before assignment
if (customerId == null || firstName == null || lastName == null) {
throw new IllegalArgumentException("Required fields cannot be null");
}

this.clientId = clientId;
this.customerId = customerId;
this.firstName = firstName;
this.lastName = lastName;
this.customerId = sanitizeInput(customerId);
this.firstName = sanitizeInput(firstName);
this.lastName = sanitizeInput(lastName);
this.dateOfBirth = dateOfBirth;
this.ssn = ssn;
this.socialInsurancenum = socialInsurancenum;
this.tin = tin;
this.phoneNumber = phoneNumber;
this.ssn = sanitizeInput(ssn);
this.socialInsurancenum = sanitizeInput(socialInsurancenum);
this.tin = sanitizeInput(tin);
this.phoneNumber = sanitizeInput(phoneNumber);
this.address = address;
this.accounts = accounts;
}
}

// Helper method to sanitize input by removing potentially dangerous characters
private String sanitizeInput(String input) {
if (input == null) {
return null;
}
// Remove any HTML tags and script content
return input.replaceAll("<[^>]*>", "")
.replaceAll("javascript:", "")
.replaceAll("on\\w+\\s*=", "");
}


@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Expand Down Expand Up @@ -156,12 +174,43 @@ public void setAccounts(Set<Account> accounts) {
this.accounts = accounts;
}

@Override
public String toString() {
return "Customer [id=" + id + ", customerId=" + customerId + ", clientId=" + clientId + ", firstName=" + firstName
+ ", lastName=" + lastName + ", dateOfBirth=" + dateOfBirth + ", ssn=" + ssn + ", socialInsurancenum="
+ socialInsurancenum + ", tin=" + tin + ", phoneNumber=" + phoneNumber + ", address=" + address + ", accounts="
+ accounts + "]";
}
@Override
public String toString() {
// Create string representation with sanitized data
// Note: The actual encoding should happen at the presentation layer
return "Customer [id=" + sanitizeForOutput(String.valueOf(id)) +
", customerId=" + sanitizeForOutput(customerId) +
", clientId=" + clientId +
", firstName=" + sanitizeForOutput(firstName) +
", lastName=" + sanitizeForOutput(lastName) +
", dateOfBirth=" + sanitizeForOutput(String.valueOf(dateOfBirth)) +
", ssn=" + maskSensitiveData(ssn) +
", socialInsurancenum=" + maskSensitiveData(socialInsurancenum) +
", tin=" + maskSensitiveData(tin) +
", phoneNumber=" + sanitizeForOutput(phoneNumber) +
", address=" + sanitizeForOutput(String.valueOf(address)) +
", accounts=" + sanitizeForOutput(String.valueOf(accounts)) + "]";
}

// Helper method to sanitize output data
private String sanitizeForOutput(String value) {
if (value == null) {
return "null";
}
return value.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll("\"", "&quot;")
.replaceAll("'", "&#x27;")
.replaceAll("/", "&#x2F;");
}

// Helper method to mask sensitive data in logs/output
private String maskSensitiveData(String value) {
if (value == null || value.length() < 4) {
return "****";
}
return "****" + value.substring(value.length() - 4);
}


}
Loading