hide empty values in dto and edited check endcoded url for false positive

This commit is contained in:
ltiongku
2024-08-06 20:21:47 +08:00
parent 3eb53c6ccd
commit 529d27d07c
2 changed files with 51 additions and 10 deletions

View File

@@ -1,6 +1,7 @@
package com.safeqr.app.qrcode.entity; package com.safeqr.app.qrcode.entity;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.hypersistence.utils.hibernate.type.array.ListArrayType; import io.hypersistence.utils.hibernate.type.array.ListArrayType;
import jakarta.persistence.*; import jakarta.persistence.*;
@@ -35,53 +36,82 @@ public class URLEntity {
private String domain; private String domain;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String subdomain; private String subdomain;
private String topLevelDomain; private String topLevelDomain;
private String path; private String path;
@JsonProperty
private String query; private String query;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String fragment; private String fragment;
private int redirect = 0; private int redirect = 0;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Type(ListArrayType.class) @Type(ListArrayType.class)
@Column(name = "hsts_header", columnDefinition = "text[]") @Column(name = "hsts_header", columnDefinition = "text[]")
private List<String> hstsHeader = new ArrayList<>(); private List<String> hstsHeader = new ArrayList<>();
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Type(ListArrayType.class) @Type(ListArrayType.class)
@Column(name = "ssl_stripping", columnDefinition = "boolean[]") @Column(name = "ssl_stripping", columnDefinition = "boolean[]")
private List<Boolean> sslStripping = new ArrayList<>(); private List<Boolean> sslStripping = new ArrayList<>();
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Type(ListArrayType.class) @Type(ListArrayType.class)
@Column(name = "redirect_chain", columnDefinition = "text[]") @Column(name = "redirect_chain", columnDefinition = "text[]")
private List<String> redirectChain = new ArrayList<>(); private List<String> redirectChain = new ArrayList<>();
@Column(name = "hostname_embedding") @Column(name = "hostname_embedding")
private int hostnameEmbedding = 0; private Integer hostnameEmbedding = 0;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Column(name = "javascript_check") @Column(name = "javascript_check")
private String javascriptCheck = ""; private String javascriptCheck = "";
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Column(name = "shortening_service") @Column(name = "shortening_service")
private String shorteningService = ""; private String shorteningService = "";
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Column(name = "has_ip_address") @Column(name = "has_ip_address")
private String hasIpAddress = ""; private String hasIpAddress = "";
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Type(ListArrayType.class) @Type(ListArrayType.class)
@Column(name = "tracking_descriptions", columnDefinition = "text[]") @Column(name = "tracking_descriptions", columnDefinition = "text[]")
private List<String> trackingDescriptions = new ArrayList<>(); private List<String> trackingDescriptions = new ArrayList<>();
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Column(name = "url_encoding") @Column(name = "url_encoding")
private String urlEncoding = ""; private String urlEncoding = "";
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Column(name = "dns_error") @Column(name = "dns_error")
private String dnsError = ""; private String dnsError = "";
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Column(name="ssl_error") @Column(name="ssl_error")
private String sslError = ""; private String sslError = "";
// Custom getter for hostnameEmbedding
@JsonInclude(JsonInclude.Include.NON_NULL)
public Integer getHostnameEmbedding() {
return hostnameEmbedding == 0 ? null : hostnameEmbedding;
}
// Custom getter for path
@JsonInclude(JsonInclude.Include.NON_NULL)
public String getPath() {
return path.isEmpty() ? null : path;
}
// Custom getter for query
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty
public String getQuery() {
return query.equals("{}") ? null : query;
}
} }

View File

@@ -71,7 +71,8 @@ public class URLVerificationService {
public URLEntity breakdownURL(String urlString) { public URLEntity breakdownURL(String urlString) {
URLEntity urlObj = new URLEntity(); URLEntity urlObj = new URLEntity();
try { try {
URL url = new URI(encodeUrl(urlString)).toURL(); //URL url = new URI(encodeUrl(urlString)).toURL();
URL url = new URI(urlString).toURL();
String host = url.getHost(); String host = url.getHost();
// Check for deceptive URL // Check for deceptive URL
@@ -88,15 +89,22 @@ public class URLVerificationService {
populateHostDetails(host, urlObj); populateHostDetails(host, urlObj);
urlObj.setPath(Optional.ofNullable(url.getPath()).filter(p -> !p.isEmpty()).orElse("/")); urlObj.setPath(Optional.ofNullable(url.getPath()).filter(p -> !p.isEmpty()).orElse(""));
urlObj.setQuery(parseQueryParams(url.getQuery()));
String query = parseQueryParams(url.getQuery());
urlObj.setQuery(query);
urlObj.setFragment(Optional.ofNullable(url.getRef()).orElse("")); urlObj.setFragment(Optional.ofNullable(url.getRef()).orElse(""));
// Check for tracking parameters // Check for tracking parameters
urlObj.setTrackingDescriptions(getTrackingDescriptions(url.getQuery())); urlObj.setTrackingDescriptions(getTrackingDescriptions(url.getQuery()));
// Check for URL encoding // Check for URL encoding in path and query
urlObj.setUrlEncoding(checkURLEncoding(url.getPath())); String pathEncoding = checkURLEncoding(url.getPath());
String queryEncoding = query != null ? checkURLEncoding(query) : "";
// Combine encoding results
urlObj.setUrlEncoding(pathEncoding.equals("Yes") || queryEncoding.equals("Yes") ? "Yes" : "");
} catch (Exception e) { } catch (Exception e) {
logger.error("Error in breaking down URL: {}", e.getMessage()); logger.error("Error in breaking down URL: {}", e.getMessage());
} }
@@ -171,6 +179,9 @@ public class URLVerificationService {
} }
private String checkForJavascriptCode(String url) { private String checkForJavascriptCode(String url) {
// Decode the URL
String decodedUrl = URLDecoder.decode(url, StandardCharsets.UTF_8);
// Patterns to detect 'javascript:', '<script>', and 'on*=' attributes // Patterns to detect 'javascript:', '<script>', and 'on*=' attributes
List<Pattern> maliciousPatterns = Arrays.asList( List<Pattern> maliciousPatterns = Arrays.asList(
Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE), Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),
@@ -180,7 +191,7 @@ public class URLVerificationService {
// Check for any malicious pattern in the URL // Check for any malicious pattern in the URL
for (Pattern pattern : maliciousPatterns) { for (Pattern pattern : maliciousPatterns) {
Matcher matcher = pattern.matcher(url); Matcher matcher = pattern.matcher(decodedUrl);
if (matcher.find()) { if (matcher.find()) {
return "Javascript found in URL."; return "Javascript found in URL.";
} }
@@ -196,9 +207,9 @@ public class URLVerificationService {
} }
// Function to check text encoding in a URL // Function to check text encoding in a URL
private static String checkURLEncoding(String pathTextPart) throws UnsupportedEncodingException { private static String checkURLEncoding(String pathTextPart) {
// Decode the text // Decode the text
String decodedText = URLDecoder.decode(pathTextPart, StandardCharsets.UTF_8.name()); String decodedText = URLDecoder.decode(pathTextPart, StandardCharsets.UTF_8);
// Check if the decoded text matches the original text // Check if the decoded text matches the original text
return decodedText.equals(pathTextPart) ? "" : "Yes"; return decodedText.equals(pathTextPart) ? "" : "Yes";