detect-data-leaks
Skill627 starsChanged 8 days agoMITView on GitHub
Detect new PII leaks introduced by the current branch. Use when asked to check for potential data leaks for the current changes.
In this repository70 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- analyticsSkill
- batch-feature-devSkill
- ci-runnersSkill
- ci-workflow-refsSkill
- cleanupSkill
- client-idsSkill
- cloud-sync-moduleSkill
- codeownershipSkill
- coin-families-contractSkill
- coin-modulesSkill
- commentsSkill
- configurationSkill
- console-logSkill
- create-changesetSkill
- create-prSkill
- data-layer-advancedSkill
- debug-rn-native-crashSkill
- dependency-patchesSkill
- device-intent-executorSkill
- devtools-import-boundarySkill
- dialogs-sliceSkill
- docs-migrateSkill
- docs-update-or-createSkill
- domain-dataSkill
- e2e-desktop-add-or-updateSkill
- e2e-desktop-onboardSkill
- e2e-earnSkill
- e2e-mobile-add-or-updateSkill
- e2e-mobile-onboardSkill
- e2e-swapSkill
- errorsSkill
- feature-devSkill
- fix-ciSkill
- flow-packageSkill
- get-pr-commentsSkill
- git-conventionsSkill
- i18n-keysSkill
- impacting-prsSkill
- knip-migrationSkill
- ldls-nativeSkill
- ldls-webSkill
- ledger-wallet-cliSkill
- legacy-migrationSkill
- mvvm-architectureSkill
- new-packageSkill
- package-public-apiSkill
- pnpm-resolutionSkill
- prefer-set-hasSkill
- pre-reviewSkill
- react-generalSkill
- rebuild-to-fix-lib-import-errorsSkill
- remove-feature-flagSkill
- run-buildsSkill
- run-e2e-ciSkill
- runner-imagesSkill
- run-testsSkill
- slack-pr-messageSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 9 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 10
Every third-party service should be considered, but each has a different risk level.
- Distinctive: line 38
Treat any of these as high-risk when found in added lines:
- Distinctive: line 44
Run git diff develop...HEAD.
- Distinctive: line 55
Check if it flows into a sink call within the diff
- Distinctive: line 56
If it may pass through intermediate calls, read the affected file to follow the chain
- Distinctive: line 59
Read surrounding context in the file
- Distinctive: line 60
Follow the call chain to determine what gets serialized
- Very specific: line 61
If the call is a wrapper (e.g.
- Distinctive: line 63
Use the grep commands below only to trace a pattern already found in the diff.
- Distinctive: line 125
If no findings reach score 7, produce no output.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Scope — what is PII, what is NOT
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:
- Kaspa →
api.kaspa.org - EVM (Ethereum, BSC, Polygon…) → Etherscan-family
- Tron → TronGrid (
api.trongrid.io)
Known third-party sinks in this repo
Prioritize these, but do not exclude others:
- Datadog
- Sentry
- Mixpanel
Analytics also leave from the monorepo layers (shared/, domain/, features/, devtools/), not only the apps:
@shared/analyticsownstrack()andtrackPage();@shared/analytics-reactwraps them in<Track>and<TrackScreen>(universal, web and native). The apps plug their vendor (setAnalytics) and filters into this pipeline, so a layer call reaches the same vendor as an app call.- Feature packages send events either through those functions (
@features/flow-fear-and-greed, and@features/platform-pay-analytics, which buildscreatePayAnalyticsHelperon@shared/analytics'strack) or through an adapter the app injects (createContactsAnalyticsHelperin@features/flow-contacts). For an injected adapter, read the app side that builds it: that is where the payload reaches the vendor. @features/platform-coin-observabilitydecides when coin errors reach Datadog.
High-risk variables
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
Process
- Run
git diff develop...HEAD. This is the primary source — start here, not from grep. - In added lines, identify:
- Assignments of high-risk variables (see above)
- New calls to third-party sinks or wrappers:
track(),trackPage(),<Track>,<TrackScreen>, analytics adapter methods (adapter.track(),analytics.trackPage(),track*()helpers),logger.*(),captureException() - Added lines under
shared/,domain/,features/anddevtools/count as much as added lines underapps/
- In removed lines, identify:
- Removed guards:
confidentialityFilter, scrubbing calls, PII-stripping wrappers — flag each removal as a potential leak enabler.
- Removed guards:
- For each high-risk variable in added lines, trace its lineage:
- Check if it flows into a sink call within the diff
- If it may pass through intermediate calls, read the affected file to follow the chain
- For each new sink call in the diff:
- Read surrounding context in the file
- Follow the call chain to determine what gets serialized
- If the call is a wrapper (e.g.
track()), read its implementation — do not assume from the name
- Use the grep commands below only to trace a pattern already found in the diff. Never run them independently to source findings.
- Score each finding 1–10. Report only those scoring 7 or higher with a concrete fix.
Grep helpers (investigation only)
SRC covers the apps and the layers that ship runtime code; support/ holds development-only presets and never sends data.
SRC=(apps shared domain features devtools)Analytics call sites in the layers:
grep -rnE "\btrack(Page)?\(|<Track(Screen)?\b" shared domain features devtools --include="*.ts" --include="*.tsx" \
| grep -vE "\.test\.|/__tests__/|/node_modules/"location.pathname flowing into track() — pathname often assigned before the call:
find "${SRC[@]}" -path "*/node_modules" -prune -o \( -name "*.ts" -o -name "*.tsx" \) -print | 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:
grep -rn "window\.location\.hash" "${SRC[@]}" --exclude-dir=node_modules --include="*.ts" --include="*.tsx"Address interpolated into new Error(...) in coin modules:
find 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:
grep -rn -E "broadcast_failure|broadcastLogger" "${SRC[@]}" --exclude-dir=node_modules --include="*.ts" | grep -v "\.test\."Full transaction object spread into analytics:
grep -rn -E "value:[[:space:]]*(params|transaction)\b" "${SRC[@]}" --exclude-dir=node_modules --include="*.ts" --include="*.tsx" \
| grep -v "\.test\." \
| grep -vE "value:[[:space:]]*(params|transaction)\."Signed payload fields in track():
grep -rn -E "binaryPayload|payinAddress|fromAccountAddress|toAccountAddress" libs "${SRC[@]}" --exclude-dir=node_modules --include="*.ts" --include="*.tsx" \
| grep -vE "\.test\.|/__tests__/|/tests/"Props filter registration (the shared pipeline applies it to both track() and trackPage()):
grep -rn "setPropsFilter(" apps/ --include="*.ts" --include="*.tsx" | grep -v testsetPropsFilter lives in @shared/analytics; only an app registers one. Desktop registers confidentialityFilter, so a layer call site rendered on mobile is unfiltered. Check whether any other app that sends analytics needs a filter.
Output format
- Score mapping: 9-10 → 🔴 Critical, 7–8 → 🟡 Suggestion. Scores below 7 are not reported.
- If no findings reach score 7, produce no output.
🔴 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.References
.agents/skills/client-ids/SKILL.md
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

