Source Code
The entire project, readable in your browser. No hidden JavaScript, no sneaky beacons. If we claimed we don't track you, this is where you check.
|
Pages/
Feeds/
Backend/
Includes/
Stylesheet/
JavaScript/
data/counter.txt and data/guestbook.txt hold visitor-supplied content
(a number and signed messages), so they are not shown here.
|
1 <?php 2 /** 3 * config.php 4 * ----------------------------------------------------------------------------- 5 * Central configuration for "What Can I Learn About You?" 6 * 7 * Pure PHP. No database. No Composer. No frameworks. 8 * Just constants, small config arrays, and a couple of environment helpers 9 * that every other file in the project relies on. 10 * 11 * Upload-and-run friendly: nothing here requires write access except the 12 * DATA_DIR (used by the visitor counter and guestbook). If DATA_DIR is not 13 * writable the site still works; those two features just degrade gracefully. 14 * ----------------------------------------------------------------------------- 15 */ 16 17 // ----------------------------------------------------------------------------- 18 // Hard error settings. On shared hosting we do NOT want stray warnings leaking 19 // into the HTML and breaking the retro layout. Flip DEBUG to true while hacking. 20 // ----------------------------------------------------------------------------- 21 define('DEBUG', false); 22 23 if (DEBUG) { 24 error_reporting(E_ALL); 25 ini_set('display_errors', '1'); 26 } else { 27 error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE & ~E_WARNING); 28 ini_set('display_errors', '0'); 29 } 30 31 // Force UTF-8 everywhere so the ASCII/ANSI art renders predictably. 32 if (function_exists('mb_internal_encoding')) { 33 mb_internal_encoding('UTF-8'); 34 } 35 36 // ----------------------------------------------------------------------------- 37 // Site identity 38 // ----------------------------------------------------------------------------- 39 define('SITE_NAME', 'What Can I Learn About You?'); 40 define('SITE_TAGLINE', 'A demonstration of everything a plain website can see.'); 41 define('SITE_VERSION', '1.0'); 42 define('SITE_AUTHOR', 'anonymous'); 43 define('SITE_YEAR', '2026'); 44 define('LAST_UPDATED', 'July 2026'); 45 46 // ----------------------------------------------------------------------------- 47 // Paths. BASE_PATH is the filesystem root of the project; BASE_URL is worked 48 // out from the current request so the site runs from a subfolder or a domain 49 // root without any edits. 50 // ----------------------------------------------------------------------------- 51 define('BASE_PATH', dirname(__DIR__)); 52 define('DATA_DIR', BASE_PATH . DIRECTORY_SEPARATOR . 'data'); 53 define('INC_DIR', BASE_PATH . DIRECTORY_SEPARATOR . 'includes'); 54 55 /** 56 * Work out the public base URL (path portion) of the site, e.g. "" for a 57 * domain root or "/eyes" for a subfolder install. Used to build links so the 58 * navigation never 404s regardless of where the files were dropped. 59 */ 60 if (!function_exists('detect_base_url')) { 61 function detect_base_url(): string 62 { 63 // SCRIPT_NAME looks like /eyes/index.php or /index.php 64 $script = isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : '/index.php'; 65 $dir = str_replace('\\', '/', dirname($script)); 66 // includes/ pages are always run from project root scripts, so dirname 67 // of the top-level script is exactly our base. Normalise trailing slash. 68 if ($dir === '/' || $dir === '.') { 69 return ''; 70 } 71 return rtrim($dir, '/'); 72 } 73 } 74 define('BASE_URL', detect_base_url()); 75 76 // Convenience: build an absolute-from-root URL for an asset or page. 77 if (!function_exists('url')) { 78 function url(string $path = ''): string 79 { 80 $path = ltrim($path, '/'); 81 return BASE_URL . '/' . $path; 82 } 83 } 84 85 // ----------------------------------------------------------------------------- 86 // Data files (flat-file storage; no database anywhere in this project) 87 // ----------------------------------------------------------------------------- 88 define('COUNTER_FILE', DATA_DIR . DIRECTORY_SEPARATOR . 'counter.txt'); 89 define('GUESTBOOK_FILE', DATA_DIR . DIRECTORY_SEPARATOR . 'guestbook.txt'); 90 91 // The counter starts from a real zero. No fake baseline. 92 define('COUNTER_SEED', 0); 93 94 // Guestbook limits (kept sane so a flat file never explodes on shared hosting). 95 define('GUESTBOOK_MAX_ENTRIES', 500); 96 define('GUESTBOOK_MAX_NAME', 40); 97 define('GUESTBOOK_MAX_MESSAGE', 500); 98 99 // ----------------------------------------------------------------------------- 100 // IP geolocation / intelligence lookup. 101 // 102 // api/scan.php calls a free, keyless JSON endpoint server-side to turn the 103 // visitor IP into country / city / ISP / ASN / proxy&VPN flags. We list several 104 // providers and try them in order; the first that answers wins. All are free 105 // tier and require no signup, so the project stays upload-and-run. 106 // 107 // Set IP_LOOKUP_ENABLED to false to disable outbound calls entirely (the scan 108 // still returns all header-derived data, just without geo enrichment). 109 // ----------------------------------------------------------------------------- 110 define('IP_LOOKUP_ENABLED', true); 111 define('IP_LOOKUP_TIMEOUT', 4); // seconds per provider before giving up 112 113 /** 114 * Ordered list of lookup providers. Each entry is a template where {ip} is 115 * replaced by the visitor's address. The matching parser in api/scan.php knows 116 * how to read each provider's field names via the "parser" key. 117 */ 118 $GLOBALS['IP_LOOKUP_PROVIDERS'] = array( 119 array( 120 'name' => 'ip-api.com', 121 'url' => 'http://ip-api.com/json/{ip}?fields=status,message,continent,country,' 122 . 'countryCode,region,regionName,city,zip,lat,lon,timezone,currency,isp,' 123 . 'org,as,asname,reverse,mobile,proxy,hosting,query', 124 'parser' => 'ipapi', 125 ), 126 array( 127 'name' => 'ipwho.is', 128 'url' => 'https://ipwho.is/{ip}', 129 'parser' => 'ipwhois', 130 ), 131 array( 132 'name' => 'ipapi.co', 133 'url' => 'https://ipapi.co/{ip}/json/', 134 'parser' => 'ipapico', 135 ), 136 ); 137 138 // ----------------------------------------------------------------------------- 139 // Author links. Shown in the footer on every page. 140 // ----------------------------------------------------------------------------- 141 define('BLOG_URL', 'https://h4x0r.icu/blog'); 142 define('WEBSITE_URL', 'https://h4x0r.icu'); 143 define('DONATE_URL', 'https://coindrop.to/delta'); 144 145 // ----------------------------------------------------------------------------- 146 // Navigation menu. Rendered by includes/nav.php. Order matters. 147 // Each item: [label, page-file, is-new?] 148 // ----------------------------------------------------------------------------- 149 $GLOBALS['NAV_ITEMS'] = array( 150 array('Home', 'index.php', false), 151 array('Scan', 'scan.php', true), 152 array('Browser', 'browser.php', false), 153 array('Fingerprint', 'fingerprint.php', true), 154 array('Privacy', 'privacy.php', false), 155 array('About', 'about.php', false), 156 array('Source', 'source.php', false), 157 ); 158 159 // ----------------------------------------------------------------------------- 160 // Marquee / news ticker lines shown in the header. Pure flavour. 161 // ----------------------------------------------------------------------------- 162 $GLOBALS['MARQUEE_LINES'] = array( 163 '*** Welcome to the last honest website on the internet ***', 164 'This site stores NOTHING about you -- everything is computed in YOUR browser', 165 'NEW! Live browser fingerprinting module added', 166 'NEW! Interactive terminal -- type help to begin', 167 'Best viewed in Firefox at 1024x768 or higher', 168 'Remember: if the product is free, usually YOU are the product -- but not here', 169 'Greetz to everyone still running an old CRT monitor <3', 170 ); 171 172 // ----------------------------------------------------------------------------- 173 // "What's new" / update log. Powers the RSS feed, the sitemap notes, and the 174 // About page changelog. Newest first. Dates are absolute (no relative dates). 175 // Each: [date (Y-m-d), title, description] 176 // ----------------------------------------------------------------------------- 177 $GLOBALS['UPDATE_LOG'] = array( 178 array('2026-07-12', 'Guestbook opened', 179 'Sign the guestbook like it is 2002. Flat-file, no database, no email harvesting.'), 180 array('2026-07-10', 'Interactive terminal shipped', 181 'A fake-but-functional shell. Try: help, scan, neofetch, fortune, whoami, export.'), 182 array('2026-07-08', 'Fingerprinting module', 183 'Canvas, audio, WebGL, and font fingerprints combined into a local SHA-256 ID.'), 184 array('2026-07-05', 'Privacy score engine', 185 'A 0-100 score across Tracking, Identity, Fingerprint, Security, Permissions, Network.'), 186 array('2026-07-01', 'Site launched', 187 'Initial release of "What Can I Learn About You?" -- built like it is still 2003.'), 188 ); 189 190 // ----------------------------------------------------------------------------- 191 // Feature list shown on the home page (with blinking NEW! markers). Powers the 192 // "recently added" easter-egg logic. Each: [name, description, is-new?] 193 // ----------------------------------------------------------------------------- 194 $GLOBALS['FEATURE_LIST'] = array( 195 array('HTTP Header Enumeration', 'See every header your browser silently sends.', false), 196 array('IP Intelligence', 'Country, city, ISP, ASN, and VPN/proxy/hosting detection.', false), 197 array('Browser Detection', 'Engine, version, OS, architecture, cores, memory.', false), 198 array('Feature Probing', '60+ Web APIs tested live: WebGPU, USB, HID, Serial, more.', false), 199 array('Fingerprinting', 'Canvas / audio / WebGL / font hashing into one local ID.', true), 200 array('Privacy Score', 'A blunt 0-100 verdict on how exposed you are.', true), 201 array('Interactive Terminal', 'A retro shell with real, computed output.', true), 202 array('Local Export', 'Download your report as JSON, HTML, Markdown, or TXT.', false), 203 ); 204 205 // ----------------------------------------------------------------------------- 206 // 88x31 buttons for the footer. We render them as tiny inline-styled boxes 207 // (data-URI GIFs are added in functions.php) so there are no binaries to upload. 208 // Each: [top-text, bottom-text, fg-color, bg-color] 209 // ----------------------------------------------------------------------------- 210 $GLOBALS['BUTTONS_88x31'] = array( 211 array('Powered by', 'PHP', '#FFFFFF', '#4B0082'), 212 array('Made with', 'LINUX', '#000000', '#FFFF00'), 213 array('Best in', 'FIREFOX', '#FFFFFF', '#B22222'), 214 array('NO', 'COOKIES', '#00FF00', '#000000'), 215 array('100%', 'OPEN SOURCE', '#000000', '#00FFFF'), 216 array('Valid', 'HTML 4.01', '#FFFFFF', '#00008B'), 217 array('This site', 'STORES NOTHING', '#FFFF00', '#000000'), 218 array('Get', 'NETSCAPE NOW', '#FFFFFF', '#000080'), 219 ); 220 221 // ----------------------------------------------------------------------------- 222 // Security headers. Even a nostalgia project should not be trivially clickjacked 223 // or sniffed. These are cheap and do not affect the look. 224 // ----------------------------------------------------------------------------- 225 if (!headers_sent()) { 226 header('X-Content-Type-Options: nosniff'); 227 header('X-Frame-Options: SAMEORIGIN'); 228 header('Referrer-Policy: no-referrer'); 229 // Explicitly promise the visitor we are not setting tracking cookies. 230 header('X-Robots-Tag: index, follow'); 231 } 232 You are reading the real file being executed on the server. What you see is what runs. |