Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .hintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"extends": ["development"]
}
}
73 changes: 46 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,33 +46,36 @@ file shows the following:

There are also some additional security features we have implemented:

- Content scripts are injected in an isolated world and never modify the DOM.
- 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 EC6 classes, we use nested functions to create truly
private methods in our content script. I.e:
- Instead of ES6 classes, we use nested functions to create truly
private methods in our content script. I.e, something like the following:

<!-- Prettier is per-file, not per-language -->
<!-- prettier-ignore -->
```ts
(async () => {
function _privateMethod() {
// Super secret internals
}

function publicMethod() {
// Public API
}

return {
publicMethod
};
})();
const clazzFactory = (async () => {
async function _privateMethod(): Promise<void> {
// Super secret internals
}

function publicMethod(): void {
// Public API
}

return {
publicMethod
};
});
const clazz = clazzFactory();

clazz.publicMethod();
```

<!--


<!--
- All messages are validated to ensure that no part of the extension has been
[compromised](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/security/compromised-renderers.md#Messaging).
-->
-->

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
Expand Down Expand Up @@ -171,8 +174,25 @@ 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.

## Caveats
<!-- ### Source Inspection flow -->

## Issues and Contribution

For a list of planned features and fixes, see the [TODOs](TODO.md)

Below are some caveats this extension has that don't have immediate fixes:

- [XML declarations](https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-XMLDecl)
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](https://developer.mozilla.org/en-US/docs/Web/API/Document/xmlVersion),
[xmlEncoding](https://developer.mozilla.org/en-US/docs/Web/API/Document/xmlEncoding)
and [xmlstandalone](https://developer.mozilla.org/en-US/docs/Web/API/Document#document.xmlstandalone)
document properties.
- We can't currently catch every attribute event. Because `MutationObserver`s
run at the microtask level, and because attribute `MutationRecord`s 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://` and `about://`, cannot be inspected. Ironically, this
Expand All @@ -190,16 +210,15 @@ the page, such as with ad blocking.
would then allow websites to detect the extension. There is nothing any
browser extension can do to cicrumvent this. Some examples:
- In Chrome, a website could send a GET request to
`chrome-extension://<YOUR_ID_HERE>/manifest.json`. If it's successful, you
have our extension installed.
`chrome-extension://<YOUR_ID_HERE>/manifest.json`. If it's successful, you
have our extension installed.
<!-- Not applicable to us, because we make zero network requests -->
<!--
- In Firefox, by clicking the extension button and activating the inspector,
the website can look at its
[origin header](https://bugzilla.mozilla.org/show_bug.cgi?id=1405971)
and determine that you're trying to use our extension.

## Contribution

For a list of known issues and planned features, see the [TODOs](TODO.md)
-->

## Credits

Expand Down
67 changes: 28 additions & 39 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,56 @@

## Functional Priorities

- StateManager needs to process multiple messages per render, defer rendering,
or decouple the renderer (`setState`) to avoid
`Uncaught Error: Too many re-renders. React limits the number of renders`
`to prevent an infinite loop` on complex websites
- Add Firefox extension support,
see: [signing](https://extensionworkshop.com/documentation/publish/)
- Write `README.md`
- How it Works section
- Add dropdown functionality to all nodes with children
- For accessibility purposes, add the ability
to select and navigate between elements in the inspector
- When elements are added, children should be processed
- Fix adding nodes with previous node IDs, as they seem to be rendered
out of order when, e.g, removing a node in DevTools and undoing the action
- Render XML attributes in an XHTML document, e.g:

```xhtml
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
```

- When elements are added, children and text should be processed
- Fix duplicate attribute names when adding a second or more attributes
to an element using DevTool's "Edit as HTML" function
(possible race condition)
- Fix adding nodes with previous node IDs
(e.g, removing a node in DevTools and then undoing the action)
- For security reasons, validate all messages to ensure no compromisation
has occurred within any untrustworthy part of the extension
(see: the [issue tracker](https://issuetracker.google.com/issues/311491887)
and the referenced
[docs](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/security/compromised-renderers.md#Messaging))
- Tell the user when a protected page cannot be inspected
- Add documentation where it's missing or necessary (e.g, @param or @returns)
- Support attribute mutations
- Have attributes and text referenced through an ID in virtual nodes instead
of storing key-value pairs and regenerating keys by a fixed pattern
- Add documentation where it's missing or necessary (e.g, @param or @template)
- Support character data mutations
- Finish supporting all applicable node types
- Test nested document nodes (see: [SO](https://stackoverflow.com/questions/26010355/is-there-a-way-to-uniquely-identify-an-iframe-that-the-content-script-runs-in-fo))
- Shadow roots can be accessed using
[`chrome.dom.openOrClosedShadowRoot`](https://developer.chrome.com/docs/extensions/reference/api/dom?hl=en#method-openOrClosedShadowRoot)
- [Validate](https://validator.w3.org) sample inspector pages
conform to a11y standards

## Technical Priorities

- StateManager needs to process multiple messages per render
or defer rendering to avoid
`Uncaught Error: Too many re-renders. React limits the number of renders`
`to prevent an infinite loop` on complex websites
- Rethink debug view (possibly a test-id field?)
- For a11y purposes, add the ability
to select and navigate between elements in the inspector
- Add an [error boundary](https://react.dev/link/error-boundaries)
for improved debugging UX
- Move top-level configuration files to their own folder
- Migrate ChildManager to a
[reducer](https://react.dev/learn/extracting-state-logic-into-a-reducer)
for increased maintainability
- ChildManager prop drills `nodes`:
use a shared context and provider (in ChildManager) to manage deep node state
- Format VS Code editor on save with Prettier
- Configure ESLint:
- Ensure ESLint config file path is correctly recognized and interpreted
- Add chromium-extension-boilerplate as an upstream repo dependency
- Add a light mode:
- Replace Prettier formatting with ESLint to resolve rule conflicts
- Add a light mode toggle

```css
:root {
color-scheme: light dark;
color: light-dark();
}
```
## Backlog Priorities

## Future Priorities

- Replace shared assert function with node:assert.assert
- Remove redundant information from messages and props
- Tell the user when a protected page cannot be inspected
- Configure React source map generation
(`React.createElement` statements are ugly)
- Create and add donation medium
- Modify ESLint config:

Expand All @@ -87,11 +78,9 @@
(i.e, script injection or manifest registering)
- Support Webpack chunking
- Add unit tests and end-to-end tests
- Add Firefox extension support (see: [signing](https://extensionworkshop.com/documentation/publish/))
- [Internationalize](https://developer.chrome.com/docs/extensions/reference/api/i18n)
- If project scope allows it, add an options page to allow the content script
to be automatically reinjected on page or tab (re)load
- If project scope allows it, add a network request viewer
- If the project scope allows it, install the dependencies necessary for Webhint
and its .hintrc config file and resolve any vulnerabilities
- If the project scope allows it, add more accessibility customization
- If the project scope allows it, install the dependencies necessary
for Webhint and its .hintrc config file and resolve any vulnerabilities
Loading