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
87 changes: 65 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,77 @@ 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 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 {

// Validate and sanitize all input parameters before processing
// This prevents XSS by ensuring no malicious scripts are stored
String sanitizedCustomerId = sanitizeInput(customerId);
String sanitizedFirstName = sanitizeInput(firstName);
String sanitizedLastName = sanitizeInput(lastName);
String sanitizedSsn = sanitizeInput(ssn);
String sanitizedSocialSecurityNum = sanitizeInput(socialSecurityNum);
String sanitizedTin = sanitizeInput(tin);
String sanitizedPhoneNumber = sanitizeInput(phoneNumber);

// Validate date format to prevent injection attacks
Date parsedDate;
try {
parsedDate = DateTime.parse(dateOfBirth).toDate();
} catch (IllegalArgumentException e) {
httpResponse.setStatus(HttpStatus.BAD_REQUEST.value());
return Encode.forHtml("Invalid date format provided");
}

// Create customer with sanitized 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"),
Customer customer1 = new Customer(sanitizedCustomerId, clientId, sanitizedFirstName,
sanitizedLastName, parsedDate,
sanitizedSsn, sanitizedSocialSecurityNum,
sanitizedTin, sanitizedPhoneNumber,
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()));

// Sanitize the Location header to prevent header injection
String location = String.format("%s/customers/%s",
sanitizeInput(request.getContextPath()),
sanitizeInput(customer1.getId()));
httpResponse.setHeader("Location", location);

// Use OWASP encoder to HTML-encode output before returning
// This prevents XSS by ensuring any HTML special characters are encoded
String customerInfo = customer1.toSafeString();
return Encode.forHtml(customerInfo);
}

// Helper method to sanitize input by removing potentially dangerous characters
private String sanitizeInput(String input) {
if (input == null) {
return "";
}
// Remove any HTML tags and special characters that could be used for XSS
return input.replaceAll("<", "")
.replaceAll(">", "")
.replaceAll("\"", "")
.replaceAll("'", "")
.replaceAll("&", "")
.trim();
}

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

/**
* Debug test for saving and reading a customer
Expand Down
63 changes: 51 additions & 12 deletions src/main/java/io/shiftleft/model/Customer.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,37 @@ 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();
// Store sanitized values to prevent XSS at the data layer
this.clientId = clientId;
this.customerId = customerId;
this.firstName = firstName;
this.lastName = lastName;
this.customerId = sanitizeField(customerId);
this.firstName = sanitizeField(firstName);
this.lastName = sanitizeField(lastName);
this.dateOfBirth = dateOfBirth;
this.ssn = ssn;
this.socialInsurancenum = socialInsurancenum;
this.tin = tin;
this.phoneNumber = phoneNumber;
this.ssn = sanitizeField(ssn);
this.socialInsurancenum = sanitizeField(socialInsurancenum);
this.tin = sanitizeField(tin);
this.phoneNumber = sanitizeField(phoneNumber);
this.address = address;
this.accounts = accounts;
}
}

// Helper method to sanitize fields at the model level
private String sanitizeField(String field) {
if (field == null) {
return "";
}
// Remove potentially dangerous characters
return field.replaceAll("<", "")
.replaceAll(">", "")
.replaceAll("\"", "")
.replaceAll("'", "")
.replaceAll("&", "")
.trim();
}


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

@Override
public String toString() {
@Override
public String toString() {
// This method should not be used for HTML output
// Use toSafeString() instead for web responses
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 + "]";
}
}

// New method specifically for safe HTML output
public String toSafeString() {
// Return a safe representation that can be HTML-encoded
// Avoid exposing sensitive information like full SSN, TIN in debug output
return "Customer [id=" + id + ", customerId=" + customerId + ", clientId=" + clientId
+ ", firstName=" + firstName + ", lastName=" + lastName + ", dateOfBirth=" + dateOfBirth
+ ", ssn=" + maskSensitiveData(ssn) + ", socialInsurancenum=" + maskSensitiveData(socialInsurancenum)
+ ", tin=" + maskSensitiveData(tin) + ", phoneNumber=" + phoneNumber
+ ", address=" + address + ", accounts=" + accounts + "]";
}

// Helper method to mask sensitive data
private String maskSensitiveData(String data) {
if (data == null || data.length() < 4) {
return "***";
}
// Show only last 4 characters
return "***" + data.substring(data.length() - 4);
}


}
Loading