Merge remote-tracking branch 'origin/feature-ml-integration' into dev

This commit is contained in:
heyethereum
2024-08-14 00:56:44 +08:00
3 changed files with 66 additions and 35 deletions

View File

@@ -1,18 +1,22 @@
package com.safeqr.app.prediction.model; package com.safeqr.app.prediction.model;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.safeqr.app.qrcode.entity.QRCodeTypeEntity;
import com.safeqr.app.qrcode.entity.URLEntity;
import com.safeqr.app.qrcode.model.URLModel; import com.safeqr.app.qrcode.model.URLModel;
import lombok.*; import lombok.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Getter @Getter
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class URLFeatures { public class URLFeaturesMapper {
private static final Logger logger = LoggerFactory.getLogger(URLFeaturesMapper.class);
@JsonProperty("domain") @JsonProperty("domain")
private Integer domain; private Integer domain;
@@ -70,27 +74,29 @@ public class URLFeatures {
@JsonProperty("contents") @JsonProperty("contents")
private Integer contents; private Integer contents;
public static URLFeatures fromEntity(URLModel urlModel) { public static URLFeaturesMapper fromEntity(URLModel urlModel) {
URLFeatures features = URLFeatures.builder() URLEntity details = urlModel.getDetails();
QRCodeTypeEntity qrCodeTypeEntity = urlModel.getData().getInfo();
URLFeaturesMapper features = URLFeaturesMapper.builder()
.build(); .build();
features.setDomain(urlModel.getDetails().getDomain()); features.setDomain(details.getDomain());
features.setSubdomain(urlModel.getDetails().getSubdomain()); features.setSubdomain(details.getSubdomain());
features.setTopLevelDomain(urlModel.getDetails().getTopLevelDomain()); features.setTopLevelDomain(details.getTopLevelDomain());
features.setQuery(urlModel.getDetails().getQuery()); features.setQuery(details.getQuery());
features.setFragment(urlModel.getDetails().getFragment()); features.setFragment(details.getFragment());
features.setPath(urlModel.getDetails().getPath()); features.setPath(details.getPath());
features.setRedirect(urlModel.getDetails().getRedirect()); features.setRedirect(details.getRedirect());
features.setRedirectChain(urlModel.getDetails().getRedirectChain()); features.setRedirectChain(details.getRedirectChain());
features.setHstsHeader(urlModel.getDetails().getHstsHeader()); features.setHstsHeader(details.getHstsHeader());
features.setSslStripping(urlModel.getDetails().getSslStripping()); features.setSslStripping(details.getSslStripping());
features.setHostnameEmbedding(urlModel.getDetails().getHostnameEmbedding()); features.setHostnameEmbedding(details.getHostnameEmbedding());
features.setJavascriptCheck(urlModel.getDetails().getJavascriptCheck()); features.setJavascriptCheck(details.getJavascriptCheck());
features.setShorteningService(urlModel.getDetails().getShorteningService()); features.setShorteningService(details.getShorteningService());
features.setHasIpAddress(urlModel.getDetails().getHasIpAddress()); features.setHasIpAddress(details.getHasIpAddress());
features.setTrackingDescriptions(urlModel.getDetails().getTrackingDescriptions()); features.setTrackingDescriptions(details.getTrackingDescriptions());
features.setUrlEncoding(urlModel.getDetails().getUrlEncoding()); features.setUrlEncoding(details.getUrlEncoding());
features.setHasExecutable(urlModel.getDetails().getHasExecutable()); features.setHasExecutable(details.getHasExecutable());
features.setTls(Math.toIntExact(urlModel.getData().getInfo().getId())); features.setTls(Math.toIntExact(qrCodeTypeEntity.getId()));
features.setContents(urlModel.getData().getContents()); features.setContents(urlModel.getData().getContents());
return features; return features;
@@ -149,18 +155,16 @@ public class URLFeatures {
// Custom setter for hstsHeader // Custom setter for hstsHeader
public void setHstsHeader(List<String> hstsHeader) { public void setHstsHeader(List<String> hstsHeader) {
logger.info("HSTS header value: {}", hstsHeader);
if (hstsHeader == null || hstsHeader.isEmpty()) { if (hstsHeader == null || hstsHeader.isEmpty()) {
this.hstsHeader = 0; this.hstsHeader = 0;
} else if (hstsHeader.get(0).startsWith("{") && hstsHeader.get(0).endsWith("}")) { } else {
Pattern pattern = Pattern.compile("\"(.*?)\""); logger.info("first hsts header value: {}", hstsHeader.get(0));
Matcher matcher = pattern.matcher(hstsHeader.get(0)); if (hstsHeader.get(0).toLowerCase().contains("no")) {
if (matcher.find() && matcher.group(1).toLowerCase().contains("no")) {
this.hstsHeader = 0; this.hstsHeader = 0;
} else { } else {
this.hstsHeader = 1; this.hstsHeader = 1;
} }
} else {
this.hstsHeader = 1;
} }
} }
@@ -190,7 +194,17 @@ public class URLFeatures {
} }
public void setRedirectChain(List<String> redirectChain) { public void setRedirectChain(List<String> redirectChain) {
this.redirectChain = (redirectChain != null) ? redirectChain.size() : 0; logger.info("Redirect chain: {}", redirectChain);
if (redirectChain != null) {
// Calculate the total number of characters in the list of strings
int totalChars;
totalChars = redirectChain.stream()
.mapToInt(String::length)
.sum();
this.redirectChain = totalChars;
} else {
this.redirectChain = 0;
}
} }
public void setContents(String contents) { public void setContents(String contents) {

View File

@@ -1,7 +1,7 @@
package com.safeqr.app.prediction.service; package com.safeqr.app.prediction.service;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.safeqr.app.prediction.model.URLFeatures; import com.safeqr.app.prediction.model.URLFeaturesMapper;
import com.safeqr.app.qrcode.model.URLModel; import com.safeqr.app.qrcode.model.URLModel;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -29,15 +29,32 @@ public class PredictionService {
public String predict(URLModel urlModel) { public String predict(URLModel urlModel) {
// Convert URLModel to URLFeatures // Convert URLModel to URLFeatures
URLFeatures features = URLFeatures.fromEntity(urlModel); URLFeaturesMapper features = URLFeaturesMapper.fromEntity(urlModel);
logger.info("Prediction request: {}", features); logger.info("Prediction request: {}", features);
logger.info("feature contents : {}", features.getContents());
logger.info("feature domain : {}", features.getDomain());
logger.info("feature sub-domain : {}", features.getSubdomain());
logger.info("feature tld : {}", features.getTopLevelDomain());
logger.info("feature path : {}", features.getPath());
logger.info("feature query : {}", features.getQuery());
logger.info("feature fragment : {}", features.getFragment());
logger.info("feature redirect : {}", features.getRedirect());
logger.info("feature redirect chain: {}", features.getRedirectChain());
logger.info("feature shortening service: {}", features.getShorteningService());
logger.info("feature hasExecutable: {}", features.getHasExecutable());
logger.info("feature hasIP: {}", features.getHasIpAddress());
logger.info("feature hostname embedding: {}", features.getHostnameEmbedding());
logger.info("feature hsts header: {}", features.getHstsHeader());
logger.info("feature javascript check: {}", features.getJavascriptCheck());
logger.info("feature tracking: {}", features.getTrackingDescriptions());
logger.info("feature urlencoding: {}", features.getUrlEncoding());
// Prepare the HTTP headers // Prepare the HTTP headers
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentType(MediaType.APPLICATION_JSON);
// Create the HTTP entity containing the features and headers // Create the HTTP entity containing the features and headers
HttpEntity<URLFeatures> requestEntity = new HttpEntity<>(features, headers); HttpEntity<URLFeaturesMapper> requestEntity = new HttpEntity<>(features, headers);
// Make the HTTP POST request to the FastAPI prediction endpoint // Make the HTTP POST request to the FastAPI prediction endpoint
ResponseEntity<String> response = restTemplate.exchange( ResponseEntity<String> response = restTemplate.exchange(

View File

@@ -60,8 +60,8 @@ public class URLVerificationService {
// Define a Set of suspicious file extensions // Define a Set of suspicious file extensions
private static final Set<String> SUSPICIOUS_EXTENSIONS = Stream.of( private static final Set<String> SUSPICIOUS_EXTENSIONS = Stream.of(
".exe", ".bat", ".sh", ".cmd", ".scr", ".pif", ".application", ".gadget", ".exe", ".bat", ".sh", ".cmd", ".scr", ".pif", ".application", ".gadget",
".vb", ".vbs", ".js", ".jse", ".ws", ".wsf", ".msc", ".com", ".cpl", ".vb", ".vbs", ".js", ".jse", ".ws", ".wsf", ".msc", ".cpl",
".msi", ".ps1", ".py", ".pyc", ".pyo", ".rb", ".app", ".bin", ".run" ".msi", ".ps1", ".py", ".pyc", ".pyo", ".rb", ".bin", ".run"
).collect(Collectors.toUnmodifiableSet()); ).collect(Collectors.toUnmodifiableSet());
// Checks if the URL has executable file // Checks if the URL has executable file