Skip to content

[mirror] Make recursive lookups honor -p/--allow-private-address#2

Open
yashwant86 wants to merge 10 commits intomm-base-718from
mm-pr-718
Open

[mirror] Make recursive lookups honor -p/--allow-private-address#2
yashwant86 wants to merge 10 commits intomm-base-718from
mm-pr-718

Conversation

@yashwant86
Copy link
Copy Markdown

@yashwant86 yashwant86 commented Apr 26, 2026

Mirror of upstream fedify-dev#718 for benchmark. Do not merge.


Summary by MergeMonkey

  • Docs & Guides:
    • Updated CLI docs to reflect that recursive lookups now honor the `-p`/`--allow-private-address` flag.
    • Clarified that private address filtering applies to URLs discovered during traversal.
  • What's New:
    • Recursive lookups now respect `-p`/`--allow-private-address` flag to allow private/localhost targets in traversal.
    • Added detection of private context URLs in recursive JSON-LD fetches with targeted error messaging.
  • Bug Fixes:
    • Fixed recursive lookups to always block private JSON-LD context URLs regardless of `-p` flag, preventing SSRF via context injection.
  • Refactors:
    • Added comprehensive test suite for recursive private address handling with local test server.

dahlia added 10 commits April 24, 2026 21:48
Make `fedify lookup --recurse` honor the same explicit
`-p`/`--allow-private-address` opt-in that `--traverse` already
uses for discovered URLs.

Update the recursive lookup failure hints to use Optique option
markup, refresh the CLI docs and changelog, and add regression
tests covering both the default blocked behavior and the opt-in
path using `srvx`.

Fixes fedify-dev#700

Assisted-by: Codex:gpt-5.4
Limit the `-p`/`--allow-private-address` opt-in to recursive
object fetches and keep indirect JSON-LD `@context` loads on the
strict loader.

Add a regression test that proves recursive private contexts stay
blocked even when recursive object fetches are explicitly allowed.

Addresses fedify-dev#718 (review)

Assisted-by: Codex:gpt-5.4
Recognize recursive failures caused by private JSON-LD context URLs
and print a dedicated hint instead of suggesting authorized fetch.

Also pin that stderr output in the recursive private-context
regression test so future UX changes stay visible.

Addresses fedify-dev#718 (comment)
Addresses fedify-dev#718 (comment)
Addresses fedify-dev#718 (comment)

Assisted-by: Codex:gpt-5.4
Clarify that `-p`/`--allow-private-address` only applies to
recursive object fetches, while recursive JSON-LD `@context`
loads remain blocked.

Also document the jsonld error-shape dependency in
`getPrivateContextUrl()` so future library upgrades know which
fields and message format this detection relies on.

Addresses fedify-dev#718 (comment)
Addresses fedify-dev#718 (comment)
Addresses fedify-dev#718 (comment)
Addresses fedify-dev#718 (comment)

Assisted-by: Codex:gpt-5.4
Extract the repeated stderr-capture setup into a small helper so
recursive lookup tests share one implementation and always restore
`process.stderr.write` in a single place.

Addresses fedify-dev#718 (comment)

Assisted-by: Codex:gpt-5.4
Require the expected jsonld error name and message shape together
before treating a recursive failure as a blocked private-context
case, and align the inline comment with that predicate.

Addresses fedify-dev#718 (comment)
Addresses fedify-dev#718 (comment)

Assisted-by: Codex:gpt-5.4
Stop routing recursive private-address hints through a synthetic
UrlError, surface the blocked recursive context URL directly, and
make private-context detection prefer structured URL fields before
falling back to the jsonld error message.

Also relax the recursive private-target stderr assertion so it does
not depend on Optique's exact presentation formatting.

Addresses fedify-dev#718 (comment)
Addresses fedify-dev#718 (comment)
Addresses fedify-dev#718 (comment)
Addresses fedify-dev#718 (comment)
Addresses fedify-dev#718 (comment)

Assisted-by: Codex:gpt-5.4
Keep recursive private-address hinting on a cheap hostname-only
path so the failure branch does not need a second DNS-based public-
URL validation pass.

Also cover the obvious private-host detection with a dedicated unit
test.

Addresses fedify-dev#718 (comment)

Assisted-by: Codex:gpt-5.4
Keep recursive private-address hinting on a cheap hostname-only
path so the failure branch does not need a second DNS-based public-
URL validation pass.

Also cover the obvious private-host detection with a dedicated unit
test.

Addresses fedify-dev#718 (comment)

Assisted-by: Codex:gpt-5.4
Add targeted comments explaining why recursive object fetches and
recursive JSON-LD context fetches use different loader policies,
and why the private-address helper functions only exist for
post-failure hint classification.

Assisted-by: Codex:gpt-5.4
@bot-mergemonkey
Copy link
Copy Markdown

bot-mergemonkey Bot commented Apr 26, 2026

Risk AssessmentNEEDS-TESTING · ~25 min review

Focus areas: Async/await correctness in test helpers · Private IP detection logic and edge cases · JSON-LD context error parsing robustness

Assessment: Adds private address filtering to recursive lookups with new detection logic and test infrastructure.

Walkthrough

User runs fedify lookup --recurse --allow-private-address on a localhost URL. The CLI now checks each discovered target URL against a fast private-address detector (localhost, RFC1918, link-local IPs) before fetching. If allowed by the flag, private targets are fetched; if blocked, a targeted error message suggests the flag. JSON-LD context URLs are always blocked for SSRF safety, with a separate error message explaining the restriction.

Changes

Files Summary
Documentation Updates
docs/cli.md
CHANGES.md
Updated documentation to reflect that recursive lookups now honor the `-p`/`--allow-private-address` flag, clarifying behavior for private/localhost targets in traversal.
Private Address Detection & Recursive Lookup Policy
packages/cli/src/lookup.ts
Implemented private address detection for recursive lookups: added `getPrivateUrlCandidate()` to identify private IPs/localhost without DNS, `isPrivateAddressTarget()` for target validation, `getPrivateContextUrl()` to detect blocked private JSON-LD contexts, and separate hint functions for target vs. context errors. Recursive targets now respect `-p` flag while contexts remain always-blocked for SSRF safety.
Recursive Lookup Test Suite
packages/cli/src/lookup.test.ts
Added test infrastructure: `withRecursiveLookupServer()` for local test server with configurable context paths, `captureStderr()` for error message validation, and three integration tests verifying private address handling (default rejection, allowed with flag, context always blocked).

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI
    participant PrivateDetector
    participant Fetcher
    participant ContextLoader
    User->>CLI: lookup --recurse --allow-private-address URL
    CLI->>Fetcher: fetch root URL
    Fetcher->>CLI: return object with inReplyTo
    CLI->>PrivateDetector: check inReplyTo target
    alt Target is private
        PrivateDetector->>CLI: isPrivateAddressTarget=true
        alt allowPrivateAddress flag set
            CLI->>Fetcher: fetch private target
            Fetcher->>CLI: return object
        else flag not set
            CLI->>CLI: printRecursivePrivateAddressHint()
            CLI->>User: error: use -p flag
        end
    else Target is public
        PrivateDetector->>CLI: isPrivateAddressTarget=false
        CLI->>Fetcher: fetch target
    end
    CLI->>ContextLoader: load @context URL
    alt Context URL is private
        ContextLoader->>CLI: error (always blocked)
        CLI->>CLI: printRecursivePrivateContextHint()
        CLI->>User: error: context always blocked
    else Context URL is public
        ContextLoader->>CLI: context loaded
    end
Loading

Dig Deeper With Commands

  • /review <file-path> <function-optional>
  • /chat <file-path> "<question>"
  • /roast <file-path>

Runs only when explicitly triggered.

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.

2 participants