Skip to content

perf!: Add security-audit skill with vulnerability hunting workflow - #897

Merged
aXenDeveloper merged 1 commit into
canaryfrom
claude/security-audit-skill
Oct 23, 2026
Merged

aXenDeveloper merged 1 commit into
canaryfrom
claude/security-audit-skill

Conversation

@aXenDeveloper

Copy link
Copy Markdown
Owner

Description

What?

Added a comprehensive security audit skill that implements a six-phase vulnerability hunting and validation workflow for codebases. This includes:

  • Core validators (validate-coverage-ledger.cjs, validate-findings.cjs): Dependency-free JSON validators with strict input limits and safety checks for coverage ledger and findings data
  • Workflow documentation: Six markdown files defining phases from reconnaissance through reporting:
    • RECONNAISSANCE.md: Phase 1 - Map source and plan coverage
    • HUNTING.md: Phase 2 - Run coverage-led hunting waves
    • VALIDATION-AND-REPORTING.md: Phase 3 - Validate candidates and generate reports
    • SKILL.md: Main skill definition with operating modes and platform terminology
    • ATTACK-CLASSES.md: Attack class taxonomy and selection guidance
  • Domain-specific hunting guides: Specialized guidance for different target types:
    • WEB-PROTOCOL-AND-AUTH.md: HTTP and authentication boundaries
    • MEMORY-SAFETY-AND-BINARY.md: Memory safety and kernel targets
    • DESKTOP-MOBILE-AND-LOCAL-IPC.md: Desktop/mobile and local IPC
    • CLOUD-AND-DEPLOYMENT.md: Cloud infrastructure and deployment
    • DATA-ISOLATION-AND-LIFECYCLE.md: Data isolation and lifecycle
    • AI-AND-LLM.md: AI/LLM-specific security concerns
    • CLIENT-SIDE.md: Browser and client-side security
    • PROTOCOLS-RPC-AND-MESSAGING.md: Protocol and messaging security
    • RESOURCE-EXHAUSTION-AND-AVAILABILITY.md: Availability and DoS
    • SUPPLY-CHAIN-AND-RELEASE.md: Supply chain and release security
  • JSON Schema: report-schema.json defining the contract for findings with three verdict branches (confirmed, needs_validation, rejected)
  • Comprehensive test suites: Full test coverage for both validators with edge cases, security checks, and CLI integration tests

Why?

This skill enables systematic, source-grounded vulnerability discovery with clear workflows for hunting, validation, and reporting. It provides:

  1. Structured methodology: Six-phase workflow from reconnaissance through final reporting
  2. Safety and limits: Validators enforce strict input bounds to prevent DoS and resource exhaustion
  3. Domain expertise: Specialized hunting guides for different application types and trust boundaries
  4. Reproducibility: Canonical coverage IDs and fingerprints ensure deterministic, traceable results
  5. Verification: Independent validation phase ensures findings are grounded in source evidence
  6. Guidance modes: Supports both focused security reviews and complete audit workflows

The validators use conservative resource limits, safe character handling, and comprehensive error reporting to handle untrusted input safely.

Test Plan

Comprehensive test suites included:

  • validate-coverage-ledger.test.cjs: 740 lines covering structural validation, cardinality limits, field validation, CLI integration, and security edge cases
  • validate-findings.test.cjs: 652 lines covering schema validation, verdict branches, unique constraints, and control character injection prevention

Both test suites verify the validators work correctly through the CLI with proper error handling and output safety.

https://claude.ai/code/session_01MVPfoMoYoGyjbGaoFxKfC2

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-23T17:54:57.143802Z 8a36388 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@aXenDeveloper aXenDeveloper changed the title Add security-audit skill with vulnerability hunting workflow perf!: Add security-audit skill with vulnerability hunting workflow Oct 22, 2026
@github-actions github-actions Bot added 🚀 Performerce Improves performance 🚨 Breaking Changes Modification that will require you to update your application labels Oct 22, 2026
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

React Doctor found no new issues. 🎉

Reviewed by React Doctor for commit 8a36388.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 47cd23425d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +103 to +105
publishedCondition(
publicationColumns(parent.target, parentColumns),
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Enforce visibility through the full parent chain

When relation-context content types are chained (for example, a reply belongs to a published topic that itself belongs to a hidden forum), this query verifies only the immediate parent's publication columns. Because it never applies that parent's own contentParentRelation, the reply remains publicly readable even though its topic is no longer publicly reachable. Resolve visibility recursively, or otherwise include all ancestor predicates, rather than treating an immediately published row as sufficient.

Useful? React with 👍 / 👎.

[
...contentRecordPageCacheTags(definition, recordIdOf(payload)),
...contentListPageCacheTags(definition),
...dependents.flatMap(dependent => contentListPageCacheTags(dependent)),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Invalidate cached child detail pages

When a parent is hidden or unpublished after a child detail page has been cached, this invalidates only the dependent type's list tag. The detail route tags a normal child response with its item tag via contentRecordPageCacheTags (public-routes.ts around line 661), so that cached HTML does not match this invalidation; bumping the API generation also does not invalidate the HTML page cache. Consequently, the cached child detail can continue exposing content whose parent now makes it return 404 on a fresh render. Tag child detail reads with their parent or invalidate a type-wide tag shared by dependent item pages.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59dc2eaf38

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

)?.model;
const parentColumns = model?.columns as Record<string, PgColumn> | undefined;
const parentId = parentColumns?.id;
if (!reference || !model || !parentColumns || !parentId) return null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fail closed when the parent model is unavailable

When a child relation's target definition remains importable but its model is not registered—for example, the target plugin is removed while a dependent plugin remains—this branch returns null, which disables parent filtering entirely. The child detail and list APIs then expose rows whose parent cannot be resolved through the installed public API; the thread route already treats the same missing root model as a 404. Treat an unresolved model/column set as unavailable content or reject this configuration at boot rather than falling back to unrestricted reads.

Useful? React with 👍 / 👎.

- Admin user edits: a non-root admin can no longer edit (reset password,
  change email, demote) a staff account holding access they lack; root and
  unrestricted accounts are editable by root only.
- Role deletion applies the staff-entry guards (protected, own entry,
  privilege ceiling) to the staff entries it would cascade away.
- Admin email change and admin password set revoke pending password-reset
  and email-verification tokens.
- SSO: `SSOProviderUser.emailVerified` makes provider verification explicit;
  core refuses an unconfirmed address instead of creating, linking or
  verifying an account with it. Built-in adapters consistently report it.
- Public content reads (list, detail, by ids) drop child records whose
  parent (thread root or relation search context) is not public, and the
  parent's writes expire the children's cached reads.
- Scheduled-publish effects skip a stale snapshot when the record was
  deleted, edited or changed visibility since, so retries cannot put
  withdrawn content back into search.
- Rich text: mark/node lookups use own-property checks, so stored types
  like "constructor" cannot become a React element type.
- SSR server fetcher never derives the API origin from the request Host.
- AI streams: text already sent before a cancel or failure is charged to
  the user's points and daily count.
- WebSockets remember the authenticating device and are closed (on every
  instance) when their sessions are revoked.
- Give BlogPostAuthors an explicit ReactNode return type and provide
  core.personalInformationFields in the moderation test harnesses.
- Exclude vendored agent skills from oxfmt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 393d542882

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +577 to +579
const edges = (await list.hydrate(await keepVisible(data.edges))).map(
list.project,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Filter parent-hidden records before paginating

When a page contains children whose parents are hidden or unpublished, keepVisible removes those rows only after withPagination has already applied the limit and calculated counts and cursors. Consequently visible rows beyond the page limit are not backfilled, while pageInfo.count, totalCount, totalPages, and navigation cursors still describe the unfiltered records; the response can even report nonzero content while returning no edges. Apply the parent visibility predicate inside the paginated database query so both the page and its metadata use the same row set.

Useful? React with 👍 / 👎.

]);

await deleteSessionCacheKeys(c, { adminSessions, sessions });
realtime.closeUserConnections(scope.userId, scope.deviceId ?? null);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Close sockets on the normal sign-out path

This close notification runs only through revokeSessions, but DELETE /users/sign_out still calls SessionModel.deleteSession(), which deletes the current session directly and never reaches this hook. If the browser has an open socket when the user signs out, that socket therefore remains indexed as the authenticated user and can continue receiving private sendToUser or room messages until it disconnects independently. Route ordinary sign-out through the same revocation/close mechanism or explicitly close that device's sockets there.

Useful? React with 👍 / 👎.

@aXenDeveloper
aXenDeveloper force-pushed the claude/security-audit-skill branch from 393d542 to 8a36388 Compare October 23, 2026 17:51
@aXenDeveloper
aXenDeveloper merged commit f568d18 into canary Oct 23, 2026
5 checks passed
@aXenDeveloper
aXenDeveloper deleted the claude/security-audit-skill branch October 23, 2026 17:53

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8a36388477

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

SESSION_REVOKED_CLOSE_CODE,
SESSION_REVOKED_CLOSE_REASON,
);
publish({ data: deviceId, id: "closeUser", type: "closeUser", userId });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Make cross-instance session revocation durable

In a multi-instance deployment, a transient failure of the revoking instance's Redis publisher leaves every remote socket open: this call uses publish(), whose rejection is deliberately swallowed, while only the local registry is closed. A remote instance whose subscriber remains connected will not run the reconnect resync, so that socket can continue receiving private user or room messages after its session has been deleted. Revocation needs an acknowledged/retried delivery path or remote sockets must independently revalidate their sessions.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🚨 Breaking Changes Modification that will require you to update your application 🚀 Performerce Improves performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant