-
Notifications
You must be signed in to change notification settings - Fork 1
Release/0.1.6 #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Release/0.1.6 #29
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| node_modules/ | ||
| .env*.local | ||
|
|
||
| # Scan output — regenerated by `deepsec scan` / `process`. INFO.md | ||
| # and SETUP.md (manually edited) stay tracked. | ||
| data/*/files/ | ||
| data/*/runs/ | ||
| data/*/reports/ | ||
| data/*/project.json |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # Agent setup | ||
|
|
||
| This is a deepsec scanning workspace. Each registered project has its | ||
| own setup prompt at `data/<id>/SETUP.md` — open the relevant one when | ||
| asked to set a project up. | ||
|
|
||
| ## Common tasks | ||
|
|
||
| - **Set up a project for scanning**: read `data/<id>/SETUP.md` and | ||
| follow it (read `node_modules/deepsec/SKILL.md`, then fill | ||
| `data/<id>/INFO.md` from the target codebase). | ||
| - **Add a new project**: run `deepsec init-project <root>` — it | ||
| scaffolds `data/<id>/` and prints/writes the setup prompt for the | ||
| new project. | ||
| - **Write a custom matcher** (only after a real true-positive shows you | ||
| a pattern worth keeping): read | ||
| `node_modules/deepsec/dist/docs/writing-matchers.md`. | ||
|
|
||
| ## Reference | ||
|
|
||
| The deepsec skill is at `node_modules/deepsec/SKILL.md` (after | ||
| `pnpm install`). The full docs ship at | ||
| `node_modules/deepsec/dist/docs/`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| # deepsec | ||
|
|
||
| This directory holds the [deepsec](https://www.npmjs.com/package/deepsec) | ||
| config for the parent repo. Checked into git so teammates inherit | ||
| project context (auth shape, threat model, custom matchers); generated | ||
| scan output is gitignored. | ||
|
|
||
| Currently configured project: `sdk-react-native` (target: `..`). | ||
|
|
||
| ## Setup | ||
|
|
||
| 1. `pnpm install` — installs deepsec. | ||
| 2. Add an AI Gateway / Anthropic / OpenAI token to `.env.local`. If | ||
| you already have `claude` or `codex` CLI logged in on this | ||
| machine, you can skip the token for non-sandbox runs (`process` / | ||
| `revalidate` / `triage`); deepsec auto-detects and reuses the | ||
| subscription. See | ||
| `node_modules/deepsec/dist/docs/vercel-setup.md` after install. | ||
| 3. Open the parent repo in your coding agent (Claude Code, Cursor, …) | ||
| and have it follow `data/sdk-react-native/SETUP.md` to fill in | ||
| `data/sdk-react-native/INFO.md`. | ||
|
|
||
| ## Daily commands | ||
|
|
||
| ```bash | ||
| pnpm deepsec scan | ||
| pnpm deepsec process --concurrency 5 | ||
| pnpm deepsec revalidate --concurrency 5 # cuts FP rate | ||
| pnpm deepsec export --format md-dir --out ./findings | ||
| ``` | ||
|
|
||
| `--project-id` is auto-resolved while there's only one project in | ||
| `deepsec.config.ts`. Once you've added a second project, pass | ||
| `--project-id sdk-react-native` (or whichever id you want) explicitly. | ||
|
|
||
| `scan` is free (regex only). `process` is the AI stage (≈$0.30/file | ||
| on Opus by default). Run state goes to `data/sdk-react-native/`. | ||
|
|
||
| ## Adding another project | ||
|
|
||
| To scan another codebase from this same `.deepsec/`: | ||
|
|
||
| ```bash | ||
| pnpm deepsec init-project ../some-other-package # path relative to .deepsec/ | ||
| ``` | ||
|
|
||
| Appends an entry to `deepsec.config.ts` and writes | ||
| `data/<id>/{INFO.md,SETUP.md,project.json}`. Open the new SETUP.md | ||
| in your agent to fill in INFO.md. | ||
|
|
||
| ## Layout | ||
|
|
||
| ``` | ||
| deepsec.config.ts Project list (one entry per scanned repo) | ||
| data/sdk-react-native/ | ||
| INFO.md Repo context — checked into git, hand-curated | ||
| SETUP.md Agent setup prompt — checked in, deletable | ||
| project.json Generated (gitignored) | ||
| files/ One JSON per scanned source file (gitignored) | ||
| runs/ Run metadata (gitignored) | ||
| reports/ Generated markdown reports (gitignored) | ||
| AGENTS.md Pointer for coding agents | ||
| .env.local Tokens (gitignored) | ||
| ``` | ||
|
|
||
| ## Docs | ||
|
|
||
| After `pnpm install`: | ||
|
|
||
| - Skill: `node_modules/deepsec/SKILL.md` | ||
| - Full docs: `node_modules/deepsec/dist/docs/{getting-started,configuration,models,writing-matchers,plugins,architecture,data-layout,vercel-setup,faq}.md` | ||
|
|
||
| Or browse on | ||
| [GitHub](https://github.com/vercel/deepsec/tree/main/docs). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # sdk-react-native | ||
|
|
||
| ## What this codebase does | ||
|
|
||
| `@formo/analytics-react-native` — a client-side analytics SDK (npm | ||
| library) embedded into third-party React Native dApps. It tracks wallet | ||
| events (connect / disconnect / signature / transaction / chain), screen | ||
| views, and custom events, batches them in `EventQueue`, and POSTs them | ||
| to `https://events.formo.so/v0/raw_events`. Optional Wagmi integration | ||
| (`WagmiEventHandler`) auto-captures wallet activity. There is **no | ||
| server component** in this repo — it is shipped code that runs inside | ||
| other people's apps. Classic web vulns (SQLi, SSRF, server authz) mostly | ||
| do not apply; data-handling and supply-chain concerns dominate. | ||
|
|
||
| ## Auth shape | ||
|
|
||
| There is no user/session auth. The only credential is the **`writeKey`** | ||
| — a *public, write-only* ingest key intentionally bundled into client | ||
| apps and sent as `Authorization: Bearer ${writeKey}` via | ||
| `EVENTS_API_REQUEST_HEADER` (`constants/config.ts`). Treat it as | ||
| non-secret. The relevant gates instead are: | ||
|
|
||
| - `hasOptedOutTracking()` / `CONSENT_OPT_OUT_KEY` + `setConsentFlag` / | ||
| `getConsentFlag` / `removeConsentFlag` (`lib/consent`). | ||
| - `isBlockedAddress` / `BLOCKED_ADDRESSES` (`utils/address.ts`). | ||
| - `validateAddress` (EVM checksum + Solana) before an address is | ||
| attached to any event. | ||
|
|
||
| ## Threat model | ||
|
|
||
| Highest impact: (1) PII / sensitive-data exfiltration — the SDK collects | ||
| wallet addresses, the **raw message text being signed**, device info, | ||
| deep-link URLs, and UTM/referrer attribution; anything that logs, | ||
| persists, or ships a private key or full signature secret is critical. | ||
| (2) Consent bypass — events generated or flushed after the user opted | ||
| out. (3) Supply-chain / untrusted input — host-app-supplied event | ||
| `properties` and deep-link URLs flow into the outbound payload. | ||
|
|
||
| ## Project-specific patterns to flag | ||
|
|
||
| - **Signature capture leaking secrets.** `signature()` / | ||
| `createSignatureEvent` (`EventFactory`) and `WagmiEventHandler` | ||
| mutation tracking store `message` + optional `signatureHash` only. | ||
| Flag any path that captures a private key, mnemonic, or the produced | ||
| signature itself beyond `signatureHash`. | ||
| - **Consent-gate bypass.** Every new event entry point must check | ||
| opt-out before `eventQueue.enqueue`, and opt-out must call | ||
| `eventQueue.clear()`. Flag new track paths that skip the consent | ||
| check. | ||
| - **Unvalidated address pass-through.** Addresses attached to events | ||
| must go through `validateAddress` / `isBlockedAddress`; flag raw | ||
| user/wallet address used directly in a payload. | ||
| - **Untrusted properties / deep-link URLs** merged into event payloads | ||
| (`parseTrafficSource`, `startDeepLinkCapture`, custom `track` | ||
| properties) without sanitization — prototype-pollution or oversized | ||
| payload risk. | ||
|
|
||
| ## Known false-positives | ||
|
|
||
| - `writeKey` in the `Bearer` header / bundled in client config — public | ||
| write-only key by design, **not** a leaked secret. | ||
| - `options.apiHost` overriding the ingest endpoint — intended | ||
| self-host/proxy support; not SSRF (runs in the host app's own | ||
| process, configured by that app's developer). | ||
| - `generateUUID()` using `Math.random()` (`utils/hash.ts`) — analytics | ||
| dedup/anon IDs, not security tokens. Acceptable. | ||
| - **Minute-rounded `message_id` deduplication** (`generateMessageId` → | ||
| `toDateHourMinute`, `lib/event/EventQueue.ts`) — intentional and | ||
| **by design**. This is the *canonical cross-SDK + backend dedup | ||
| contract* shared with `@formo/analytics` (web) and the | ||
| `events.formo.so` ingest pipeline; content-identical events colliding | ||
| within the same wall-clock minute is expected behavior, not a bug. Do | ||
| **not** flag or "fix" this — including the BUG finding | ||
| `other-deduplication-data-loss`. The `message_id` contract may only | ||
| change via coordinated web-SDK + backend + RN sign-off, never as an | ||
| SDK-local patch. | ||
| - Unencrypted `AsyncStorage` / `MemoryStorage` fallback — only stores | ||
| anon id + consent flag, non-sensitive by design. | ||
| - Hardcoded `SOLANA_SYSTEM_ADDRESSES` / `BLOCKED_ADDRESSES` — public | ||
| constants, not secrets. | ||
| - Anything under `src/__tests__/` — fixtures and mocks. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| # Agent setup for `sdk-react-native` | ||
|
|
||
| This is a deepsec scanning workspace. Project `sdk-react-native` was just registered | ||
| (target: `..`). Setup is incomplete — `data/sdk-react-native/INFO.md` | ||
| still has placeholder sections. | ||
|
|
||
| ## What to do | ||
|
|
||
| 1. **Read the deepsec skill.** After `pnpm install`, the file is at | ||
| `node_modules/deepsec/SKILL.md`. It maps every doc topic to a file | ||
| under `node_modules/deepsec/dist/docs/`. Read `getting-started.md`, | ||
| `configuration.md`, and `writing-matchers.md` (skim the rest). | ||
|
|
||
| 2. **Fill in `data/sdk-react-native/INFO.md`.** It's auto-injected into the AI | ||
| prompt for every batch — keep it short and selective. | ||
|
|
||
| **Length budget: 50–100 lines total.** Verbose context dilutes | ||
| signal in the scanner's prompt window. The goal is "what would a | ||
| reviewer miss if they didn't read this?", not exhaustive enumeration. | ||
|
|
||
| **Per-section rubric**: | ||
| - Pick 3–5 representative items per section. **Don't list every | ||
| file, helper, or callsite** — pick the patterns. | ||
| - Name primitives by their public name (e.g. `withAuthentication`, | ||
| `auth.can()`, `isTeamAdmin`). **No line numbers.** Don't enumerate | ||
| more than 5 paths in any list. | ||
| - Skip generic CWE categories — built-in matchers already cover | ||
| "SSRF", "SQL injection", "XSS". Cover what's *project-specific*: | ||
| internal auth helpers, custom middleware names, fork-specific | ||
| stubs, intended-public endpoints. | ||
| - One short paragraph or 3–5 short bullets per section. Not both. | ||
|
|
||
| Source material (read in this order, stop when you have enough): | ||
| - `../README.md` | ||
| - any `AGENTS.md` / `CLAUDE.md` in `..` | ||
| - `../package.json` (or `go.mod`, `pyproject.toml`, etc.) | ||
| - 5–10 representative code files (entry points, auth helpers) — not | ||
| a full code tour. | ||
|
|
||
| 3. **(Optional) Add custom matchers** for repo-specific patterns the | ||
| built-in matchers won't catch. Read | ||
| `node_modules/deepsec/dist/docs/writing-matchers.md` first; the | ||
| workflow there starts from a confirmed finding and grows the matcher | ||
| from it. Don't add matchers speculatively — wait for a real TP. | ||
|
|
||
| ## When you're done | ||
|
|
||
| The user will run: | ||
|
|
||
| ```bash | ||
| pnpm deepsec scan --project-id sdk-react-native | ||
| pnpm deepsec process --project-id sdk-react-native | ||
| ``` | ||
|
|
||
| You can delete this file once setup is complete. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "tags": [ | ||
| "github-actions", | ||
| "node", | ||
| "react" | ||
| ], | ||
| "sentinels": [ | ||
| "package.json" | ||
| ], | ||
| "detectedAt": "2026-05-16T23:06:59.117Z", | ||
| "rootPath": "/Users/yos/sdk-react-native" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import { defineConfig } from "deepsec/config"; | ||
|
|
||
| export default defineConfig({ | ||
| projects: [ | ||
| { id: "sdk-react-native", root: ".." }, | ||
| // <deepsec:projects-insert-above> | ||
| ], | ||
| }); |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,12 @@ | ||||||
| { | ||||||
| "name": "deepsec-workspace", | ||||||
| "version": "0.1.0", | ||||||
| "private": true, | ||||||
| "description": "deepsec scanning workspace", | ||||||
| "type": "module", | ||||||
| "workspaces": [], | ||||||
| "packageManager": "pnpm@9.15.4", | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The packageManager version specified here (pnpm@9.15.4) is inconsistent with the version used in the root package.json (pnpm@10.27.0). It is recommended to keep these versions synchronized to ensure consistent dependency resolution and lockfile behavior across the entire repository. Before applying this change, verify that pnpm@10.27.0 is available on the official registry (e.g., npm view pnpm@10.27.0).
Suggested change
References
|
||||||
| "dependencies": { | ||||||
| "deepsec": "^2.0.8" | ||||||
| } | ||||||
| } | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rootPath property contains an absolute path specific to a local environment (/Users/yos/...). This makes the configuration non-portable and leaks local system information. If this file is intended to be tracked in git, this path should be made relative (e.g., ".."). However, given that it also contains a detectedAt timestamp, this file appears to be a generated cache that should likely be added to .deepsec/.gitignore and removed from the repository.