Runtime

Security Architecture Report: Browser-Based Desktop Emulation Environment

Report summary

The engineering of a sophisticated, browser-based desktop emulation environment constrained exclusively to a technology stack of PHP, Hypertext Markup Language (HTML), Cascading Style Sheets (CSS), and vanilla JavaScript introduces a highly complex, non-standard security paradigm. The absolute archi

Status
Research archive item
Category
Runtime
Length
5,868 words
Reading time
27 minutes
Report type
evaluation

Key topics

  • Runtime
  • .NET
  • Privacy
  • Research Archive
  • Audit
  • Architecture
  • Governance
  • Security

Research provenance

Archive status
Research archive item
Content identity
sha256:43b89188b71469678fe4d6e94f6c73d1b280a2843587b8d6c6c72cc7a5f89cbf

For citation, use the report title and canonical URL. Archival presence does not establish authorship or promote report statements into portfolio evidence.

This page renders the archived Markdown as safe, formatted HTML. It is background research and does not become a portfolio claim without evidence review.

Full report

On this page

1. Executive Summary

The engineering of a sophisticated, browser-based desktop emulation environment constrained exclusively to a technology stack of PHP, Hypertext Markup Language (HTML), Cascading Style Sheets (CSS), and vanilla JavaScript introduces a highly complex, non-standard security paradigm. The absolute architectural prohibition of external libraries, third-party Application Programming Interfaces (APIs), widget frameworks, Content Delivery Networks (CDNs), and analytics platforms necessitates the creation of bespoke, highly fortified security mechanisms. These custom mechanisms must govern all aspects of the application, ranging from internal routing and Markdown parsing to complex state management and document object model (DOM) rendering. The foundational, unalterable security invariant of this architecture dictates that the canonical historical archive—the primary data source of the application—must remain strictly read-only and impervious to any modification originating from the desktop metaphor or client-side interactions. This exhaustive report delivers a comprehensive security architecture analysis tailored specifically for this emulation environment. Because the application relies heavily on the theatrical illusion of a desktop operating system—complete with a read-only terminal, a virtual filesystem, and historical web reconstructions—the primary overarching architectural risk is ontological confusion. There is a high probability that future developers, maintainers, or contributors might accidentally implement genuine execution surfaces or real filesystem linkages in a misguided attempt to satisfy the theatrical requirements of the emulation. Without the safety nets provided by established third-party sanitizers (such as DOMPurify) or mature routing frameworks (such as Laravel or Express), the application must rely exclusively on rigorous native browser APIs, mathematically sound Abstract Syntax Tree (AST)-to-DOM rendering methodologies, stringent Content Security Policy (CSP) enforcement, and strict, type-safe PHP backend routing. The strategic framework formulated herein relies on deep, multi-layered defense-in-depth principles. It establishes uncompromising trust boundaries between the PHP backend, the browser DOM, the isolated iframes utilized for historical reconstruction, and the local persistence layers. By enforcing strict data handling routines, immutable canonical state validations, and safe derived-view generation protocols, the architecture is designed to systematically mitigate critical risks including DOM-based Cross-Site Scripting (XSS), prototype pollution, DOM clobbering, CSS injection, clipboard vulnerabilities, and server-side path traversal.

2. Threat Model

The threat model for this browser-based desktop emulation is uniquely shaped by its stringent architectural constraints, the absence of standardized security libraries, and its fundamentally theatrical nature. The application functions effectively as a client-side operating system simulation, processing complex, potentially hostile inputs, managing intricate application state, and rendering historical web content that may harbor legacy exploits. The primary threat actors operating within this model include curious users and academic researchers attempting to "break out" of the desktop simulation by aggressively probing the terminal logic, the Virtual Filesystem (VFS), and Uniform Resource Locator (URL) parameters. Furthermore, malicious actors may target legitimate users through social engineering, specifically by distributing malicious "Research Tray" exported states or utilizing crafted deep links to trigger client-side execution. Finally, the historical archives themselves represent a latent threat; the reconstruction feature requires rendering archived web pages that inherently contain legacy exploits, malicious JavaScript, or heavily obfuscated embedded objects. The attack surface encompasses both the server-side PHP backend and the highly interactive vanilla JavaScript frontend, presenting a wide array of specific vulnerabilities that must be preemptively neutralized. Because no external HTML sanitization libraries are permitted, any conversion of untrusted text into HTML—such as rendering research documents or parsing user-supplied Markdown—introduces extreme risk1. If a developer resorts to using native string-to-DOM sinks like innerHTML or insertAdjacentHTML, the application immediately becomes vulnerable to severe XSS and HTML injection attacks3. The theatrical nature of the environment introduces the risk of theatrical escapes. The presence of a simulated command-line interface and VFS creates a dangerous psychological trap; the threat model anticipates scenarios where a simulated command is accidentally passed directly to the PHP backend rather than being handled purely as a harmless client-side string operation, leading to command injection or shell escapes5. Similarly, the reliance on local persistence (localStorage or IndexedDB) and imported JavaScript Object Notation (JSON) states opens sophisticated vectors for prototype pollution via unsafe recursive merges7. DOM clobbering is a critical threat in this ecosystem, as historical or derived HTML could introduce elements with id or name attributes that silently collide with, and overwrite, global application variables9. On the backend, the read-only archive faces the persistent threat of modification or unauthorized access if the PHP routing logic is manipulated via route traversal, unsafe virtual paths, or HTTP parameter pollution11. Furthermore, CSS injection poses a unique threat, as attackers could theoretically inject malicious stylesheets to exfiltrate sensitive text displayed on the screen or completely overlay the interface to facilitate clickjacking attacks.

3. Trust Boundaries

Establishing rigid, mathematically verifiable trust boundaries is the most critical architectural requirement when simulating an operating system entirely within a web browser. Data crossing any of these defined boundaries must inherently be treated as deeply hostile and subjected to rigorous validation, canonicalization, and safe serialization protocols before being processed.

BoundaryContextData DirectionSecurity Validation Requirement
Client-Server (HTTP/API)Vanilla JS to PHP BackendBidirectionalThe backend PHP trusts absolutely nothing. All inbound requests must utilize strict allowlists and parameter validation. Conversely, the client JS must not trust backend JSON blindly, necessitating defensive parsing to mitigate prototype pollution during state ingestion.
Emulator vs. Historical WebMain DOM vs. Sandboxed iframeIsolatedThe emulator must strictly isolate all historical web reconstructions using highly restrictive iframe sandbox attributes13. Any inter-frame communication via postMessage must rigorously check origins and validate data against strict schemas.
Memory vs. Local PersistenceJS Runtime to localStorageBidirectionalData retrieved from local storage must be schema-validated before being merged into the active application state to prevent storage poisoning and persistent mutation XSS14.
VFS vs. Real FilesystemDesktop UI to PHP BackendUnidirectionalVirtual paths must strictly map to unique, opaque identifiers or cryptographic hashes, never traversing, mimicking, or exposing actual backend operating system paths17.
External ImportsUploaded/Dragged "Research Tray" JSONIngressDeep merges of user-imported JSON must actively explicitly block or strip \_\_proto\_\_, constructor, and prototype keys prior to instantiation in memory7.

The integrity of these boundaries relies on the principle that the client-side JavaScript engine is an inherently compromised environment. Therefore, any security decision regarding the retrieval of canonical data must ultimately be validated independently by the PHP backend, while the client must fiercely protect its own execution context from the data it retrieves and displays.

4. Source-Versus-Derived Data Boundary

To satisfy the immutable operational directive that the canonical archive must never become writable through the desktop metaphor, the architecture mandates a strict physical, logical, and cryptographic separation between source data and derived data. The failure to maintain this boundary could result in the catastrophic corruption of the historical records the system is designed to preserve. The source data resides exclusively on the PHP backend. It consists of the historical web records, foundational research documents, and all foundational terminal command definitions. This data is delivered to the client via strictly read-only RESTful endpoints. The backend PHP implementation must be stripped of any programmatic logic capable of handling POST, PUT, PATCH, or DELETE methods for the archive paths. Authentication and session management on the backend must explicitly lack the capability to write to the archive directories. This is enforced at the operating system level; the web server process (e.g., www-data) must be granted strictly read-only file permissions to the canonical data directories, ensuring that even if a severe PHP vulnerability is exploited, the filesystem itself rejects the modification. Conversely, derived data includes all user-generated notes, spatial Research Tray organizations, search histories, VFS directory structures created by the user, and dynamically customized views. This data lives entirely within the client's local persistence layers (IndexedDB or localStorage) and is serialized exclusively as JSON19. The absolute security invariant governing this relationship is that derived data must never be transmitted back to the PHP canonical archive under any circumstances. If a user wishes to save their session or share their research, the state is exported locally as a downloaded JSON file directly from the browser memory, creating a strict downloadable source boundary. When the client application renders a view, it aggregates the read-only JSON from the backend with the mutable JSON from local storage. The rendering engine must explicitly tag data provenance in memory, ensuring that any user interface action attempting to "save" or "modify" a document mathematically checks the provenance tag and silently rejects the action if the data originated from the canonical archive. This segregation guarantees zero information leakage from the client's localized context back into the global source truth.

5. Terminal Security Invariants

The inclusion of a simulated command-line terminal within a web application is historically fraught with profound command injection risks. Because this terminal is purely theatrical and designed to mimic an operating system interface, the security architecture must enforce an absolute, unbridgeable severance between the terminal interface and any backend execution environment. The psychological temptation for a developer to pass a simulated terminal command directly to a backend shell environment must be structurally neutralized. The terminal must be implemented as a pure, deterministic vanilla JavaScript state machine. It operates by capturing keyboard events, parsing raw strings, tokenizing those strings based on a strict grammar, and mapping those tokens to a hardcoded dictionary of JavaScript functions entirely within the client. Under no circumstances should the raw string entered into the terminal be transmitted to the PHP backend. If a terminal command requires data from the backend (for instance, a simulated grep command over the historical archive), the client state machine must intercept the command, parse out the search term, and map it to a predefined, strongly typed API query parameter (e.g., GET /api/archive?search=term). This completely abstracts the shell syntax from the network request, preventing any form of backend shell escape or command injection5. Within the client-side sandbox itself, the terminal must never utilize functions that dynamically evaluate code. The use of eval(), setTimeout(string), or new Function() to process terminal commands is strictly prohibited, as these vectors instantly transform user input into executable code20. Command arguments must be strictly typed as strings or integers. If a user types a command such as echo "\<script\>alert(1)\</script\>" \> file.txt, the terminal parser must ensure the VFS stores the exact literal string as data, not as an executable node. When that file is subsequently "read" or displayed in the terminal UI, the rendering rules dictate it is rendered as text nodes, neutralizing any stored XSS within the virtual environment. Furthermore, the terminal parser must actively reject and sanitize shell metacharacters (|, ;, &, $()) unless they are explicitly simulated by the internal JavaScript engine for theatrical piping. If piping is simulated, the output of function A must be passed strictly as a literal string argument to function B, guaranteeing it is never evaluated as operational logic.

6. Virtual Filesystem Security

The Virtual Filesystem (VFS) exists to provide the user with the compelling illusion of a directory structure. Critical security risks emerge if the VFS logic can be manipulated to overwrite application memory via prototype pollution, or if virtual paths are erroneously passed to the backend, resulting in actual, catastrophic path traversal5. The VFS must be represented as a flattened map or a strictly controlled acyclic graph residing entirely within JavaScript memory. To prevent prototype pollution during path resolution—for example, an attacker attempting to access or write to a path like /home/user/\_\_proto\_\_/polluted—the VFS object dictionary must be instantiated using Object.create(null)21. Alternatively, the architecture should mandate the use of the native JavaScript Map object for all directory and file lookups. Using Object.create(null) or Map effectively strips the object of the default JavaScript prototype chain, ensuring that special keys like \_\_proto\_\_ or constructor are treated as literal strings rather than inherited object properties that could alter the global application state15. When a user interacts with the VFS, path resolution must occur entirely within the client-side sandbox. The algorithm responsible for resolving relative path indicators (../ and ./) must mathematically compute the virtual absolute path before querying the VFS map. If the VFS requires fetching a physical file from the canonical backend archive to fulfill a user request, the client must seamlessly translate the virtual path to an opaque, alphanumeric identifier. For example, a user attempting to read /archive/1999/index.html in the VFS must trigger a mapping function that results in a highly constrained API call, such as GET /api/archive?id=8a7b6c5d. The PHP backend must never accept a raw path string (e.g., GET /api/file?path=1999/index.html) from the client, entirely nullifying the threat of unsafe virtual paths bleeding into real backend filesystems23.

7. URL/Router Security

Routing occurs concurrently on both the client side—to support deep linking for desktop states and Research Trays—and on the server side via PHP API endpoints. Both environments require rigorous, independent security constraints to prevent unauthorized navigation and data exfiltration. On the backend, the PHP architecture must actively defend against dynamic file inclusion based on URL parameters, commonly known as Local File Inclusion (LFI) or directory traversal24. Routing must be implemented using strictly defined associative arrays that map exact URL paths to specific controller functions. When dispatching routes, the PHP match expression or in\_array functions must exclusively utilize strict, type-sensitive comparison (===)25. This strict comparison prevents severe type juggling bypasses, where PHP might silently cast an unexpected boolean or integer input to match a string key, leading to unauthorized route execution28. In scenarios where the backend must interact with the real filesystem to serve specific canonical archive files, the application is required to use basename() to strip all directory traversal characters and extract only the filename. Subsequently, realpath() must be used to resolve the absolute path, and the application must perform a stringent string comparison to verify that the resolved path strictly begins with the hardcoded, intended archive directory, aborting the operation if any deviation is detected5. The desktop environment relies heavily on URL fragments (hash routing) or the HTML5 History API for establishing deep links to specific application states (e.g., https://emulator.local/\#/workspace/tray1). The vanilla JavaScript router must parse these URLs with extreme prejudice to prevent query-string and hash injection. The router must never directly embed segments of the URL into the DOM (for example, by executing element.innerHTML \= location.hash), as this is a fundamental and easily exploitable source of DOM-based XSS1. Furthermore, the application must defend against open redirects. Any deep links that include redirection parameters (e.g., ?next=...) must be validated against a strict, hardcoded allowlist of known internal views. The application must never pass user-controlled input to window.location.assign() or window.location.replace() without mathematically verifying that the input begins exactly with the application's own origin or a strictly whitelisted internal hash path29.

8. Rendering/Escaping Rules

Because external sanitizers like DOMPurify or specialized Markdown libraries like Marked are strictly prohibited by the architectural requirements, the system must rely entirely on native browser APIs to enforce secure rendering. This rendering protocol is the single most critical defense mechanism against XSS, HTML injection, DOM clobbering, and CSS injection within the application. The use of innerHTML, outerHTML, insertAdjacentHTML, and document.write() is absolutely and universally prohibited across the entire vanilla JavaScript codebase2. These specific APIs are inherently dangerous because they parse arbitrary strings directly into executable DOM nodes, bypassing contextual escaping and leading inevitably to XSS if the string contains untrusted data. To support the rendering of research documents and formatted text, the application must implement a lightweight, bespoke Markdown parser written entirely in vanilla JavaScript. This custom parser must operate on a strict Abstract Syntax Tree (AST) methodology, entirely avoiding direct string-to-HTML concatenation30. The process operates as follows:

1. Lexical Analysis: The parser reads the Markdown string and tokenizes it based on regular expressions, identifying headers, paragraphs, bold text, and links.

2. AST Generation: These tokens are assembled into a hierarchical AST object that structurally represents the document32.

3. DOM Construction: A recursive rendering function traverses this AST. For each node, it uses the native document.createElement() API to create the appropriate HTML element (e.g., document.createElement('h1')).

4. Safe Content Insertion: The text content for these elements is inserted strictly using the textContent property33. The textContent API inherently encodes all characters; thus, a payload like \<script\>alert(1)\</script\> will be rendered visually as harmless text on the screen rather than being parsed and executed as an HTML tag by the browser engine.

By bypassing string-to-HTML conversions entirely, this architecture neutralizes the primary XSS vectors associated with Markdown parsing without necessitating a massive external sanitization library31. Furthermore, this methodology prevents CSS injection. If a user attempts to inject malicious styles to exfiltrate data or alter the layout, the AST parser simply treats the \<style\> tags or inline style="..." attributes as literal text nodes, rendering them inert. DOM Clobbering presents another severe risk. This vulnerability occurs when an injected HTML element utilizes an id or name attribute that silently overwrites global JavaScript variables or native window properties, due to legacy browser compatibility behaviors9. Because historical archives might contain legacy HTML with conflicting IDs, the emulator must actively defend its execution environment. The application must completely avoid reading configuration data or state variables from window.x or global variables7. If global objects must be referenced, developers are required to use Object.hasOwn(window, 'propertyName') and explicitly check the type of the retrieved object to ensure it is not unexpectedly an HTML element (e.g., \!(obj instanceof HTMLElement))7. When rendering derived views, the DOM construction logic must automatically strip or apply a unique cryptographic prefix to all id attributes originating from user-supplied or historical content, guaranteeing total namespace isolation9.

9. CSP Recommendation

A highly rigorous Content-Security-Policy (CSP) is mandatory to provide a robust layer of defense-in-depth against any theoretical escaping flaws in the bespoke rendering logic. Given the strict constraints of the project—specifically the total absence of external CDNs, third-party plugins, or remote scripts—the CSP can be configured to an exceptionally tight standard. The recommended CSP configuration is as follows:

HTTP Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data: blob:; font-src 'self'; connect-src 'self'; frame-src 'self' blob:; frame-ancestors 'none'; base-uri 'none'; form-action 'none'; object-src 'none'; require-trusted-types-for 'script';

This policy immediately neutralizes numerous attack vectors. The object-src 'none' directive provides critical object/embed restrictions, preventing the browser from executing legacy plugins like Flash or Java via \<object\>, \<embed\>, or \<applet\> tags that might be hidden within the historical archive data. The frame-ancestors 'none' directive ensures the emulator itself cannot be embedded into an attacker's site, neutralizing clickjacking threats13. To programmatically enforce the strict prohibition of innerHTML and other sink-based string executions, the CSP prominently features the require-trusted-types-for 'script' directive4. Even in the absence of external polyfills, modern browsers will natively intercept and block any attempt to assign raw strings to dangerous DOM sinks. The application will construct a minimal, native Trusted Types policy that explicitly and unconditionally rejects all string-to-HTML conversions. This forces all developers interacting with the codebase to adhere to the createElement and textContent methodology, ensuring the DOM remains mathematically protected from injection attacks14.

10. Security Headers

In conjunction with the CSP, the PHP backend must append a comprehensive suite of strict HTTP response headers to ensure fundamental browser-level protections are universally activated.

HTTP HeaderRecommended ValueSecurity Purpose and Mechanism
X-Content-Type-OptionsnosniffPrevents severe MIME-sniffing vulnerabilities. It ensures the browser strictly respects the provided Content-Type, neutralizing attacks where user-uploaded text files or JSON payloads are maliciously interpreted and executed as HTML by the browser37.
X-Frame-OptionsDENYPrevents the emulator from being embedded in a malicious iframe. While largely superseded by the CSP frame-ancestors directive, it remains a mandatory inclusion to ensure backward compatibility with legacy browsers13.
Cross-Origin-Opener-Policysame-origin(COOP) Isolates the browsing context, preventing external windows or tabs from holding a DOM reference to the emulator context, thereby mitigating cross-window attacks.
Cross-Origin-Embedder-Policyrequire-corp(COEP) Prevents the loading of cross-origin resources unless explicitly permitted by the target server, safeguarding application memory against sophisticated side-channel attacks like Spectre.
Referrer-Policyno-referrerEnforces total privacy by preventing information leakage via the Referer header when navigating out of the emulator or fetching assets, ensuring internal state or pathing is never broadcast to external entities38.

11. Storage Validation

Local persistence mechanisms, primarily localStorage and IndexedDB, are heavily utilized by the application to maintain the complex desktop state, encompassing the user's VFS, Research Tray organizations, and custom settings. Because local storage is directly accessible and modifiable via the browser's developer tools, it must be treated as a highly untrusted, potentially hostile input boundary. A primary risk in this domain is storage poisoning, which can lead to persistent mutation XSS. An attacker with temporary physical access, or an attacker exploiting a minor, transient XSS flaw, might poison the JSON payload resting in localStorage. If the application blindly parses and executes this JSON payload upon the next reload, the minor vulnerability is instantly upgraded into a persistent execution context or a persistent Denial of Service (DoS)14. To mitigate JSON injection and storage poisoning, the vanilla JavaScript must rigorously validate the data upon reading from localStorage. This requires enforcing a strict schema mapping. Because external JSON schema validators are banned, the application must utilize custom, recursive type-checking functions to verify that every key and value matches expected primitive types before the data is utilized. Furthermore, when the application loads the state, it frequently merges the saved user state with application default configurations. The custom deepMerge utility written for this purpose must explicitly and recursively filter out any keys named \_\_proto\_\_, constructor, and prototype to definitively eliminate prototype pollution vectors7. As a final defensive measure, the in-memory representation of the storage object should utilize JavaScript Map objects rather than standard Object literals whenever possible, as Map keys do not interact with the prototype chain, rendering prototype pollution impossible by design15.

12. Import/Export Validation

The emulator facilitates the sharing of historical research contexts by allowing users to import and export the "Research Tray" state. This capability requires processing completely untrusted file uploads purely within the client environment. When a user imports a state file, the vanilla JS FileReader must first perform strict file type and size validation. It must mathematically verify the file extension is strictly .json and the MIME type is application/json. The file size must be rigidly capped (e.g., at 5MB) to prevent client-side Denial of Service via intentional memory exhaustion. To prevent JSON injection, the imported file must be parsed using the native JSON.parse() method. A dedicated reviver function must be passed as the second argument (JSON.parse(text, reviver)). This reviver function is tasked with instantly identifying and stripping any prototype-polluting keys (\_\_proto\_\_, etc.) during the exact moment of parsing, before the object is fully constructed in memory. The application must also gracefully handle malformed imported Research Tray states. If the imported JSON contains corrupted UI mappings, missing keys, or logic that attempts to reference non-existent VFS nodes, the application must fail safely, reverting immediately to a clean, default state and alerting the user. It must never attempt to render a malformed DOM tree, which could lead to unexpected clobbering or injection vulnerabilities. Should the application ever be expanded to handle generic user-upload handling (e.g., allowing users to upload custom images or PDFs to the VFS), these uploads must be subjected to extreme isolation. The architecture must enforce strict MIME checking, strip all metadata, and ensure that uploaded files are only served back to the user via forced downloads (using the Content-Disposition: attachment header) or rendered strictly within the highly constrained iframe sandbox, preventing them from ever executing within the primary application origin.

The canonical archive, as well as user-derived notes, will inevitably contain hyperlinks directing the user to external resources. The handling of these links represents a critical trust boundary transition. To maintain context and protect the application, all external links must be programmatically forced to open in a new tab by appending the target="\_blank" attribute. Crucially, to prevent the newly opened external site from hijacking the emulator's own browsing context via the window.opener API, every external link must be strictly decorated with the rel="noopener noreferrer" attribute38. The application must also actively defend against unsafe external links. Before any href attribute is assigned to an anchor tag during the AST DOM construction phase, the URL must be evaluated to ensure the protocol strictly matches http: or https:, or is a valid relative path. The javascript:, data:, and vbscript: protocols must be explicitly blocked and stripped, as clicking a link with these protocols will execute arbitrary code within the context of the application, bypassing all HTML escaping mitigations31.

14. Failure-Safe Behavior

The entire system architecture must rely on a strict "fail closed" and default-deny paradigm to ensure stability and security when encountering anomalous data. In the rendering pipeline, if the custom Markdown AST parser encounters an unrecognized token, a malformed structure, or a deeply nested loop that threatens performance, it must drop the content entirely rather than attempting to guess the rendering intent or passing raw HTML to the DOM. In the routing infrastructure, if the PHP router or the client-side hash router encounters an undefined or malformed path, it must gracefully resolve to a safe, static 404 page rather than reflecting the invalid path back into the DOM, which is a classic cause of Reflected XSS. Finally, within the terminal simulation, any unrecognized command or malformed argument must yield a generic, hardcoded "Command not found" output. The terminal must never echo the raw, untrusted input back into the terminal output interface without applying strict text-node encoding, preventing command reflection attacks.

15. Security Regression Tests

To guarantee that the custom vanilla JS and PHP defenses remain intact over time, and to prevent future developers from accidentally reintroducing vulnerabilities, the environment must employ specific, automated security regression testing strategies.

Test CategoryMethodology and Assertion
Clobbering TestsAutomated test suites must inject payloads like \<form id="config"\>\<input name="settings"\>\</form\> into the historical web iframes and derived views. The test must assert that window.config remains undefined or resolves strictly to the original application configuration object, not the injected HTML element7.
Prototype Pollution TestsThe suite must feed payloads containing {"\_\_proto\_\_": {"isAdmin": true}} into the Research Tray import function and local storage parser. The test asserts that a newly created object {} evaluates {}.isAdmin as undefined after the deep merge operation7.
Path Traversal TestsAutomated requests must be submitted to the PHP backend containing ../../etc/passwd and heavily URL-encoded variants (%2e%2e%2f). The test must verify they result exclusively in 404 Not Found or 403 Forbidden errors, rather than 200 OK or 500 Internal Server Error responses17.
DOM XSS FuzzingThe pipeline must pass known XSS payloads (e.g., \<img src=x onerror=alert(1)\>) through the Markdown parser and VFS naming conventions. The test asserts that the resulting DOM contains safely encoded text nodes, not executable image elements or script tags.

16. Abuse Cases

The primary abuse cases stem directly from the psychological reality that developers and users alike view the theatrical desktop as a genuine execution environment, leading to unexpected vectors of compromise. Clipboard Risks: A user may copy text from a malicious historical archive or external site to paste into their derived research notes. The system clipboard often contains a hidden MIME type text/html payload alongside the plain text. If the vanilla JS paste event listener blindly pastes the raw clipboard data into the DOM, it triggers an immediate XSS vulnerability. To mitigate this, the paste event listener must intercept the clipboard data and strictly request only the text/plain format (e.clipboardData.getData('text/plain')), forcefully discarding any rich HTML formatting or embedded scripts. Drag-and-Drop File Exposure: The emulator supports drag-and-drop mechanics to move files into the "Research Tray." An attacker could socially engineer a user to drag a malicious HTML or SVG file from their real desktop into the browser emulator. If the emulator uses URL.createObjectURL() and attempts to render the file natively without forcing a download, the malicious script within the SVG or HTML will execute with full privileges within the emulator's origin. Drag-and-drop must strictly limit accepted MIME types to plain text or standard image formats (JPEG, PNG). Executable formats (HTML, SVG, XML) must be rejected entirely or explicitly processed as raw text to strip all execution contexts. Historical Web Frame Hijacking: The emulator reconstructs an archived webpage from 2002\. This webpage may contain a malicious script or an embedded object that attempts to navigate the parent window (the emulator). The legacy code executes window.top.location \= "http://evil.com", successfully hijacking the entire desktop environment. To prevent this, the historical web content must be rendered in an \<iframe\> utilizing the strict sandbox attribute. Crucially, the sandbox configuration must never combine allow-scripts and allow-same-origin simultaneously, as this combination allows the iframe to remove its own sandbox38. Furthermore, it must explicitly omit allow-top-navigation, ensuring the iframe is strictly partitioned and mathematically incapable of altering the emulator host URL13. Information Leakage: Because the emulator handles potentially sensitive research alongside historical data, there is a risk of information leakage via side channels. If a derived view requests an external resource (like an image), the URL path or search terms could be leaked. This is mitigated by the strict enforcement of the Referrer-Policy: no-referrer header, which ensures no contextual path data is appended to outbound requests.

17. Implementation Checklist

The following strict implementation checklist must be adhered to and verified by all developers contributing to the emulation environment.

ComponentTaskStatus Requirement
PHP BackendEnforce OS-level read-only permissions on the canonical archive directory for the web server user.Mandatory
PHP BackendEnforce strict routing using \=== array key matching to prevent type juggling26.Mandatory
PHP BackendImplement realpath() and basename() for all file retrievals, mathematically comparing the prefix to the allowed directory base5.Mandatory
PHP BackendApply the full suite of security headers (CSP, COOP, COEP, X-Frame-Options, X-Content-Type-Options)37.Mandatory
Vanilla JSUniversally ban innerHTML, outerHTML, insertAdjacentHTML, and document.write()4.Mandatory
Vanilla JSImplement the AST Markdown parser, utilizing document.createElement() and node.textContent for all rendering.Mandatory
Vanilla JSInitialize all VFS dictionaries and deep-merge targets with Object.create(null) or Map to prevent prototype pollution21.Mandatory
Vanilla JSCreate a JSON.parse() reviver function to strip \_\_proto\_\_, prototype, and constructor keys from all JSON ingests8.Mandatory
Vanilla JSSanitize all URL attributes (href, src) to ensure they begin with http://, https://, or relative paths, explicitly blocking javascript: URIs31.Mandatory
Vanilla JSConfigure iframe sandbox for all historical archives, explicitly omitting allow-same-origin and allow-top-navigation38.Mandatory
Vanilla JSEnsure all terminal commands execute strictly via local, typed Javascript functions, with zero raw strings passed to the backend.Mandatory

18. Minimum Security Acceptance Gate

Before the sophisticated browser-based desktop emulation can be confidently deployed to production environments, it must pass the following Minimum Security Acceptance Gate. These criteria are non-negotiable. First, a zero-dependency verification scan must confirm the total, provable absence of third-party JavaScript libraries, CDNs, PHP frameworks, or external widgets. Any inclusion of remote code immediately fails the deployment. Second, the application must successfully load and function entirely under a CSP that includes require-trusted-types-for 'script'. This serves as mathematical proof that no unmitigated string-to-DOM sinks exist anywhere in the vanilla JS codebase35. Third, the application must demonstrate absolute prototype pollution immunity. A simulated attack importing a deeply nested, malicious JSON file containing aggressive \_\_proto\_\_ payloads must fail to pollute the global Object.prototype, proving the efficacy of the JSON reviver and Object.create(null) implementations8. Fourth, automated requests attempting to fetch files outside the designated canonical archive directories using ../ and URL-encoded variants must yield consistent 404 Not Found or 403 Forbidden errors, proving the PHP backend's path traversal mitigations are sound39. Finally, execution of window.parent and window.top manipulation scripts within the historical web iframe must be actively blocked by the browser, confirming the strict efficacy of the iframe sandbox constraints and ensuring the emulator host remains fully isolated from the historical artifacts it renders13.

Works cited

1. Testing for DOM-Based Cross Site Scripting \- OWASP Foundation, https://owasp.org/www-project-web-security-testing-guide/latest/4-Web\_Application\_Security\_Testing/11-Client-side\_Testing/01-Testing\_for\_DOM-based\_Cross\_Site\_Scripting

2. What breaks when developers use dangerouslySetInnerHTML, https://nhimg.org/faq/what-breaks-when-developers-use-dangerouslysetinnerhtml-without-sanitizing-input/

3. Question concerning practical alternatives to innerHTML and, https://discourse.mozilla.org/t/question-concerning-practical-alternatives-to-innerhtml-and-insertadjacent-html-passing-amo-review/34806

4. Element: innerHTML property \- Web APIs | MDN, https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML

5. PHP Security 2: Directory Traversal & Code Injection \- Acunetix, https://www.acunetix.com/websitesecurity/php-security-2/

6. Symfony \- OWASP Cheat Sheet Series, https://cheatsheetseries.owasp.org/cheatsheets/Symfony\_Cheat\_Sheet.html

7. Prototype pollution, DOM clobbering, postMessage without origin, https://vibe-eval.com/patterns/prototype-pollution-and-dom-attacks/

8. Testing for Prototype Pollution \- WSTG \- Latest | OWASP Foundation, https://owasp.org/www-project-web-security-testing-guide/latest/4-Web\_Application\_Security\_Testing/07-Input\_Validation\_Testing/22-Testing\_for\_Prototype\_Pollution

9. DOM Clobbering Prevention \- OWASP Cheat Sheet Series, https://cheatsheetseries.owasp.org/cheatsheets/DOM\_Clobbering\_Prevention\_Cheat\_Sheet.html

10. Mitigating DOM clobbering attacks in JavaScript \- Snyk, https://snyk.io/blog/mitigating-dom-clobbering-attacks-javascript/

11. Directory Traversal (Path Traversal) \- Invicti, https://www.invicti.com/learn/directory-traversal-path-traversal

12. Path traversal and arbitrary PHP execution in ht.router.php \- Drupal, https://www.drupal.org/project/drupal/issues/3590068

13. Iframe XSS: postMessage, CSP, Sandboxing, & Clickjacking, https://7asecurity.com/blog/2026/06/iframe-xss-security/

14. Client-Side Cross-Site Scripting: Exploitation, Detection, Mitigation, https://d-nb.info/1295070162/34

15. Prototype Pollution in json-schema | CVE-2021-3918 | Snyk, https://security.snyk.io/vuln/SNYK-JS-JSONSCHEMA-1920922

16. json-schema is vulnerable to Prototype Pollution \- CVE-2021-3918, https://www.thesmartscanner.com/vulnerability-list/json-schema-is-vulnerable-to-prototype-pollution

17. Path Traversal | OWASP Foundation, https://owasp.org/www-community/attacks/Path\_Traversal

18. File Path Traversal \- Ismail Dawoodjee \- Medium, https://ismaildawoodjee.medium.com/file-path-traversal-6782ac650f2c

19. Builder Guide: Designing and Building Apps \- Cribl Docs, https://docs.cribl.io/apps/builder-guide/

20. env/common/code/cheats/web.md at master \- GitHub, https://github.com/nevesnunes/env/blob/master/common/code/cheats/web.md

21. Prototype Pollution Prevention \- OWASP Cheat Sheet Series, https://cheatsheetseries.owasp.org/cheatsheets/Prototype\_Pollution\_Prevention\_Cheat\_Sheet.html

22. How should security teams prevent prototype pollution in JavaScript, https://nhimg.org/faq/how-should-security-teams-prevent-prototype-pollution-in-javascript-tools-that-p/

23. 12.3.1 Clarification · Issue \#1136 · OWASP/ASVS \- GitHub, https://github.com/OWASP/ASVS/issues/1136

24. Testing for Local File Inclusion \- WSTG \- v4.2 | OWASP Foundation, https://owasp.org/www-project-web-security-testing-guide/v42/4-Web\_Application\_Security\_Testing/07-Input\_Validation\_Testing/11.1-Testing\_for\_Local\_File\_Inclusion

25. Mastering PHP's \array\_search()\ Function for Array Searching and, https://reintech.io/blog/mastering-php-array-search-function-array-searching-filtering

26. match \- Manual \- PHP, https://www.php.net/manual/en/control-structures.match.php

27. Why Array String Keys Are Not Type-Safe in PHP \- PHPStan, https://phpstan.org/blog/why-array-string-keys-are-not-type-safe

28. PHP array\_key\_exists \- loose on some types, strict on another, https://stackoverflow.com/questions/11905896/php-array-key-exists-loose-on-some-types-strict-on-another

29. Unvalidated Redirects and Forwards \- OWASP Cheat Sheet Series, https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated\_Redirects\_and\_Forwards\_Cheat\_Sheet.html

30. CommonMark parser and renderer in JavaScript \- GitHub, https://github.com/commonmark/commonmark.js/

31. How Can I Safely Render User-Submitted Markdown Without, https://talk.commonmark.org/t/how-can-i-safely-render-user-submitted-markdown-without-allowing-raw-html/5058

32. syntax-tree/mdast: Markdown Abstract Syntax Tree format \- GitHub, https://github.com/syntax-tree/mdast

33. Render a safe HTML subset in JavaScript \- Stack Overflow, https://stackoverflow.com/questions/11309993/render-a-safe-html-subset-in-javascript

34. Mastering DOM manipulation with vanilla JavaScript \- Hacker News, https://news.ycombinator.com/item?id=38162435

35. Discover | web.dev, https://web.dev/discover

36. TrustyMon: Practical Detection of DOM-based Cross-Site Scripting, https://wsp-lab.github.io/papers/park-trustymon-asiaccs25.pdf

37. Security | 2025 | The Web Almanac by HTTP Archive, https://almanac.httparchive.org/en/2025/security

38. HTML inline frame element \- MDN Web Docs \- Mozilla, https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/iframe

39. Testing for Path Traversal \- WSTG \- v4.2 | OWASP Foundation, https://owasp.org/www-project-web-security-testing-guide/v42/4-Web\_Application\_Security\_Testing/05-Authorization\_Testing/01-Testing\_Directory\_Traversal\_File\_Include