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. Some examples:
The Chromium development team has mentioned any method of
detection can be circumvented by navigating to
chrome://inspect > Pages > pause, but pausing the page's execution state
doesn't allow for live, interactive inspection and can be detected after
unpaused. It also may require pausing individual embedded frames, so if frames
trade heartbeats, there's a window where this desync could also be detected.
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
written in pure HTML or XHTML.
This extension currently only supports desktop devices using Chromium or Firefox and derivatives, such as Edge or Tor. We aim to support all the currently stable node types. The remaining node types are a secondary priority, as their obsoletion from modern browsers impedes testing.
Tor Browser currently doesn't support Firefox 142. However, this extension has
been tested on it. Until this is the case, remove the strict_min_version
property in the built manifest.json file or set it to a lower value, such as
140.0.
See our privacy policy
For more technical readers with a knowledge of browser extensions, the built manifest files show the following:
- We do not have any web accessible resources. If we did, we'd incorporate
use_dynamic_urlto prevent extension detection. - Running the extension in normal or incognito mode shares the same extension memory. This is to maintain parity with Firefox, as MV2 doesn't support the split config. As per our privacy policy, we don't store any sensitive data.
- 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.
- Although it would be nice, this extension does not use elevated permissions that would allow it to self-inspect.
There are also some additional security features we have implemented:
- The content script is injected in an isolated world and never modifies the DOM or, more generally, the global scope. This prevents detection while still allowing access to the DOM.
- Code is wrapped in an IIFE to restrict external access of internal members.
- All messages are validated to ensure that compromised renderers have limited scope.
- We make zero network requests, superseding an origin header bug in Firefox that could allow for detection.
- We use MV3, superseding an MV2 timing attack with Chromium (excluding Brave) that would allow extension detection
In order to use this extension, you must first build it from source.
- Clone this repository
- Open your IDE or terminal to the root of the project
- Run
npm ito install dependencies - Run
npm run build -- <browser> <mode>, where:<browser>ischromeorfirefox<mode>isdevorprod
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
manifest.jsonfile
- 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.
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 view the page source, the doctype differs, because the page uses deprecated XHTML features.
- XML declarations aren't completely accurate, as in order to use properties that aren't deprecated or obsolete, we estimate some values based on similar, standardized 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, mostly just the latest time. - 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 this extension can't inspect its own inspector. - This extension is unable to view the original source, as it reconstructs the source from what's visible. Browsers render non-(X)HTML documents and XML documents without attached stylesheets as (X)HTML. In other words, this extension sees what you see.
See our contributing guidelines.
Similar to the build script, we offer a web server for iterative development
via hot-reloading. It can be started by running
npm run start:<browser>:<mode>. Though it will attempt to reload on changes it
can't hot-reload, you can trigger manual reloading by typing rs and hitting
enter in the terminal. It will not reload the underlying Nodemon process, so
stopping and starting the process will be necessary to update Nodemon
and its dependencies.
- Extension boilerplate
- Code review icons created by Freepik - Flaticon
- The community members involved in contribution and translation