implemented ssl stripping checks and hsts checks
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
package com.safeqr.app.qrcode.service;
|
||||
|
||||
import com.safeqr.app.constants.CommonConstants;
|
||||
import static com.safeqr.app.constants.CommonConstants.*;
|
||||
import com.safeqr.app.qrcode.dto.QRCodePayload;
|
||||
import com.safeqr.app.qrcode.dto.URLVerificationResponse;
|
||||
import com.safeqr.app.qrcode.entity.URLEntity;
|
||||
@@ -10,12 +10,11 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@Service
|
||||
public class URLVerificationService {
|
||||
@@ -70,15 +69,17 @@ public class URLVerificationService {
|
||||
// set query params to URL query
|
||||
urlObj.setQuery(queryParams.toString());
|
||||
// set fragment to URL ref
|
||||
urlObj.setFragment(url.getRef());
|
||||
urlObj.setFragment(Optional.ofNullable(url.getRef()).orElse(""));
|
||||
|
||||
return urlObj;
|
||||
}
|
||||
|
||||
public List<String> countAndTrackRedirects(String urlString) throws IOException, URISyntaxException {
|
||||
public void countAndTrackRedirects(String urlString, URLEntity details) throws IOException, URISyntaxException {
|
||||
URI uri = new URI(urlString);
|
||||
URL url = uri.toURL();
|
||||
List<String> redirectChain = new ArrayList<>();
|
||||
List<String> hstsHeaderList = new ArrayList<>();
|
||||
List<Boolean> sslStrippingList = new ArrayList<>();
|
||||
|
||||
// Add the initial URL to the chain
|
||||
redirectChain.add(urlString);
|
||||
@@ -86,12 +87,25 @@ public class URLVerificationService {
|
||||
int redirectCount = 0;
|
||||
|
||||
do {
|
||||
URLConnection testConnection = url.openConnection();
|
||||
|
||||
if (!(testConnection instanceof HttpURLConnection)) {
|
||||
// Handle non-HTTP connections (like mailto:)
|
||||
logger.info("Non-HTTP URL encountered: {}", url);
|
||||
hstsHeaderList.add(INFO_HSTS_NOT_APPLICABLE);
|
||||
sslStrippingList.add(false);
|
||||
break;
|
||||
}
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
connection.setInstanceFollowRedirects(false);
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
redirected = (responseCode >= 300 && responseCode < 400);
|
||||
|
||||
// Checks for HSTS Header
|
||||
hstsHeaderList.add(detectHSTSHeader(url, connection));
|
||||
|
||||
// Handle redirects
|
||||
if (redirected) {
|
||||
// Location header contains the URL to redirect to
|
||||
@@ -99,19 +113,49 @@ public class URLVerificationService {
|
||||
if (newUrl == null) {
|
||||
break;
|
||||
}
|
||||
URI newUri = uri.resolve(newUrl);
|
||||
// check for SSL stripping during redirect
|
||||
sslStrippingList.add(checkRedirectForSSLStripping(uri, newUri));
|
||||
|
||||
// Handle relative URLs
|
||||
uri = uri.resolve(newUrl);
|
||||
url = uri.toURL();
|
||||
redirectChain.add(url.toString());
|
||||
redirectCount++;
|
||||
logger.info("Redirect #{}: {}",redirectCount, newUrl);
|
||||
} else {
|
||||
// No redirect, so no SSL stripping
|
||||
sslStrippingList.add(false);
|
||||
}
|
||||
|
||||
connection.disconnect();
|
||||
} while (redirected && redirectCount < CommonConstants.MAX_REDIRECT_COUNT);
|
||||
} while (redirected && redirectCount < MAX_REDIRECT_COUNT);
|
||||
|
||||
return redirectChain;
|
||||
details.setRedirect(redirectChain.size() - 1);
|
||||
details.setRedirectChain(redirectChain);
|
||||
details.setSslStripping(sslStrippingList);
|
||||
details.setHstsHeader(hstsHeaderList);
|
||||
}
|
||||
// Function to check if the redirect is from HTTPS to HTTP
|
||||
private boolean checkRedirectForSSLStripping(URI originalUri, URI newUri) {
|
||||
return originalUri.getScheme().equalsIgnoreCase("https") &&
|
||||
newUri.getScheme().equalsIgnoreCase("http");
|
||||
}
|
||||
// Function to check if HSTS header is present for HTTPS connections
|
||||
private String detectHSTSHeader(URL url, HttpURLConnection connection) {
|
||||
if (connection instanceof HttpsURLConnection) {
|
||||
String hstsHeader = connection.getHeaderField("Strict-Transport-Security");
|
||||
if (hstsHeader != null && !hstsHeader.isEmpty()) {
|
||||
logger.info("HSTS Header detected for {}: {}", url, hstsHeader);
|
||||
return INFO_HSTS_HEADER_PREFIX + hstsHeader;
|
||||
} else {
|
||||
logger.warn("No HSTS Header for HTTPS connection to {}", url);
|
||||
return INFO_NO_HSTS_HEADER;
|
||||
}
|
||||
}
|
||||
return INFO_NON_SECURE_CONNECTION;
|
||||
}
|
||||
|
||||
public URLVerificationResponse verifyURL(QRCodePayload payload) {
|
||||
URLVerificationResponse response = new URLVerificationResponse();
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user