Note: This extension currently only supports desktop devices using Chrome or Chromium derivatives, such as Edge. We aim to support all the node types currently in use and not deprecated as per MDN.
If you're a developer who ever needs to debug something within their browser, DevTools is probably the most popular debugger, as it's shipped with Chrome. It's a great resource, as are the many open-source alternatives. However, these debuggers all rely on the browser's native debugger. Some very smart people have figured out ways to detect when a debugger has been attached to their site, whether through DevTools or through browser.debugger.
Enter source-inspector. We attempt to circumvent detection, so that you can
safely view the live HTML source of even the sketchiest websites. This tool is
intended to let you inspect the source of any website live, whether it's
rendered in HTML or XHTML.
This extension does not record any data. In the future, we plan to possibly add an options menu. This will be the extent of data collected, (i.e, yes/no), and it will not be sent or broadcast anywhere. We also do not collect browser history. We will never share any data with anyone, not even ourselves. We believe that open source comprises source transparency and user privacy. Your data is yours and yours alone, and we plan to keep it that way. Plus, this is an extension intended for offline use.
For more technical readers with a knowledge of browser extensions, the manifest file shows the following:
- We do not have any web accessible resources.
- Running the extension in normal or incognito mode uses separate processes and separate memory. This means the extension in one mode cannot communicate with- or access any data from- the other. In other words, our extension respects incognito mode.
- This extension uses minimal permissions for security purposes.
- DevTools or any external debugger is not used. We wrote ours from scratch using plain JavaScript inspection and messaging.
- We don't use any host permissions. Instead, we only perform anything on the active tab upon user initiation.
There are also some additional security features we have implemented:
-
The content script are injected in an isolated world and never modify the DOM. This prevents detection while still allowing access to the DOM.
-
Instead of ES6 classes, we use nested functions to create truly private methods in our content script. I.e, something like the following:
const clazzFactory = (async () => { async function _privateMethod(): Promise<void> { // Super secret internals } function publicMethod(): void { // Public API } return { publicMethod }; }); const clazz = clazzFactory(); clazz.publicMethod();
The only possible means of detecting this extension could be a timing attack, which is beyond the skill set of this repository's owner. If you're able to present a proof-of-concept or potential patches, please feel free to do so. For now, this remains only an unproven theory with no supporting evidence.
Finally, for transparency's sake, yes, the initial commit added a lot. That's because this project had been in the works for a while. This was a rich opportunity to learn about React and more technical (X)HTML. And in learning about React through this project, there were a few migrations to get the nesting of diverse component states functional and implemented to reasonable and modern coding standards.
In order to use this extension, you must first build it from source.
- Download the source code
- Open your IDE or terminal to the root of the project
- Run
npm installto install dependencies - To build the extension, start a development server:
- For users, run
npm run start:<browser>:prodto run in production mode, where<browser>ischrome(port 8081) orfirefox(port 8083). This will create a folderdist/<browser>/prodcontaining the built extension. - For developers, run
npm run start:<browser>:dev, to run in development mode, where<browser>ischrome(port 8080) orfirefox(port 8082). This will create a folderdist/<browser>/devcontaining the built extension.
- For users, run
- Optionally, when the server says that webpack has compiled successfully, you can stop the server. (Ctrl+C, or Command+C on Mac) It's only necessary to keep it running if you plan on making changes to the source code and having them be patched in live. Though, in Chromium-based browsers, you will still be required to reload the extension manually.
You should now have an installable extension.
This extension is not available on any browser web store, such as the Chrome or Firefox web store. It's recommended that you pin the extension after installation for quick and easy access, but it's not required.
- In the address bar, type
chrome://extensionsand hit enter - If it's not already enabled, click the
Developer modetoggle - Click the
Load unpackedbutton - Select the built extension folder
- In the address bar, type
about:addonsand hit enter - If it's not already enabled, click the
Developer modetoggle - Click the
Load Temporary Add-onbutton - Select the built extension folder
- Right click the extension icon in the extension toolbar
- Click
Manage extension - Find the extension and click
Details
This is the extension details page. From here, you can toggle the extension's permissions to:
- Run in incognito/private mode
- Run in local files (i.e,
file://)
and possibly more, depending on your browser.
If you want evidence towards our claim of being "undetectable", or you're curious about the project's inner workings, this is the section for you.
This extension is divided into three parts:
When you click on the extension icon, the popup is the source inspection tab that opens.
This is the internal event handler for any protected extension functions, such as opening the popup. It also passes events between the popup and content script.
This is a script that's "injected" into the page you're attempting to inspect. Basically, it's run alongside the page and has access to the page's source. If our extension wasn't trying to be undetectable, we could use this to modify the page, such as with ad blocking.
For a list of planned features and fixes, see the TODOs
Below are some caveats this extension has that don't have immediate fixes:
- Obsolete node types are either ignored or replaced by modern browsers, which makes it particularly difficult for us to support them. For instance, try the entity reference test in your browser. If you're using a modern browser, everything should be valid HTML. But if you look at the page source, there's something weird in the doctype...
- XML declarations are not included in inspected output due to the lack of Firefox DOM APIs necessary to easily regenerate one. For more information, see the xmlVersion, xmlEncoding and xmlstandalone document properties.
- We can't currently catch every attribute event. Because
MutationObservers run at the microtask level, and because attributeMutationRecords don't include the new attribute value, we don't yet have a way to get the values of attributes every time they're updated, only most times. - This extension is subject to the same restrictions as any extension. That
means that protected URLs, such as
chrome://,edge://,chrome-extension://andabout://, cannot be inspected. Ironically, this means that you can't inspect the extension's own source code. - Due to how browsers render XML documents that don't have attached stylesheets, XML is only partially supported. If the XML document is styled, then it should be fully supported. However, many modern browsers may add some boilerplate to the rendered document to say that there's no stylesheet. Because of how this extension works and the restrictions we apply to it for the user's sake, this will be included in the inspected source. In other words, if you can see it, so can this extension.
- My own extension boilerplate
- Code review icons created by Freepik - Flaticon