Skip to main content

jsdet_browser/
persona.rs

1/// Browser persona — configurable identity presented to JavaScript.
2///
3/// Phishing kits fingerprint the browser to detect sandboxes. The persona
4/// must be internally consistent: a Chrome UA on Windows should report
5/// Win32 platform, en-US language, and realistic screen dimensions.
6#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
7pub struct Persona {
8    pub user_agent: String,
9    pub platform: String,
10    pub language: String,
11    pub languages: Vec<String>,
12    pub screen_width: u32,
13    pub screen_height: u32,
14    pub color_depth: u32,
15    pub timezone: String,
16    pub timezone_offset: i32,
17    pub referrer: String,
18    pub hardware_concurrency: u32,
19    pub device_memory: f64,
20    pub max_touch_points: u32,
21    pub vendor: String,
22    pub app_name: String,
23    pub app_version: String,
24    pub do_not_track: Option<String>,
25}
26
27impl Default for Persona {
28    fn default() -> Self {
29        Self::chrome_windows()
30    }
31}
32
33impl Persona {
34    /// Chrome 120 on Windows 10. The most common browser configuration.
35    pub fn chrome_windows() -> Self {
36        Self {
37            user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36".into(),
38            platform: "Win32".into(),
39            language: "en-US".into(),
40            languages: vec!["en-US".into(), "en".into()],
41            screen_width: 1920,
42            screen_height: 1080,
43            color_depth: 24,
44            timezone: "America/New_York".into(),
45            timezone_offset: -300,
46            referrer: String::new(),
47            hardware_concurrency: 8,
48            device_memory: 8.0,
49            max_touch_points: 0,
50            vendor: "Google Inc.".into(),
51            app_name: "Netscape".into(),
52            app_version: "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36".into(),
53            do_not_track: None,
54        }
55    }
56
57    /// Chrome on macOS. Second most common.
58    pub fn chrome_macos() -> Self {
59        Self {
60            user_agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36".into(),
61            platform: "MacIntel".into(),
62            screen_width: 1440,
63            screen_height: 900,
64            timezone: "America/Los_Angeles".into(),
65            timezone_offset: -480,
66            ..Self::chrome_windows()
67        }
68    }
69
70    /// Chrome on Android. Tests mobile-targeted phishing.
71    pub fn chrome_android() -> Self {
72        Self {
73            user_agent: "Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36".into(),
74            platform: "Linux armv81".into(),
75            screen_width: 412,
76            screen_height: 915,
77            max_touch_points: 5,
78            device_memory: 4.0,
79            hardware_concurrency: 4,
80            ..Self::chrome_windows()
81        }
82    }
83
84    /// Firefox on Linux. Tests cross-browser compatibility of phishing kits.
85    pub fn firefox_linux() -> Self {
86        Self {
87            user_agent: "Mozilla/5.0 (X11; Linux x86_64; rv:121.0) Gecko/20100101 Firefox/121.0"
88                .into(),
89            platform: "Linux x86_64".into(),
90            vendor: String::new(),
91            ..Self::chrome_windows()
92        }
93    }
94}