mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-05-30 05:42:00 +00:00
disable fingerpritning
This commit is contained in:
parent
c59d3ff3e0
commit
3b5b7772a9
@ -1,68 +1,68 @@
|
|||||||
package stirling.software.SPDF.config.fingerprint;
|
//package stirling.software.SPDF.config.fingerprint;
|
||||||
|
//
|
||||||
import java.io.IOException;
|
//import java.io.IOException;
|
||||||
|
//
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
//import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
//import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
//import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
//
|
||||||
import jakarta.servlet.FilterChain;
|
//import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
//import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
//import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
//import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.servlet.http.HttpSession;
|
//import jakarta.servlet.http.HttpSession;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
//import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.utils.RequestUriUtils;
|
//import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
//
|
||||||
@Component
|
////@Component
|
||||||
@Slf4j
|
//@Slf4j
|
||||||
public class FingerprintBasedSessionFilter extends OncePerRequestFilter {
|
//public class FingerprintBasedSessionFilter extends OncePerRequestFilter {
|
||||||
private final FingerprintGenerator fingerprintGenerator;
|
// private final FingerprintGenerator fingerprintGenerator;
|
||||||
private final FingerprintBasedSessionManager sessionManager;
|
// private final FingerprintBasedSessionManager sessionManager;
|
||||||
|
//
|
||||||
@Autowired
|
// @Autowired
|
||||||
public FingerprintBasedSessionFilter(
|
// public FingerprintBasedSessionFilter(
|
||||||
FingerprintGenerator fingerprintGenerator,
|
// FingerprintGenerator fingerprintGenerator,
|
||||||
FingerprintBasedSessionManager sessionManager) {
|
// FingerprintBasedSessionManager sessionManager) {
|
||||||
this.fingerprintGenerator = fingerprintGenerator;
|
// this.fingerprintGenerator = fingerprintGenerator;
|
||||||
this.sessionManager = sessionManager;
|
// this.sessionManager = sessionManager;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
protected void doFilterInternal(
|
// protected void doFilterInternal(
|
||||||
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
// HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||||
throws ServletException, IOException {
|
// throws ServletException, IOException {
|
||||||
|
//
|
||||||
if (RequestUriUtils.isStaticResource(request.getContextPath(), request.getRequestURI())) {
|
// if (RequestUriUtils.isStaticResource(request.getContextPath(), request.getRequestURI())) {
|
||||||
filterChain.doFilter(request, response);
|
// filterChain.doFilter(request, response);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
String fingerprint = fingerprintGenerator.generateFingerprint(request);
|
// String fingerprint = fingerprintGenerator.generateFingerprint(request);
|
||||||
log.debug("Generated fingerprint for request: {}", fingerprint);
|
// log.debug("Generated fingerprint for request: {}", fingerprint);
|
||||||
|
//
|
||||||
HttpSession session = request.getSession();
|
// HttpSession session = request.getSession();
|
||||||
boolean isNewSession = session.isNew();
|
// boolean isNewSession = session.isNew();
|
||||||
String sessionId = session.getId();
|
// String sessionId = session.getId();
|
||||||
|
//
|
||||||
if (isNewSession) {
|
// if (isNewSession) {
|
||||||
log.info("New session created: {}", sessionId);
|
// log.info("New session created: {}", sessionId);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (!sessionManager.isFingerPrintAllowed(fingerprint)) {
|
// if (!sessionManager.isFingerPrintAllowed(fingerprint)) {
|
||||||
log.info("Blocked fingerprint detected, redirecting: {}", fingerprint);
|
// log.info("Blocked fingerprint detected, redirecting: {}", fingerprint);
|
||||||
response.sendRedirect(request.getContextPath() + "/too-many-requests");
|
// response.sendRedirect(request.getContextPath() + "/too-many-requests");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
session.setAttribute("userFingerprint", fingerprint);
|
// session.setAttribute("userFingerprint", fingerprint);
|
||||||
session.setAttribute(
|
// session.setAttribute(
|
||||||
FingerprintBasedSessionManager.STARTUP_TIMESTAMP,
|
// FingerprintBasedSessionManager.STARTUP_TIMESTAMP,
|
||||||
FingerprintBasedSessionManager.APP_STARTUP_TIME);
|
// FingerprintBasedSessionManager.APP_STARTUP_TIME);
|
||||||
|
//
|
||||||
sessionManager.registerFingerprint(fingerprint, sessionId);
|
// sessionManager.registerFingerprint(fingerprint, sessionId);
|
||||||
|
//
|
||||||
log.debug("Proceeding with request: {}", request.getRequestURI());
|
// log.debug("Proceeding with request: {}", request.getRequestURI());
|
||||||
filterChain.doFilter(request, response);
|
// filterChain.doFilter(request, response);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
@ -1,134 +1,134 @@
|
|||||||
package stirling.software.SPDF.config.fingerprint;
|
//package stirling.software.SPDF.config.fingerprint;
|
||||||
|
//
|
||||||
import java.util.Iterator;
|
//import java.util.Iterator;
|
||||||
import java.util.Map;
|
//import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
//import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
//import java.util.concurrent.TimeUnit;
|
||||||
|
//
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
//import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Component;
|
//import org.springframework.stereotype.Component;
|
||||||
|
//
|
||||||
import jakarta.servlet.http.HttpSession;
|
//import jakarta.servlet.http.HttpSession;
|
||||||
import jakarta.servlet.http.HttpSessionAttributeListener;
|
//import jakarta.servlet.http.HttpSessionAttributeListener;
|
||||||
import jakarta.servlet.http.HttpSessionEvent;
|
//import jakarta.servlet.http.HttpSessionEvent;
|
||||||
import jakarta.servlet.http.HttpSessionListener;
|
//import jakarta.servlet.http.HttpSessionListener;
|
||||||
import lombok.AllArgsConstructor;
|
//import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
//import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
//import lombok.extern.slf4j.Slf4j;
|
||||||
|
//
|
||||||
@Slf4j
|
//@Slf4j
|
||||||
@Component
|
//@Component
|
||||||
public class FingerprintBasedSessionManager
|
//public class FingerprintBasedSessionManager
|
||||||
implements HttpSessionListener, HttpSessionAttributeListener {
|
// implements HttpSessionListener, HttpSessionAttributeListener {
|
||||||
private static final ConcurrentHashMap<String, FingerprintInfo> activeFingerprints =
|
// private static final ConcurrentHashMap<String, FingerprintInfo> activeFingerprints =
|
||||||
new ConcurrentHashMap<>();
|
// new ConcurrentHashMap<>();
|
||||||
|
//
|
||||||
// To be reduced in later version to 8~
|
// // To be reduced in later version to 8~
|
||||||
private static final int MAX_ACTIVE_FINGERPRINTS = 30;
|
// private static final int MAX_ACTIVE_FINGERPRINTS = 30;
|
||||||
|
//
|
||||||
static final String STARTUP_TIMESTAMP = "appStartupTimestamp";
|
// static final String STARTUP_TIMESTAMP = "appStartupTimestamp";
|
||||||
static final long APP_STARTUP_TIME = System.currentTimeMillis();
|
// static final long APP_STARTUP_TIME = System.currentTimeMillis();
|
||||||
private static final long FINGERPRINT_EXPIRATION = TimeUnit.MINUTES.toMillis(30);
|
// private static final long FINGERPRINT_EXPIRATION = TimeUnit.MINUTES.toMillis(30);
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void sessionCreated(HttpSessionEvent se) {
|
// public void sessionCreated(HttpSessionEvent se) {
|
||||||
HttpSession session = se.getSession();
|
// HttpSession session = se.getSession();
|
||||||
String sessionId = session.getId();
|
// String sessionId = session.getId();
|
||||||
String fingerprint = (String) session.getAttribute("userFingerprint");
|
// String fingerprint = (String) session.getAttribute("userFingerprint");
|
||||||
|
//
|
||||||
if (fingerprint == null) {
|
// if (fingerprint == null) {
|
||||||
log.warn("Session created without fingerprint: {}", sessionId);
|
// log.warn("Session created without fingerprint: {}", sessionId);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
synchronized (activeFingerprints) {
|
// synchronized (activeFingerprints) {
|
||||||
if (activeFingerprints.size() >= MAX_ACTIVE_FINGERPRINTS
|
// if (activeFingerprints.size() >= MAX_ACTIVE_FINGERPRINTS
|
||||||
&& !activeFingerprints.containsKey(fingerprint)) {
|
// && !activeFingerprints.containsKey(fingerprint)) {
|
||||||
log.info("Max fingerprints reached. Marking session as blocked: {}", sessionId);
|
// log.info("Max fingerprints reached. Marking session as blocked: {}", sessionId);
|
||||||
session.setAttribute("blocked", true);
|
// session.setAttribute("blocked", true);
|
||||||
} else {
|
// } else {
|
||||||
activeFingerprints.put(
|
// activeFingerprints.put(
|
||||||
fingerprint, new FingerprintInfo(sessionId, System.currentTimeMillis()));
|
// fingerprint, new FingerprintInfo(sessionId, System.currentTimeMillis()));
|
||||||
log.info(
|
// log.info(
|
||||||
"New fingerprint registered: {}. Total active fingerprints: {}",
|
// "New fingerprint registered: {}. Total active fingerprints: {}",
|
||||||
fingerprint,
|
// fingerprint,
|
||||||
activeFingerprints.size());
|
// activeFingerprints.size());
|
||||||
}
|
// }
|
||||||
session.setAttribute(STARTUP_TIMESTAMP, APP_STARTUP_TIME);
|
// session.setAttribute(STARTUP_TIMESTAMP, APP_STARTUP_TIME);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void sessionDestroyed(HttpSessionEvent se) {
|
// public void sessionDestroyed(HttpSessionEvent se) {
|
||||||
HttpSession session = se.getSession();
|
// HttpSession session = se.getSession();
|
||||||
String fingerprint = (String) session.getAttribute("userFingerprint");
|
// String fingerprint = (String) session.getAttribute("userFingerprint");
|
||||||
|
//
|
||||||
if (fingerprint != null) {
|
// if (fingerprint != null) {
|
||||||
synchronized (activeFingerprints) {
|
// synchronized (activeFingerprints) {
|
||||||
activeFingerprints.remove(fingerprint);
|
// activeFingerprints.remove(fingerprint);
|
||||||
log.info(
|
// log.info(
|
||||||
"Fingerprint removed: {}. Total active fingerprints: {}",
|
// "Fingerprint removed: {}. Total active fingerprints: {}",
|
||||||
fingerprint,
|
// fingerprint,
|
||||||
activeFingerprints.size());
|
// activeFingerprints.size());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public boolean isFingerPrintAllowed(String fingerprint) {
|
// public boolean isFingerPrintAllowed(String fingerprint) {
|
||||||
synchronized (activeFingerprints) {
|
// synchronized (activeFingerprints) {
|
||||||
return activeFingerprints.size() < MAX_ACTIVE_FINGERPRINTS
|
// return activeFingerprints.size() < MAX_ACTIVE_FINGERPRINTS
|
||||||
|| activeFingerprints.containsKey(fingerprint);
|
// || activeFingerprints.containsKey(fingerprint);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public void registerFingerprint(String fingerprint, String sessionId) {
|
// public void registerFingerprint(String fingerprint, String sessionId) {
|
||||||
synchronized (activeFingerprints) {
|
// synchronized (activeFingerprints) {
|
||||||
activeFingerprints.put(
|
// activeFingerprints.put(
|
||||||
fingerprint, new FingerprintInfo(sessionId, System.currentTimeMillis()));
|
// fingerprint, new FingerprintInfo(sessionId, System.currentTimeMillis()));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public void unregisterFingerprint(String fingerprint) {
|
// public void unregisterFingerprint(String fingerprint) {
|
||||||
synchronized (activeFingerprints) {
|
// synchronized (activeFingerprints) {
|
||||||
activeFingerprints.remove(fingerprint);
|
// activeFingerprints.remove(fingerprint);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Scheduled(fixedRate = 1800000) // Run every 30 mins
|
// @Scheduled(fixedRate = 1800000) // Run every 30 mins
|
||||||
public void cleanupStaleFingerprints() {
|
// public void cleanupStaleFingerprints() {
|
||||||
log.info("Starting cleanup of stale fingerprints");
|
// log.info("Starting cleanup of stale fingerprints");
|
||||||
long now = System.currentTimeMillis();
|
// long now = System.currentTimeMillis();
|
||||||
int removedCount = 0;
|
// int removedCount = 0;
|
||||||
|
//
|
||||||
synchronized (activeFingerprints) {
|
// synchronized (activeFingerprints) {
|
||||||
Iterator<Map.Entry<String, FingerprintInfo>> iterator =
|
// Iterator<Map.Entry<String, FingerprintInfo>> iterator =
|
||||||
activeFingerprints.entrySet().iterator();
|
// activeFingerprints.entrySet().iterator();
|
||||||
while (iterator.hasNext()) {
|
// while (iterator.hasNext()) {
|
||||||
Map.Entry<String, FingerprintInfo> entry = iterator.next();
|
// Map.Entry<String, FingerprintInfo> entry = iterator.next();
|
||||||
FingerprintInfo info = entry.getValue();
|
// FingerprintInfo info = entry.getValue();
|
||||||
|
//
|
||||||
if (now - info.getLastAccessTime() > FINGERPRINT_EXPIRATION) {
|
// if (now - info.getLastAccessTime() > FINGERPRINT_EXPIRATION) {
|
||||||
iterator.remove();
|
// iterator.remove();
|
||||||
removedCount++;
|
// removedCount++;
|
||||||
log.info("Removed stale fingerprint: {}", entry.getKey());
|
// log.info("Removed stale fingerprint: {}", entry.getKey());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
log.info("Cleanup complete. Removed {} stale fingerprints", removedCount);
|
// log.info("Cleanup complete. Removed {} stale fingerprints", removedCount);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public void updateLastAccessTime(String fingerprint) {
|
// public void updateLastAccessTime(String fingerprint) {
|
||||||
FingerprintInfo info = activeFingerprints.get(fingerprint);
|
// FingerprintInfo info = activeFingerprints.get(fingerprint);
|
||||||
if (info != null) {
|
// if (info != null) {
|
||||||
info.setLastAccessTime(System.currentTimeMillis());
|
// info.setLastAccessTime(System.currentTimeMillis());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Data
|
// @Data
|
||||||
@AllArgsConstructor
|
// @AllArgsConstructor
|
||||||
private static class FingerprintInfo {
|
// private static class FingerprintInfo {
|
||||||
private String sessionId;
|
// private String sessionId;
|
||||||
private long lastAccessTime;
|
// private long lastAccessTime;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
@ -1,77 +1,77 @@
|
|||||||
package stirling.software.SPDF.config.fingerprint;
|
//package stirling.software.SPDF.config.fingerprint;
|
||||||
|
//
|
||||||
import java.security.MessageDigest;
|
//import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
//import java.security.NoSuchAlgorithmException;
|
||||||
|
//
|
||||||
import org.springframework.stereotype.Component;
|
//import org.springframework.stereotype.Component;
|
||||||
|
//
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
//import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
//
|
||||||
@Component
|
//@Component
|
||||||
public class FingerprintGenerator {
|
//public class FingerprintGenerator {
|
||||||
|
//
|
||||||
public String generateFingerprint(HttpServletRequest request) {
|
// public String generateFingerprint(HttpServletRequest request) {
|
||||||
if (request == null) {
|
// if (request == null) {
|
||||||
return "";
|
// return "";
|
||||||
}
|
// }
|
||||||
StringBuilder fingerprintBuilder = new StringBuilder();
|
// StringBuilder fingerprintBuilder = new StringBuilder();
|
||||||
|
//
|
||||||
// Add IP address
|
// // Add IP address
|
||||||
fingerprintBuilder.append(request.getRemoteAddr());
|
// fingerprintBuilder.append(request.getRemoteAddr());
|
||||||
|
//
|
||||||
// Add X-Forwarded-For header if present (for clients behind proxies)
|
// // Add X-Forwarded-For header if present (for clients behind proxies)
|
||||||
String forwardedFor = request.getHeader("X-Forwarded-For");
|
// String forwardedFor = request.getHeader("X-Forwarded-For");
|
||||||
if (forwardedFor != null) {
|
// if (forwardedFor != null) {
|
||||||
fingerprintBuilder.append(forwardedFor);
|
// fingerprintBuilder.append(forwardedFor);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Add User-Agent
|
// // Add User-Agent
|
||||||
String userAgent = request.getHeader("User-Agent");
|
// String userAgent = request.getHeader("User-Agent");
|
||||||
if (userAgent != null) {
|
// if (userAgent != null) {
|
||||||
fingerprintBuilder.append(userAgent);
|
// fingerprintBuilder.append(userAgent);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Add Accept-Language header
|
// // Add Accept-Language header
|
||||||
String acceptLanguage = request.getHeader("Accept-Language");
|
// String acceptLanguage = request.getHeader("Accept-Language");
|
||||||
if (acceptLanguage != null) {
|
// if (acceptLanguage != null) {
|
||||||
fingerprintBuilder.append(acceptLanguage);
|
// fingerprintBuilder.append(acceptLanguage);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Add Accept header
|
// // Add Accept header
|
||||||
String accept = request.getHeader("Accept");
|
// String accept = request.getHeader("Accept");
|
||||||
if (accept != null) {
|
// if (accept != null) {
|
||||||
fingerprintBuilder.append(accept);
|
// fingerprintBuilder.append(accept);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Add Connection header
|
// // Add Connection header
|
||||||
String connection = request.getHeader("Connection");
|
// String connection = request.getHeader("Connection");
|
||||||
if (connection != null) {
|
// if (connection != null) {
|
||||||
fingerprintBuilder.append(connection);
|
// fingerprintBuilder.append(connection);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Add server port
|
// // Add server port
|
||||||
fingerprintBuilder.append(request.getServerPort());
|
// fingerprintBuilder.append(request.getServerPort());
|
||||||
|
//
|
||||||
// Add secure flag
|
// // Add secure flag
|
||||||
fingerprintBuilder.append(request.isSecure());
|
// fingerprintBuilder.append(request.isSecure());
|
||||||
|
//
|
||||||
// Generate a hash of the fingerprint
|
// // Generate a hash of the fingerprint
|
||||||
return generateHash(fingerprintBuilder.toString());
|
// return generateHash(fingerprintBuilder.toString());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private String generateHash(String input) {
|
// private String generateHash(String input) {
|
||||||
try {
|
// try {
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
// MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||||
byte[] hash = digest.digest(input.getBytes());
|
// byte[] hash = digest.digest(input.getBytes());
|
||||||
StringBuilder hexString = new StringBuilder();
|
// StringBuilder hexString = new StringBuilder();
|
||||||
for (byte b : hash) {
|
// for (byte b : hash) {
|
||||||
String hex = Integer.toHexString(0xff & b);
|
// String hex = Integer.toHexString(0xff & b);
|
||||||
if (hex.length() == 1) hexString.append('0');
|
// if (hex.length() == 1) hexString.append('0');
|
||||||
hexString.append(hex);
|
// hexString.append(hex);
|
||||||
}
|
// }
|
||||||
return hexString.toString();
|
// return hexString.toString();
|
||||||
} catch (NoSuchAlgorithmException e) {
|
// } catch (NoSuchAlgorithmException e) {
|
||||||
throw new RuntimeException("Failed to generate fingerprint hash", e);
|
// throw new RuntimeException("Failed to generate fingerprint hash", e);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user