Initial commit
Dieser Commit ist enthalten in:
276
domain/entities/browser_fingerprint.py
Normale Datei
276
domain/entities/browser_fingerprint.py
Normale Datei
@ -0,0 +1,276 @@
|
||||
"""
|
||||
Browser Fingerprint Entity - Repräsentiert einen kompletten Browser-Fingerprint
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from typing import List, Dict, Any, Optional
|
||||
from enum import Enum
|
||||
import uuid
|
||||
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class StaticComponents:
|
||||
"""Static fingerprint components that don't change"""
|
||||
device_type: str = "desktop" # desktop/mobile/tablet
|
||||
os_family: str = "windows" # windows/macos/linux/android/ios
|
||||
browser_family: str = "chromium" # chromium/firefox/safari
|
||||
gpu_vendor: str = "Intel Inc."
|
||||
gpu_model: str = "Intel Iris OpenGL Engine"
|
||||
cpu_architecture: str = "x86_64"
|
||||
base_fonts: List[str] = field(default_factory=list)
|
||||
base_resolution: tuple = (1920, 1080)
|
||||
base_timezone: str = "Europe/Berlin"
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return {
|
||||
'device_type': self.device_type,
|
||||
'os_family': self.os_family,
|
||||
'browser_family': self.browser_family,
|
||||
'gpu_vendor': self.gpu_vendor,
|
||||
'gpu_model': self.gpu_model,
|
||||
'cpu_architecture': self.cpu_architecture,
|
||||
'base_fonts': self.base_fonts,
|
||||
'base_resolution': self.base_resolution,
|
||||
'base_timezone': self.base_timezone
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class CanvasNoise:
|
||||
"""Canvas Fingerprinting Schutz-Konfiguration"""
|
||||
noise_level: float = 0.02
|
||||
seed: int = 42
|
||||
algorithm: str = "gaussian"
|
||||
|
||||
|
||||
@dataclass
|
||||
class WebRTCConfig:
|
||||
"""WebRTC Konfiguration für IP-Leak Prevention"""
|
||||
enabled: bool = True
|
||||
ice_servers: List[str] = field(default_factory=list)
|
||||
local_ip_mask: str = "10.0.0.x"
|
||||
disable_webrtc: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class HardwareConfig:
|
||||
"""Hardware-Konfiguration für Fingerprinting"""
|
||||
hardware_concurrency: int = 4
|
||||
device_memory: int = 8
|
||||
max_touch_points: int = 0
|
||||
screen_resolution: tuple = (1920, 1080)
|
||||
color_depth: int = 24
|
||||
pixel_ratio: float = 1.0
|
||||
|
||||
|
||||
@dataclass
|
||||
class NavigatorProperties:
|
||||
"""Navigator-Eigenschaften für Browser-Fingerprint"""
|
||||
platform: str = "Win32"
|
||||
vendor: str = "Google Inc."
|
||||
vendor_sub: str = ""
|
||||
product: str = "Gecko"
|
||||
product_sub: str = "20030107"
|
||||
app_name: str = "Netscape"
|
||||
app_version: str = "5.0"
|
||||
user_agent: str = ""
|
||||
language: str = "de-DE"
|
||||
languages: List[str] = field(default_factory=lambda: ["de-DE", "de", "en-US", "en"])
|
||||
online: bool = True
|
||||
do_not_track: str = "1"
|
||||
|
||||
|
||||
@dataclass
|
||||
class BrowserFingerprint:
|
||||
"""Repräsentiert einen kompletten Browser-Fingerprint"""
|
||||
|
||||
fingerprint_id: str = field(default_factory=lambda: str(uuid.uuid4()))
|
||||
canvas_noise: CanvasNoise = field(default_factory=CanvasNoise)
|
||||
webrtc_config: WebRTCConfig = field(default_factory=WebRTCConfig)
|
||||
font_list: List[str] = field(default_factory=list)
|
||||
hardware_config: HardwareConfig = field(default_factory=HardwareConfig)
|
||||
navigator_props: NavigatorProperties = field(default_factory=NavigatorProperties)
|
||||
created_at: datetime = field(default_factory=datetime.now)
|
||||
last_rotated: datetime = None
|
||||
|
||||
# WebGL Parameter
|
||||
webgl_vendor: str = "Intel Inc."
|
||||
webgl_renderer: str = "Intel Iris OpenGL Engine"
|
||||
|
||||
# Audio Context
|
||||
audio_context_base_latency: float = 0.00
|
||||
audio_context_output_latency: float = 0.00
|
||||
audio_context_sample_rate: int = 48000
|
||||
|
||||
# Timezone
|
||||
timezone: str = "Europe/Berlin"
|
||||
timezone_offset: int = -60 # UTC+1
|
||||
|
||||
# Plugins
|
||||
plugins: List[Dict[str, str]] = field(default_factory=list)
|
||||
|
||||
# New fields for account-bound persistence
|
||||
static_components: Optional[StaticComponents] = None
|
||||
rotation_seed: Optional[str] = None
|
||||
account_bound: bool = False
|
||||
platform_specific_config: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Konvertiert Fingerprint zu Dictionary für Serialisierung"""
|
||||
return {
|
||||
'fingerprint_id': self.fingerprint_id,
|
||||
'canvas_noise': {
|
||||
'noise_level': self.canvas_noise.noise_level,
|
||||
'seed': self.canvas_noise.seed,
|
||||
'algorithm': self.canvas_noise.algorithm
|
||||
},
|
||||
'webrtc_config': {
|
||||
'enabled': self.webrtc_config.enabled,
|
||||
'ice_servers': self.webrtc_config.ice_servers,
|
||||
'local_ip_mask': self.webrtc_config.local_ip_mask,
|
||||
'disable_webrtc': self.webrtc_config.disable_webrtc
|
||||
},
|
||||
'font_list': self.font_list,
|
||||
'hardware_config': {
|
||||
'hardware_concurrency': self.hardware_config.hardware_concurrency,
|
||||
'device_memory': self.hardware_config.device_memory,
|
||||
'max_touch_points': self.hardware_config.max_touch_points,
|
||||
'screen_resolution': self.hardware_config.screen_resolution,
|
||||
'color_depth': self.hardware_config.color_depth,
|
||||
'pixel_ratio': self.hardware_config.pixel_ratio
|
||||
},
|
||||
'navigator_props': {
|
||||
'platform': self.navigator_props.platform,
|
||||
'vendor': self.navigator_props.vendor,
|
||||
'vendor_sub': self.navigator_props.vendor_sub,
|
||||
'product': self.navigator_props.product,
|
||||
'product_sub': self.navigator_props.product_sub,
|
||||
'app_name': self.navigator_props.app_name,
|
||||
'app_version': self.navigator_props.app_version,
|
||||
'user_agent': self.navigator_props.user_agent,
|
||||
'language': self.navigator_props.language,
|
||||
'languages': self.navigator_props.languages,
|
||||
'online': self.navigator_props.online,
|
||||
'do_not_track': self.navigator_props.do_not_track
|
||||
},
|
||||
'webgl_vendor': self.webgl_vendor,
|
||||
'webgl_renderer': self.webgl_renderer,
|
||||
'audio_context': {
|
||||
'base_latency': self.audio_context_base_latency,
|
||||
'output_latency': self.audio_context_output_latency,
|
||||
'sample_rate': self.audio_context_sample_rate
|
||||
},
|
||||
'timezone': self.timezone,
|
||||
'timezone_offset': self.timezone_offset,
|
||||
'plugins': self.plugins,
|
||||
'created_at': self.created_at.isoformat(),
|
||||
'last_rotated': self.last_rotated.isoformat() if self.last_rotated else None,
|
||||
'static_components': self.static_components.to_dict() if self.static_components else None,
|
||||
'rotation_seed': self.rotation_seed,
|
||||
'account_bound': self.account_bound,
|
||||
'platform_specific_config': self.platform_specific_config
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: Dict[str, Any]) -> 'BrowserFingerprint':
|
||||
"""Creates BrowserFingerprint from dictionary"""
|
||||
fingerprint = cls()
|
||||
|
||||
# Basic fields
|
||||
fingerprint.fingerprint_id = data.get('fingerprint_id', str(uuid.uuid4()))
|
||||
fingerprint.webgl_vendor = data.get('webgl_vendor', "Intel Inc.")
|
||||
fingerprint.webgl_renderer = data.get('webgl_renderer', "Intel Iris OpenGL Engine")
|
||||
fingerprint.timezone = data.get('timezone', "Europe/Berlin")
|
||||
fingerprint.timezone_offset = data.get('timezone_offset', -60)
|
||||
fingerprint.plugins = data.get('plugins', [])
|
||||
|
||||
# Canvas noise
|
||||
if 'canvas_noise' in data:
|
||||
cn = data['canvas_noise']
|
||||
fingerprint.canvas_noise = CanvasNoise(
|
||||
noise_level=cn.get('noise_level', 0.02),
|
||||
seed=cn.get('seed', 42),
|
||||
algorithm=cn.get('algorithm', 'gaussian')
|
||||
)
|
||||
|
||||
# WebRTC config
|
||||
if 'webrtc_config' in data:
|
||||
wc = data['webrtc_config']
|
||||
fingerprint.webrtc_config = WebRTCConfig(
|
||||
enabled=wc.get('enabled', True),
|
||||
ice_servers=wc.get('ice_servers', []),
|
||||
local_ip_mask=wc.get('local_ip_mask', "10.0.0.x"),
|
||||
disable_webrtc=wc.get('disable_webrtc', False)
|
||||
)
|
||||
|
||||
# Hardware config
|
||||
if 'hardware_config' in data:
|
||||
hc = data['hardware_config']
|
||||
fingerprint.hardware_config = HardwareConfig(
|
||||
hardware_concurrency=hc.get('hardware_concurrency', 4),
|
||||
device_memory=hc.get('device_memory', 8),
|
||||
max_touch_points=hc.get('max_touch_points', 0),
|
||||
screen_resolution=tuple(hc.get('screen_resolution', [1920, 1080])),
|
||||
color_depth=hc.get('color_depth', 24),
|
||||
pixel_ratio=hc.get('pixel_ratio', 1.0)
|
||||
)
|
||||
|
||||
# Navigator properties
|
||||
if 'navigator_props' in data:
|
||||
np = data['navigator_props']
|
||||
fingerprint.navigator_props = NavigatorProperties(
|
||||
platform=np.get('platform', "Win32"),
|
||||
vendor=np.get('vendor', "Google Inc."),
|
||||
vendor_sub=np.get('vendor_sub', ""),
|
||||
product=np.get('product', "Gecko"),
|
||||
product_sub=np.get('product_sub', "20030107"),
|
||||
app_name=np.get('app_name', "Netscape"),
|
||||
app_version=np.get('app_version', "5.0"),
|
||||
user_agent=np.get('user_agent', ""),
|
||||
language=np.get('language', "de-DE"),
|
||||
languages=np.get('languages', ["de-DE", "de", "en-US", "en"]),
|
||||
online=np.get('online', True),
|
||||
do_not_track=np.get('do_not_track', "1")
|
||||
)
|
||||
|
||||
# Audio context
|
||||
if 'audio_context' in data:
|
||||
ac = data['audio_context']
|
||||
fingerprint.audio_context_base_latency = ac.get('base_latency', 0.00)
|
||||
fingerprint.audio_context_output_latency = ac.get('output_latency', 0.00)
|
||||
fingerprint.audio_context_sample_rate = ac.get('sample_rate', 48000)
|
||||
|
||||
# Font list
|
||||
fingerprint.font_list = data.get('font_list', [])
|
||||
|
||||
# Dates
|
||||
if 'created_at' in data:
|
||||
fingerprint.created_at = datetime.fromisoformat(data['created_at'])
|
||||
if 'last_rotated' in data and data['last_rotated']:
|
||||
fingerprint.last_rotated = datetime.fromisoformat(data['last_rotated'])
|
||||
|
||||
# New persistence fields
|
||||
if 'static_components' in data and data['static_components']:
|
||||
sc = data['static_components']
|
||||
fingerprint.static_components = StaticComponents(
|
||||
device_type=sc.get('device_type', 'desktop'),
|
||||
os_family=sc.get('os_family', 'windows'),
|
||||
browser_family=sc.get('browser_family', 'chromium'),
|
||||
gpu_vendor=sc.get('gpu_vendor', 'Intel Inc.'),
|
||||
gpu_model=sc.get('gpu_model', 'Intel Iris OpenGL Engine'),
|
||||
cpu_architecture=sc.get('cpu_architecture', 'x86_64'),
|
||||
base_fonts=sc.get('base_fonts', []),
|
||||
base_resolution=tuple(sc.get('base_resolution', [1920, 1080])),
|
||||
base_timezone=sc.get('base_timezone', 'Europe/Berlin')
|
||||
)
|
||||
|
||||
fingerprint.rotation_seed = data.get('rotation_seed')
|
||||
fingerprint.account_bound = data.get('account_bound', False)
|
||||
fingerprint.platform_specific_config = data.get('platform_specific_config', {})
|
||||
|
||||
return fingerprint
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren