@hakam-aldeen-kh/blix 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +174 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ a dockable panel with a waterfall, diffing, replay and HAR/cURL export.
|
|
|
8
8
|
The entire panel is eliminated from production builds — see
|
|
9
9
|
[Production elimination](#production-elimination).
|
|
10
10
|
|
|
11
|
-
Release notes are in [CHANGELOG.md](CHANGELOG.md).
|
|
11
|
+
Release notes are in [CHANGELOG.md](https://github.com/Hakam-aldeen-Kh/blix/blob/main/CHANGELOG.md).
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -32,6 +32,13 @@ while resolving that import. devDependencies have to be present at build time.
|
|
|
32
32
|
Dropping them from the final runtime image is fine: nothing from Blix reaches
|
|
33
33
|
the production output anyway.
|
|
34
34
|
|
|
35
|
+
The package ships **ESM only**. Both entry points declare `"types"` and
|
|
36
|
+
`"import"` in `exports`, with no `"require"` and no `"default"` fallback, so
|
|
37
|
+
`require("@hakam-aldeen-kh/blix")` and CJS-only tooling — an older Jest config
|
|
38
|
+
is the usual one — fail with `ERR_PACKAGE_PATH_NOT_EXPORTED`. That is by
|
|
39
|
+
design, not a packaging bug: a dev tool that is eliminated from production has
|
|
40
|
+
no reason to carry a second build output.
|
|
41
|
+
|
|
35
42
|
### Peer dependencies
|
|
36
43
|
|
|
37
44
|
`react` and `react-dom` (v19) are required. `axios`, `@reduxjs/toolkit` and
|
|
@@ -351,12 +358,14 @@ as a bounded hex preview plus byte length). They go through the same
|
|
|
351
358
|
serialization and truncation rules as the plaintext bodies, both in the panel
|
|
352
359
|
and in IndexedDB, so a multi-megabyte ciphertext cannot blow out the log.
|
|
353
360
|
|
|
354
|
-
> **Redaction.** Blix masks sensitive *headers*
|
|
355
|
-
>
|
|
356
|
-
>
|
|
357
|
-
> you pass
|
|
358
|
-
>
|
|
359
|
-
>
|
|
361
|
+
> **Redaction.** Blix masks sensitive *headers* — and the list is closed at
|
|
362
|
+
> exactly four, matched exactly: `authorization`, `cookie`, `set-cookie`,
|
|
363
|
+
> `x-api-key`. It does **not**, and cannot, redact anything inside the values
|
|
364
|
+
> you pass here — they are bodies, and Blix has no way to tell ciphertext from
|
|
365
|
+
> plaintext. If you pass an already-decrypted body as `response`, whatever
|
|
366
|
+
> secrets it contains are shown in the panel verbatim and written to IndexedDB
|
|
367
|
+
> when preserve-log is on. Pass the wire form, not the decrypted one. See
|
|
368
|
+
> [Security](#security) for the full picture.
|
|
360
369
|
|
|
361
370
|
#### `withInitiatorCapture(instance)`
|
|
362
371
|
|
|
@@ -684,11 +693,15 @@ There is no API for adding your own; a theme is ~20 colours in
|
|
|
684
693
|
|
|
685
694
|
### `dbName` — when you need it
|
|
686
695
|
|
|
687
|
-
The panel
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
696
|
+
The panel can persist its log to IndexedDB so it survives a reload, but only
|
|
697
|
+
when you opt in: **preserve-log is off by default**, and while it is off
|
|
698
|
+
nothing is written to disk. See [Security](#security) for what the toggle does
|
|
699
|
+
and what lands there.
|
|
700
|
+
|
|
701
|
+
IndexedDB is scoped **per origin**, not per app — so two apps served from the
|
|
702
|
+
same origin (different ports in dev are different origins, but path-based
|
|
703
|
+
routing, multi-zone Next.js setups and anything behind one reverse proxy are
|
|
704
|
+
not) both open `nm-devtools` and interleave their logs into one database.
|
|
692
705
|
|
|
693
706
|
Give each app its own name to keep them separate:
|
|
694
707
|
|
|
@@ -788,6 +801,154 @@ example above, which is written in the guarded form.
|
|
|
788
801
|
|
|
789
802
|
---
|
|
790
803
|
|
|
804
|
+
## Security
|
|
805
|
+
|
|
806
|
+
Blix is a debugger, and it captures what a debugger has to capture: **full
|
|
807
|
+
request and response bodies, request and response headers, Redux action
|
|
808
|
+
payloads and state diffs, and realtime frames**. It captures them in
|
|
809
|
+
plaintext — the request body *before* your encryption interceptor runs, the
|
|
810
|
+
response body *after* your decryption interceptor. That is the whole point of
|
|
811
|
+
it, and it means the log holds whatever your traffic holds, credentials
|
|
812
|
+
included.
|
|
813
|
+
|
|
814
|
+
By default all of that is **in memory only**. Nothing is written to disk, and
|
|
815
|
+
a reload starts clean.
|
|
816
|
+
|
|
817
|
+
All of it is dev-only regardless. Capture is gated on
|
|
818
|
+
`process.env.NODE_ENV === "development" && typeof window !== "undefined"`, and
|
|
819
|
+
the database is opened only when the panel mounts — see
|
|
820
|
+
[Production elimination](#production-elimination).
|
|
821
|
+
|
|
822
|
+
### What reaches disk, and when
|
|
823
|
+
|
|
824
|
+
**Preserve-log** is the sole gate on disk writes. It is off by default, and
|
|
825
|
+
while it is off nothing Blix captures reaches IndexedDB — the store is
|
|
826
|
+
actively cleared on every panel mount.
|
|
827
|
+
|
|
828
|
+
Three ways to toggle it:
|
|
829
|
+
|
|
830
|
+
| Where | Note |
|
|
831
|
+
| --- | --- |
|
|
832
|
+
| Toolbar button | Hidden in the compact layout |
|
|
833
|
+
| **⋯ More actions** overflow menu | — |
|
|
834
|
+
| `Shift+L` | — |
|
|
835
|
+
|
|
836
|
+
All three require the panel to be mounted.
|
|
837
|
+
|
|
838
|
+
**Turning it on is retroactive.** The toggle does not mean "from now on".
|
|
839
|
+
Switching it on writes every entry already sitting in the live buffer — the
|
|
840
|
+
session you have *already* captured — to disk immediately, along with
|
|
841
|
+
everything that follows. If you have just reproduced a login flow and then
|
|
842
|
+
reach for the toggle, you have written that login flow to disk. Read that
|
|
843
|
+
again before you assume otherwise; it is the one behaviour here that
|
|
844
|
+
reasonably surprises people.
|
|
845
|
+
|
|
846
|
+
With preserve-log on, this is what is kept:
|
|
847
|
+
|
|
848
|
+
| Captured | Persisted |
|
|
849
|
+
| --- | --- |
|
|
850
|
+
| HTTP entries — bodies, headers, timings | yes |
|
|
851
|
+
| Realtime frames | yes |
|
|
852
|
+
| The encrypted envelope, if you call `captureEncrypted` | yes |
|
|
853
|
+
| Panel preferences and budget totals | yes — preferences are also mirrored to `localStorage` |
|
|
854
|
+
| Redux actions, payloads and diffs | only if you pin the row |
|
|
855
|
+
| Query cache rows | only if you pin the row |
|
|
856
|
+
|
|
857
|
+
### What is redacted
|
|
858
|
+
|
|
859
|
+
Exactly four header names, and nothing else:
|
|
860
|
+
|
|
861
|
+
| Header | Match |
|
|
862
|
+
| --- | --- |
|
|
863
|
+
| `authorization` | exact, case-insensitive |
|
|
864
|
+
| `cookie` | exact, case-insensitive |
|
|
865
|
+
| `set-cookie` | exact, case-insensitive |
|
|
866
|
+
| `x-api-key` | exact, case-insensitive |
|
|
867
|
+
|
|
868
|
+
The match is **exact on the full header name** — not a prefix, not a
|
|
869
|
+
substring, not a pattern. Near-miss names are *not* covered and are written in
|
|
870
|
+
the clear: `x-auth-token` and `api-key` are the two that most often catch
|
|
871
|
+
people out, and `proxy-authorization`, `x-csrf-token` and
|
|
872
|
+
`x-amz-security-token` are equally uncovered. If your auth travels in a header
|
|
873
|
+
that is not one of the four above, it is captured verbatim.
|
|
874
|
+
|
|
875
|
+
Masking is partial rather than total: for a value longer than 12 characters
|
|
876
|
+
the first 8 and last 4 survive, so you can still tell which token you sent.
|
|
877
|
+
Shorter values are replaced outright.
|
|
878
|
+
|
|
879
|
+
**Nothing inside a body is redacted.** Request bodies, response bodies, error
|
|
880
|
+
payloads, the encrypted request/response values, Redux payloads and diffs, and
|
|
881
|
+
realtime frames all pass through a size-only walker — it truncates large
|
|
882
|
+
values and never once inspects a key name. A `password`, `ssn` or
|
|
883
|
+
`refreshToken` field is captured, and with preserve-log on written to disk,
|
|
884
|
+
exactly as it appears. Blix has no mechanism to do otherwise: it has no schema
|
|
885
|
+
for your payloads and no way to tell a secret from any other string.
|
|
886
|
+
|
|
887
|
+
### Retention and clearing
|
|
888
|
+
|
|
889
|
+
| Bound | Value |
|
|
890
|
+
| --- | --- |
|
|
891
|
+
| Records | 200 |
|
|
892
|
+
| Total size | 24 MB — HTTP entries only |
|
|
893
|
+
| Per payload field | 512 KB |
|
|
894
|
+
| Eviction | oldest first, once either bound is exceeded |
|
|
895
|
+
| Time-based expiry | none |
|
|
896
|
+
|
|
897
|
+
There is **no TTL of any kind**. A record leaves the database when 200 newer
|
|
898
|
+
records or 24 MB of newer traffic push it out, or when you clear it yourself.
|
|
899
|
+
On a low-traffic app with preserve-log left on, a captured token stays in the
|
|
900
|
+
browser profile indefinitely.
|
|
901
|
+
|
|
902
|
+
To purge, use the persisted-size label in the status bar — the one reading
|
|
903
|
+
`12 saved · 3.4 MB`. It is the control: click once to arm it, at which point
|
|
904
|
+
it changes to `Purge saved log?`, and click again to delete the database.
|
|
905
|
+
|
|
906
|
+
Switching preserve-log **off** also clears the stored entries, so turning it
|
|
907
|
+
off is itself a way to drop everything Blix has written.
|
|
908
|
+
|
|
909
|
+
Both paths clear the captured entries; Purge additionally deletes the
|
|
910
|
+
IndexedDB database itself. **Your panel preferences survive either way** —
|
|
911
|
+
they are mirrored to `localStorage`, and a fresh database is re-seeded from
|
|
912
|
+
that mirror on the next boot. There is no UI or API for clearing them.
|
|
913
|
+
|
|
914
|
+
**The purge control is only rendered while preserve-log is on**, so once you
|
|
915
|
+
have switched it off there is nothing left in the UI to press. There is no
|
|
916
|
+
programmatic API for either path.
|
|
917
|
+
|
|
918
|
+
### Threat model
|
|
919
|
+
|
|
920
|
+
IndexedDB is scoped **per origin, not per app**, and it is not encrypted at
|
|
921
|
+
rest. Any script running on that origin can read Blix's database — including
|
|
922
|
+
browser extension content scripts with access to the origin. Whatever you
|
|
923
|
+
capture is readable by whatever you have installed.
|
|
924
|
+
|
|
925
|
+
Export and copy move captured data out of the browser entirely:
|
|
926
|
+
|
|
927
|
+
| Path | Carries |
|
|
928
|
+
| --- | --- |
|
|
929
|
+
| HAR export | Decrypted request and response bodies |
|
|
930
|
+
| JSON / NDJSON export | Everything captured — frames, Redux diffs, timings |
|
|
931
|
+
| **Copy as cURL** / **Copy as fetch** | Headers and bodies, with the four redacted headers masked — so the output is not a working request |
|
|
932
|
+
|
|
933
|
+
HAR is the one to watch. It is a plain JSON file carrying your decrypted
|
|
934
|
+
bodies, and it is the artifact most likely to end up attached to a ticket.
|
|
935
|
+
|
|
936
|
+
### If you handle sensitive data
|
|
937
|
+
|
|
938
|
+
- **Leave preserve-log off unless you actively need it.** It is off by
|
|
939
|
+
default. In-memory capture already gives you the entire panel; the toggle
|
|
940
|
+
buys you nothing but survival across a reload.
|
|
941
|
+
- **Clear the log after any session that captured an auth flow** —
|
|
942
|
+
switching preserve-log off is enough; Purge additionally deletes the
|
|
943
|
+
database, though neither removes your panel preferences.
|
|
944
|
+
- **Use the Redux `ignore` option** for action types that carry credentials or
|
|
945
|
+
personal data, so they are never captured in the first place. See
|
|
946
|
+
[Redux](#redux--createreduxmonitormiddlewareoptions).
|
|
947
|
+
- **Treat an exported HAR as a credential-bearing file.** Do not attach one to
|
|
948
|
+
a public issue, and do not commit one.
|
|
949
|
+
|
|
950
|
+
---
|
|
951
|
+
|
|
791
952
|
## Entry points
|
|
792
953
|
|
|
793
954
|
| Import | Contents | `"use client"` |
|
|
@@ -810,4 +971,4 @@ The `/capture` entry exports `attachHttpMonitor`, `captureEncrypted`,
|
|
|
810
971
|
|
|
811
972
|
## License
|
|
812
973
|
|
|
813
|
-
MIT — see [LICENSE](
|
|
974
|
+
MIT — see [LICENSE](https://github.com/Hakam-aldeen-Kh/blix/blob/main/LICENSE).
|