Skip to main content

security-audit-api-2fa

Checks 2FA enforcement across GraphQL V2 mutations. Use for coverage gaps or on-demand checks.

معلومات المصدر

المستودع
opencollective/monorepo
آخر نشاط في المصدر
١ أكتوبر ٢٠٢٦ في ٠٥:٤٨
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٣
التفرعات
٣

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
2 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
security-audit-api-2fa
description
Checks 2FA enforcement across GraphQL V2 mutations. Use for coverage gaps or on-demand checks.
# API GraphQL V2 2FA completeness hunter Deterministic completeness check of **two-factor enforcement** on every GraphQL V2 mutation in `opencollective-api`. For engineers running on-demand checks. This hunter **records and classifies**. The enumerator does not decide Bug vs hardening. ## Enumerator From the workspace root: ```bash node .agents/skills/security-audit/scripts/enumerate-2fa-coverage.cjs --root opencollective-api --out /tmp/opencode/v2-2fa.json ``` `--root` defaults to `OC_API_ROOT`, then `./opencollective-api`, then `/workspace/opencollective-api`. Also run `enumerate-v2-mutations.cjs` when you need the raw mutation list. Smoke test (no extra deps): ```bash node --test .agents/skills/security-audit/scripts/enumerators.test.cjs ``` ## Load known-safe patterns Read `.agents/skills/review-feature-security/SKILL.md` when that skill is present. Otherwise use `AGENTS.md` Security: public GraphQL introspection and permissive API CORS are not defects. OWASP framing: Multifactor Authentication. This skill's outputs (classification, optional findings.json, Bug) are the source of truth, not the cheat sheet. ## Classify every mutation For each row in the enumerator JSON, trace `file` + `line` + `twoFactor.callees` (1-2 hops into `server/graphql/common/*`). Assign **one** class: | Class | When | Verdict | | --- | --- | --- | | **public/guest N/A** | Unauthenticated or guest-only (example: `confirmGuestAccount`) | Not a 2FA finding | | **read-only N/A** | No durable write, payout, token, or admin policy change | Not a 2FA finding | | **admin write / REQUIRE_2FA_FOR_ADMINS** | Admin (or host-admin) mutation that changes money, payout methods, vendors, legal docs, hosting, or equivalent. Must follow host policy `REQUIRE_2FA_FOR_ADMINS` via `twoFactorAuthLib.enforceForAccount` or `enforceForAccountsUserIsAdminOf` (which call `validateRequest` when the policy or user 2FA is on) | Missing call with a real threat model is **confirmed** | | **user-has-2FA-enabled** | Path that should prompt when the acting user already has 2FA enrolled (`validateRequest` / `enforceForAccount` without waiting only for host policy) | Missing call is confirmed only with a real threat model | | **intentional onlyAskOnLogin / preAuthorize2FA** | `onlyAskOnLogin: true` or `TWO_FACTOR_SESSIONS_PARAMS` / `preAuthorize2FA` is an explicit product choice (login-time or pre-authorized token) | Hardening at most, not a Bug, unless the option skips a required payout/admin gate | `twoFactor.sessionParams` means the script saw `TWO_FACTOR_SESSIONS_PARAMS` and/or `preAuthorize2FA`. `onlyAskOnLogin` is login-time 2FA, not a fresh prompt for the mutation. ## What is confirmed **Confirmed** = missing 2FA call on an admin-write mutation with a **real threat model**, in the class of `editVendor` payout 2FA bypass ([opencollective-security #200](https://github.com/opencollective/opencollective-security/issues/200)). Unambiguous missing call: confirm from **source trace + threat model**. Mocha PoC when cheap (phase 2). Do not file from enumerator flags alone. **Not a Bug:** defense-in-depth extra prompts after login (for example `onlyAskOnLogin` on tier edits). That is hardening. ## Fingerprint `oc:api:2fa:graphql.v2.mutation.<name>[.<subpath>]` Examples: `oc:api:2fa:graphql.v2.mutation.editVendor`, `oc:api:2fa:graphql.v2.mutation.editVendor.payoutMethod`. Stable across runs. No line numbers, waves, or severity in the fingerprint. ## Dedup and filing 1. Search `opencollective-security/harness/index.json` (when present). 2. Search GitHub `opencollective/opencollective-security` issues (open and closed). 3. Grep `reports/` and `internal/` in the security repo checkout for the same fingerprint. 4. Upsert hunt fields (must not rewrite `reports[]`): ```bash node .agents/skills/security-audit/scripts/patch-index.cjs --mode hunt \ --index opencollective-security/harness/index.json \ --fingerprint 'oc:api:2fa:graphql.v2.mutation.editVendor' \ --verdict confirmed --repo opencollective-api \ --path server/graphql/v2/mutation/VendorMutations.ts --issue 200 ``` 5. File a Bug **only if confirmed and not a duplicate**. Label `source > harness`. ## Artifacts Write under `opencollective-security/harness/api/runs/<YYYY-MM-DD>-<n>/` (and local gitignored `priv/security-audit/` when the security repo is not checked out). Do not patch product code from this hunter. If you produce `findings.json`, validate it: ```bash node .agents/skills/security-audit/validate-findings.cjs path/to/findings.json ``` ## Enumerator limitations Heuristic/regex parser (`lib-scan.cjs`): not TypeScript. Spread fields are not expanded. Runtime field factories are not executed. 2FA hops follow same-file helpers and `server/graphql/common/*` only (not `server/lib/*` except through those hops). If a mutation is missing from JSON, say so; do not invent GraphQL fields. ## Sub-agents Run via sub-agent `security/2fa` (this skill) plus `security/verifier` on every candidate. Hunters must not edit product source.
عرض على GitHub