Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Detect new PII leaks introduced by the current branch. Use when asked to check for potential data leaks for the current changes.
.claude/skills/ledgerhq-detect-data-leaks/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-15 | ✗→✓ | ▲ Improved | 69% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 23% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 64% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 30% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 40% | 0% |
We only consider PII that is sent to third-party services. Any call to our own backend with PII is not considered a data leak.
Every third-party service should be considered, but each has a different risk level. Logging services are the highest risk.
Some information is only PII in context — for example, public addresses are not PII by themselves, but on a logging service such as Datadog, an address can be linked to a location and device, allowing identification of the person behind it.
Crash reports need to be studied alongside logs — they are a common source of data leaks.
Any service that queries the blockchain for an address is not a concern — the query is mandatory for the system to function and the data is not linked to any other identifiable information. This applies to all coin modules. Examples:
api.kaspa.orgapi.trongrid.io)Prioritize these, but do not exclude others:
Treat any of these as high-risk when found in added lines:
location.pathname, window.location.hash, address, walletAccountId, txId, publicKey, signature, rawData, payinAddress, fromAccountAddress, toAccountAddress, binaryPayload
git diff develop...HEAD. This is the primary source — start here, not from grep.track(), trackPage(), logger.*(), captureException()confidentialityFilter, scrubbing calls, PII-stripping wrappers — flag each removal as a potential leak enabler.track()), read its implementation — do not assume from the namelocation.pathname flowing into track() — pathname often assigned before the call:
bashfind apps \( -name "*.ts" -o -name "*.tsx" \) | grep -vE "\.test\.|/__tests__/|/tests/" | \ xargs perl -0777 -ne 'BEGIN { exit unless @ARGV } print "$ARGV\n" if /track(?:Page)?\([\s\S]{0,500}?location\.pathname/'
window.location.hash in analytics:
bashgrep -rn "window\.location\.hash" apps/ --include="*.ts" --include="*.tsx"
Address interpolated into new Error(...) in coin modules:
bashfind libs \( -name "*.ts" -o -name "*.tsx" \) | grep -vE "live-e2e-shared|coin-tester-modules|__tests__|tests|\.test\." | \ xargs perl -0777 -ne 'BEGIN { exit unless @ARGV } print "$ARGV\n" if /new Error\(`[\s\S]{0,300}?\$\{[^}]*(address|sender|hash|walletAccountId|txId|publicKey)[^}]*\}/i'
Signed tx payload on broadcast failure:
bashgrep -rn -E "broadcast_failure|broadcastLogger" apps/ --include="*.ts" | grep -v "\.test\."
Full transaction object spread into analytics:
bashgrep -rn -E "value:[[:space:]]*(params|transaction)\b" apps/ --include="*.ts" --include="*.tsx" \ | grep -v "\.test\." \ | grep -vE "value:[[:space:]]*(params|transaction)\."
Signed payload fields in track():
bashgrep -rn -E "binaryPayload|payinAddress|fromAccountAddress|toAccountAddress" libs/ apps/ --include="*.ts" --include="*.tsx" \ | grep -vE "\.test\.|/__tests__/|/tests/"
confidentialityFilter coverage on trackPage():
bashfind apps/ledger-live-desktop apps/ledger-live-mobile -name "segment.ts" -path "*/analytics/*" | \ xargs -I{} grep -n -E "confidentialityFilter|trackPage" {}
🔴 Critical (10/10) — apps/.../useActivityIndicator.ts:39
track("SyncErrorList", { page: location.pathname, ... });
Fix: remove `page` from the payload or replace with a static route label stripped of account IDs.
🟡 Suggestion (8/10) — apps/.../someFile.ts:12
track("Event", { hash: window.location.hash });
Fix: pass only the route segment before the `#`, not the full hash..agents/skills/client-ids/SKILL.md
Other measured skills in the registry, with their headline benchmark lift.