Google AI Studio

https://aistudio.google.com/app/prompts/new_chat

Is there any way to detect document.write is replaced with another function?

Yes, there are several ways to detect if `document.write` has been replaced with another function, with varying degrees of reliability and complexity.

Here are the common methods:

1.  **Comparing with a Pristine `document.write` (Most Reliable)**
    You can create a new, clean iframe, get its `document.write` function, and compare it to the current `document.write`.

    ```javascript
    function isDocumentWriteReplaced() {
        // Create an iframe to get a pristine document object
        const iframe = document.createElement('iframe');
        iframe.style.display = 'none'; // Don't show it
        document.body.appendChild(iframe);

        let isReplaced = false;
        try {
            // Get the document.write from the pristine iframe
            const pristineDocumentWrite = iframe.contentWindow.document.write;

            // Compare it with the current document.write
            if (document.write !== pristineDocumentWrite) {
                isReplaced = true;
            }
        } catch (e) {
            // If an error occurs (e.g., security restrictions in some edge cases),
            // it's harder to tell, but could indicate tampering or an unusual environment.
            console.error("Error checking document.write:", e);
            isReplaced = true; // Assume replaced if we can't verify
        } finally {
            // Clean up the iframe
            document.body.removeChild(iframe);
        }
        return isReplaced;
    }

    if (isDocumentWriteReplaced()) {
        console.log("document.write has been replaced!");
        console.log("Current document.write:", document.write.toString());
    } else {
        console.log("document.write is the original native function.");
    }

    // Example of replacing it:
    // const originalDocWrite = document.write;
    // document.write = function(...args) {
    //   console.log("Hijacked document.write called with:", args);
    //   // originalDocWrite.apply(document, args); // Optionally call the original
    // };

    // if (isDocumentWriteReplaced()) {
    //    console.log("After replacement: document.write has been replaced!");
    // }
    ```

2.  **Checking `Function.prototype.toString()` Output**
    Native browser functions, when `toString()` is called on them, typically return a string like `"[native code]"`. User-defined functions will return their source code.

    ```javascript
    function isDocumentWriteNative() {
        try {
            const str = Function.prototype.toString.call(document.write);
            // Or simply: const str = document.write.toString();
            return str.includes('[native code]');
        } catch (e) {
            // Could be an indication of something unusual or an attempt to block this check
            return false;
        }
    }

    if (!isDocumentWriteNative()) {
        console.log("document.write might have been replaced (doesn't look native).");
        console.log("Current document.write:", document.write.toString());
    } else {
        console.log("document.write appears to be the native function.");
    }
    ```
    **Caveat:** A sophisticated replacement could try to override the `toString` method of the replacement function to also return `"[native code]"`. However, this is less common.

3.  **Storing the Original Reference Early (Timing Dependent)**
    If you can execute your detection code *before* any other script that might modify `document.write`, you can store the original reference.

    ```javascript
    // --- This code must run very early, ideally the first script on the page ---
    const earlyRefDocumentWrite = document.write;
    // --- End of early code ---

    // ... later in your application ...
    function checkStoredReference() {
        if (document.write !== earlyRefDocumentWrite) {
            console.log("document.write was replaced (compared to early reference)!");
            return true;
        }
        console.log("document.write is the same as the early reference.");
        return false;
    }

    // checkStoredReference();
    ```
    **Caveat:** This is highly dependent on script execution order. If another script modifies `document.write` before `earlyRefDocumentWrite` is assigned, this method won't detect it correctly.

4.  **Checking the `name` property (Less Reliable)**
    Native functions often have a `name` property. For `document.write`, it should be `"write"`.

    ```javascript
    if (document.write.name !== 'write') {
        console.log(`document.write.name is "${document.write.name}", expected "write". It might be replaced.`);
    } else {
        console.log("document.write.name is 'write'.");
    }
    ```
    **Caveat:** A replacement function can also be explicitly named `"write"`: `document.write = function write() { /* ... */ }`. So this is not a strong indicator on its own.

**Why would `document.write` be replaced?**

*   **Malicious Scripts (XSS):** To intercept data, redirect users, or inject other malicious content.
*   **Ad Blockers/Privacy Tools:** Some extensions might neutralize `document.write` to prevent certain types of ads or trackers.
*   **Frameworks/Libraries (Less Common):** A framework might wrap or modify it for specific reasons, though this is rare and generally discouraged for `document.write`.
*   **Debugging/Monitoring:** Developers might temporarily override it to log calls or modify its behavior during development.

**Recommendation:**

The **iframe comparison method (1)** is generally the most robust way to check if the `document.write` function object is the browser's original native implementation. The `toString()` method (2) is a good, simpler heuristic.