Skip to content

Fix logic-path audit defects (decode corrupted sources + correctness bugs) - #32

Open
canstralian wants to merge 3 commits into
mainfrom
claude/logic-path-audit-mXlrP
Open

canstralian wants to merge 3 commits into
mainfrom
claude/logic-path-audit-mXlrP

Conversation

@canstralian

@canstralian canstralian commented May 25, 2026 •

Copy link
Copy Markdown
Owner

Addresses the deterministic, unambiguous findings from the logic-path audit (issues #24–#31). Design-requiring work is intentionally left for follow-up (see bottom).

Root cause: base64-corrupted source files

Four files were stored base64-encoded on disk, so they are invalid as Python/shell/YAML — ruff check . and shellcheck would error on them in CI. Decoded to plaintext:

  • adapters/mcp/server.py
  • adapters/airtable/scope_mapper.py
  • import_vectors.sh
  • control-plane/registry/vectors.yaml

Fixes by issue

Verified locally

  • ruff check adapters vectors → all checks passed
  • bash -n import_vectors.sh + dry-run produces correct, runnable output
  • python3 -m py_compile on the decoded Python files

Intentionally deferred (need design, not just bug fixes)

Closes #27. Partially addresses #24, #25, #26, #29, #30, #31.


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added MCP tools for authorization scope checking and vector registry listing.
    • Enhanced scan endpoint with protocol handling and request validation.
    • Added database timestamp tracking for bug reports.
  • Bug Fixes

    • Improved error handling with explicit environment variable validation.
    • Better scan request input validation with detailed error feedback.
  • Refactor

    • Simplified state management hooks and internal module structure.
    • Clarified configuration scripts and registry formats.

Review Change Stack

…ipts

Decode base64-corrupted source files (mcp server, scope_mapper, import
script, vector registry) so they lint and run as intended, and fix
deterministic correctness bugs surfaced by the logic-path audit:

- import_vectors.sh: fix unexpanded $EXECUTE guard, wrong URL parameter
  expansion, missing error handling, malformed dry-run quoting; add
  set -euo pipefail and URL scheme validation
- scope_mapper: fix __main__ guard typo, source base/table from env
- storage/pipeline Flask apps: bind SQLAlchemy via db.init_app so models
  are usable; add report timestamp
- dashboard db: replace non-null assertion on DATABASE_URL with explicit check
- recon route: validate body with existing zod schema, guard URL parsing,
  wrap handler in try/catch
- hooks: drop unused zustand imports
- remove unused imports from nlp_processor

https://claude.ai/code/session_01XXDAcaDMRNh1s6fohSbkKq
@coderabbitai

coderabbitai Bot commented May 25, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

@canstralian, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 54 minutes and 29 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 15b92051-42ce-49d1-917b-260456b6611d

📥 Commits

Reviewing files that changed from the base of the PR and between f64f279 and d421a0e.

📒 Files selected for processing (2)
  • adapters/airtable/scope_mapper.py
  • import_vectors.sh
📝 Walkthrough

Walkthrough

The PR decodes previously obfuscated shell scripts and configuration files, fixing critical bugs in import_vectors.sh (#27). It establishes database infrastructure across three services with environment-driven configuration and validation. API endpoints gain request validation and error handling. Client-side state management is simplified to stubs.

Changes

Infrastructure Setup and Stabilization

Layer / File(s) Summary
Decoded Configuration and Shell Scripts with Fixes
adapters/airtable/scope_mapper.py, control-plane/registry/vectors.yaml, adapters/mcp/server.py, import_vectors.sh
Base64-encoded shell script and MCP server are decoded and rewritten. import_vectors.sh fixes critical variable expansion bugs (missing $EXECUTE reference, malformed URL pattern), adds set -euo pipefail and HTTPS validation, and properly implements conditional execution logic and dry-run output. vectors.yaml is decoded to readable YAML defining four vector entries. Airtable adapter cleans up unused json import.
Database Initialization and Validation
vectors/pipeline/app.py, vectors/storage/app.py, vectors/dashboard/db/index.ts
Flask apps bind SQLAlchemy instances with DATABASE_URL environment configuration (sqlite fallbacks). Dashboard database module validates DATABASE_URL at load time and throws if missing, replacing unsafe non-null assertions.
Domain Models and Import Cleanup
vectors/pipeline/models.py, vectors/pipeline/nlp_processor.py
BugReport model adds created_at timestamp column with datetime.utcnow default. NLP processor stub removes unused imports.
API Request Validation and Error Handling
vectors/dashboard/server/routes/recon.ts
/scan endpoint validates request body via Zod, returning HTTP 400 with flattened errors on failure. performRecon adds protocol-fallback URL parsing (tries direct parse, falls back to https://). Route wraps execution in try/catch, returning HTTP 500 with error message on exceptions.
Client Hook Simplification
vectors/dashboard/client/src/hooks/use-programs.ts, vectors/dashboard/client/src/hooks/use-toast.ts, vectors/dashboard/client/src/hooks/use-user.ts
Zustand imports removed; hooks replaced with static stub implementations returning default empty states (programs: [], user: null, no-op toast function).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

A rabbit hops through tangled code,
Decoding what was long concealed—
Scripts once twisted now made whole,
With databases and validation sealed.
From chaos springs a cleaner path,
One layer at a time, the pieces heal.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive The PR includes additional fixes beyond issue #27 (database validation, SQLAlchemy binding, BugReport timestamp, hook cleanup). These appear intentional per PR description as part of broader logic-path audit (#24-#31), though some may warrant clarification. Verify that additional changes to storage/pipeline apps, db/index.ts, recon.ts, and dashboard hooks are intentional audit fixes and not scope creep.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: decoding corrupted/encoded sources and fixing correctness bugs identified by audit.
Linked Issues check ✅ Passed The PR successfully addresses all critical and high-priority findings from issue #27 (import_vectors.sh): fixed EXECUTE guard, URL extraction pattern, added error handling for git subtree, improved quoting, added set -euo pipefail, and URL validation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/logic-path-audit-mXlrP

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request updates the BugBountyOS by replacing hardcoded configuration values with environment variables in the Airtable adapter, enhancing the vector import script with validation and error handling, and adding input validation to the dashboard's recon routes. It also configures SQLAlchemy for the pipeline and storage services and removes unused imports. Feedback suggests removing hardcoded default IDs to improve security, making the git branch name configurable in the import script, and masking raw error messages in API responses to prevent information disclosure.

Comment thread adapters/airtable/scope_mapper.py Outdated
Comment thread import_vectors.sh Outdated
const { target, scanType } = parsed.data;
res.json(await performRecon(target, scanType));
} catch (err) {
res.status(500).json({ error: err instanceof Error ? err.message : "scan failed" });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-medium medium

Exposing the raw error message (err.message) to the client in a 500 response can lead to information disclosure, potentially revealing internal system details. It is recommended to log the error details server-side and return a generic error message to the client.

    console.error("Scan failed:", err);
    res.status(500).json({ error: "scan failed" });

@canstralian
canstralian marked this pull request as ready for review May 27, 2026 15:48
canstralian and others added 2 commits May 28, 2026 01:50
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
control-plane/registry/vectors.yaml (1)

1-29: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore base64 encoding for this registry file.

This file is checked in as plain YAML, but this path is required to be stored base64-encoded in this repository.

As per coding guidelines, "Use base64 encoding for: ... control-plane/registry/vectors.yaml ...".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@control-plane/registry/vectors.yaml` around lines 1 - 29, This file was
checked in as plain YAML but needs to be stored base64-encoded; replace the
current plain-text content of control-plane/registry/vectors.yaml with the
base64 encoding of the entire YAML content (the full "vectors:" document
including all entries like ids dashboard, pipeline, storage, red-sage and their
fields), ensuring you encode using standard base64 (UTF‑8 input) and commit the
encoded string in place of the plain YAML so the repository follows the
guideline to store control-plane/registry/vectors.yaml as base64.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@adapters/mcp/server.py`:
- Around line 7-10: The check_scope function currently ignores its asset_id
parameter and always returns a permissive string; replace the stub in
check_scope with real authorization logic that validates the given asset_id
against the BugBountyOS Immune System (e.g., call an existing immune system
client method like immune_system_client.verify_asset(asset_id) or query the
scope datastore), return a clear authorization result (authorized/denied or
raise a specific exception) based on that verification, and handle/log any
errors from the external call so out-of-scope assets are not permitted by
default.

In `@import_vectors.sh`:
- Line 31: The dry-run echo currently prefixes the command with "[DRY-RUN]"
which makes it non-runnable; change the behavior in the import_vectors.sh line
that echoes the command (the echo of "git subtree add --prefix='vectors/$NAME'
'$URL' main --squash") so it prints a directly copy-pastable command — for
example emit the raw command string without the "[DRY-RUN]" token or print the
token as a separate, non-interfering comment and then echo the executable
command itself so users can copy-paste and run the shown command.

In `@vectors/dashboard/server/routes/recon.ts`:
- Around line 57-62: The current parsing of the incoming target in recon.ts
attempts new URL(target) then falls back to new URL(`https://${target`) but if
both fail it bubbles to a 500; change this to treat an unparseable target as a
client error by returning a 400. In the recon route handler, update the
try/catch logic around the url and target variables so that if both attempts to
construct URL (new URL(target) and new URL(`https://${target}`)) throw, you call
res.status(400).json(...) (or next with a 400 HTTP error) with a clear
validation message about the invalid target instead of allowing the error to
propagate to a 500. Ensure the code references the same url/target variables so
downstream logic still uses the validated URL.
- Around line 76-77: The catch block in the recon route currently sends
err.message to the client; instead, stop exposing internal error text by
returning a stable generic message (e.g., res.status(500).json({ error:
"Internal server error" }) or { error: "scan failed" }) and log the full error
server-side (e.g., console.error(err) or use the existing logger) before sending
the response; update the catch that references err and res.status(500).json(...)
to perform server-side logging of err and return the generic message to the
client.

---

Outside diff comments:
In `@control-plane/registry/vectors.yaml`:
- Around line 1-29: This file was checked in as plain YAML but needs to be
stored base64-encoded; replace the current plain-text content of
control-plane/registry/vectors.yaml with the base64 encoding of the entire YAML
content (the full "vectors:" document including all entries like ids dashboard,
pipeline, storage, red-sage and their fields), ensuring you encode using
standard base64 (UTF‑8 input) and commit the encoded string in place of the
plain YAML so the repository follows the guideline to store
control-plane/registry/vectors.yaml as base64.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4cf8d572-77f3-4145-8421-ef19a488be92

📥 Commits

Reviewing files that changed from the base of the PR and between 3ecfc97 and f64f279.

📒 Files selected for processing (13)
  • adapters/airtable/scope_mapper.py
  • adapters/mcp/server.py
  • control-plane/registry/vectors.yaml
  • import_vectors.sh
  • vectors/dashboard/client/src/hooks/use-programs.ts
  • vectors/dashboard/client/src/hooks/use-toast.ts
  • vectors/dashboard/client/src/hooks/use-user.ts
  • vectors/dashboard/db/index.ts
  • vectors/dashboard/server/routes/recon.ts
  • vectors/pipeline/app.py
  • vectors/pipeline/models.py
  • vectors/pipeline/nlp_processor.py
  • vectors/storage/app.py
💤 Files with no reviewable changes (3)
  • vectors/dashboard/client/src/hooks/use-programs.ts
  • vectors/dashboard/client/src/hooks/use-user.ts
  • vectors/dashboard/client/src/hooks/use-toast.ts

Comment thread adapters/mcp/server.py
Comment on lines +7 to +10
def check_scope(asset_id: str) -> str:
"""Query the BugBountyOS Immune System to verify if an asset is authorized."""
return "Importing Airtable Adapter... Currently Permissive mode."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

check_scope ignores input and always returns permissive authorization.

This currently bypasses the intended scope check path and can authorize out-of-scope assets by behavior.

Suggested fix
 `@mcp.tool`()
 def check_scope(asset_id: str) -> str:
     """Query the BugBountyOS Immune System to verify if an asset is authorized."""
-    return "Importing Airtable Adapter... Currently Permissive mode."
+    # Wire to real adapter/policy check; deny by default if unavailable.
+    authorized = False
+    return "authorized" if authorized else "unauthorized"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@adapters/mcp/server.py` around lines 7 - 10, The check_scope function
currently ignores its asset_id parameter and always returns a permissive string;
replace the stub in check_scope with real authorization logic that validates the
given asset_id against the BugBountyOS Immune System (e.g., call an existing
immune system client method like immune_system_client.verify_asset(asset_id) or
query the scope datastore), return a clear authorization result
(authorized/denied or raise a specific exception) based on that verification,
and handle/log any errors from the external call so out-of-scope assets are not
permitted by default.

Comment thread import_vectors.sh
exit 1
}
else
echo "[DRY-RUN] git subtree add --prefix='vectors/$NAME' '$URL' main --squash"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Dry-run output is not directly runnable due to the [DRY-RUN] prefix.

The emitted line includes a non-command token at the start, so copy-paste execution fails.

Suggested fix
-    echo "[DRY-RUN] git subtree add --prefix='vectors/$NAME' '$URL' main --squash"
+    echo "git subtree add --prefix='vectors/$NAME' '$URL' main --squash"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
echo "[DRY-RUN] git subtree add --prefix='vectors/$NAME' '$URL' main --squash"
echo "git subtree add --prefix='vectors/$NAME' '$URL' main --squash"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@import_vectors.sh` at line 31, The dry-run echo currently prefixes the
command with "[DRY-RUN]" which makes it non-runnable; change the behavior in the
import_vectors.sh line that echoes the command (the echo of "git subtree add
--prefix='vectors/$NAME' '$URL' main --squash") so it prints a directly
copy-pastable command — for example emit the raw command string without the
"[DRY-RUN]" token or print the token as a separate, non-interfering comment and
then echo the executable command itself so users can copy-paste and run the
shown command.

Comment on lines +57 to +62
let url: URL;
try {
url = new URL(target);
} catch {
url = new URL(`https://${target}`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Return 400 for unparseable target instead of bubbling to 500.

If both URL parses fail, this is still client input error, but it currently falls through to the generic 500 path. Normalize/validate target here (or in schema) and surface it as a bad-request failure.

Suggested fix
 async function performRecon(target: string, scanType: string): Promise<ScanResult> {
   let url: URL;
   try {
     url = new URL(target);
   } catch {
-    url = new URL(`https://${target}`);
+    try {
+      url = new URL(`https://${target}`);
+    } catch {
+      throw new Error("invalid target");
+    }
   }
   const domain = url.hostname;
   return { domain, timestamp: new Date().toISOString(), whois: null, dns: { a: [], mx: [], ns: [], txt: [] }, ports: [], technologies: [] };
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let url: URL;
try {
url = new URL(target);
} catch {
url = new URL(`https://${target}`);
}
let url: URL;
try {
url = new URL(target);
} catch {
try {
url = new URL(`https://${target}`);
} catch {
throw new Error("invalid target");
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@vectors/dashboard/server/routes/recon.ts` around lines 57 - 62, The current
parsing of the incoming target in recon.ts attempts new URL(target) then falls
back to new URL(`https://${target`) but if both fail it bubbles to a 500; change
this to treat an unparseable target as a client error by returning a 400. In the
recon route handler, update the try/catch logic around the url and target
variables so that if both attempts to construct URL (new URL(target) and new
URL(`https://${target}`)) throw, you call res.status(400).json(...) (or next
with a 400 HTTP error) with a clear validation message about the invalid target
instead of allowing the error to propagate to a 500. Ensure the code references
the same url/target variables so downstream logic still uses the validated URL.

Comment on lines +76 to +77
} catch (err) {
res.status(500).json({ error: err instanceof Error ? err.message : "scan failed" });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid exposing raw internal error messages in HTTP 500 responses.

err.message should not be sent directly to clients. Return a stable generic message (and log full error server-side) to reduce information leakage.

Suggested fix
   } catch (err) {
-    res.status(500).json({ error: err instanceof Error ? err.message : "scan failed" });
+    // log err internally
+    res.status(500).json({ error: "scan failed" });
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (err) {
res.status(500).json({ error: err instanceof Error ? err.message : "scan failed" });
} catch (err) {
// log err internally
res.status(500).json({ error: "scan failed" });
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@vectors/dashboard/server/routes/recon.ts` around lines 76 - 77, The catch
block in the recon route currently sends err.message to the client; instead,
stop exposing internal error text by returning a stable generic message (e.g.,
res.status(500).json({ error: "Internal server error" }) or { error: "scan
failed" }) and log the full error server-side (e.g., console.error(err) or use
the existing logger) before sending the response; update the catch that
references err and res.status(500).json(...) to perform server-side logging of
err and return the generic message to the client.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

import_vectors.sh cannot work in live (EXECUTE=1) mode

2 participants