https://aistudio.google.com/app/prompts/new_chat
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.