Skip to content

[WIP] Verify website ownership for domain identities#897

Open
HaykK-Solicy wants to merge 4 commits into
stabilisationfrom
feature/add-domain-identity
Open

[WIP] Verify website ownership for domain identities#897
HaykK-Solicy wants to merge 4 commits into
stabilisationfrom
feature/add-domain-identity

Conversation

@HaykK-Solicy
Copy link
Copy Markdown
Contributor

@HaykK-Solicy HaykK-Solicy commented Jun 1, 2026

Adds the node side of website-ownership identity.

The node fetches the wallet-signed proof file from the claimed domain over HTTPS (TLS cert binds content to the hostname), verifies the signature against the sender, and enforces that the proof URL's host matches the claimed domain. Verified domains flow through the existing generic web2 GCR write path as web2.domain.

Summary by CodeRabbit

  • New Features
    • Domain ownership proof verification via HTTPS, plus a backend endpoint and protocol message to request/fetch proofs.
  • Bug Fixes
    • Enforced HTTPS, exact proof-path checks, and hostname validation for proof URLs.
    • Added network-level protections when fetching proofs (SSRF/address restrictions, timeouts, no-redirects, size limits).

@qodo-code-review
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Add domain identity verification with website ownership proof

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Adds domain identity verification via website ownership proof
• Implements HTTPS-based proof fetching with TLS certificate validation
• Integrates domain proof parser into web2 identity verification flow
• Adds new opcode and handler for domain proof retrieval
Diagram
flowchart LR
  A["Domain Proof Request"] --> B["Validate URL Format"]
  B --> C["Fetch via HTTPS"]
  C --> D["Verify TLS Certificate"]
  D --> E["Parse Proof Payload"]
  E --> F["DomainProofParser"]
  F --> G["Web2 Identity Flow"]

Loading

Grey Divider

File Changes

1. src/libs/abstraction/index.ts ✨ Enhancement +37/-0

Add domain proof verification to web2 abstraction

• Imports DomainProofParser and DOMAIN_PROOF_PATH from domain module
• Adds domain case to verifyWeb2Proof switch statement
• Validates proof URL format, HTTPS protocol, well-known path, and hostname matching
• Routes domain proofs to DomainProofParser for signature verification

src/libs/abstraction/index.ts


2. src/libs/abstraction/web2/domain.ts ✨ Enhancement +92/-0

Implement domain proof parser and HTTPS fetcher

• Creates new DomainProofParser class extending Web2ProofParser
• Implements fetchDomainProof function to retrieve proof files over HTTPS with configurable
 certificate validation
• Enforces maximum payload size of 4096 bytes and 10-second timeout
• Parses domain proof payload and returns hostname and body

src/libs/abstraction/web2/domain.ts


3. src/libs/abstraction/web2/parsers.ts ✨ Enhancement +1/-0

Add domain format to proof parser formats

• Adds domain format entry to proof URL formats mapping
• Domain format accepts any HTTPS URL as valid base

src/libs/abstraction/web2/parsers.ts


View more (3)
4. src/libs/network/handlers/identityHandlers.ts ✨ Enhancement +41/-0

Add getDomainProof network handler

• Imports fetchDomainProof and DOMAIN_PROOF_PATH utilities
• Implements new getDomainProof handler for retrieving domain ownership proofs
• Validates URL format and well-known path before fetching
• Returns hostname and proof body on success with error handling

src/libs/network/handlers/identityHandlers.ts


5. src/libs/omniprotocol/protocol/opcodes.ts ✨ Enhancement +1/-0

Add GET_DOMAIN_PROOF opcode

• Adds new opcode GET_DOMAIN_PROOF = 0x55 for domain proof retrieval

src/libs/omniprotocol/protocol/opcodes.ts


6. src/libs/omniprotocol/protocol/registry.ts ✨ Enhancement +6/-0

Register domain proof opcode handler

• Registers GET_DOMAIN_PROOF opcode handler descriptor
• Maps opcode to getDomainProof handler with HTTP fallback
• Sets authentication as not required for domain proof requests

src/libs/omniprotocol/protocol/registry.ts


Grey Divider

Qodo Logo

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

Warning

Review limit reached

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

More reviews will be available in 24 minutes. 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3c3e0c08-693c-4a25-bf9a-63583cc36bb3

📥 Commits

Reviewing files that changed from the base of the PR and between ac0eb44 and 3af533f.

📒 Files selected for processing (1)
  • src/libs/abstraction/web2/domain.ts

Walkthrough

Adds domain-based Web2 proof support: SSRF-checked HTTPS fetching of proof URLs, a DomainProofParser, verifier integration validating URL scheme/path/hostname, a network handler endpoint, and an OmniProtocol opcode/registry entry.

Changes

Domain Proof Verification

Layer / File(s) Summary
Domain proof implementation
src/libs/abstraction/web2/domain.ts
fetchDomainProof() enforces https:, performs DNS/IP SSRF checks, configures TLS agent per environment, fetches trimmed plain-text proofs with size/timeout/redirect limits, and returns { hostname, body }. DomainProofParser.readData() validates format, fetches body, parses payload, and returns { message, type, signature }.
Parser registration and types
src/libs/abstraction/web2/parsers.ts, src/libs/abstraction/index.ts
Web2ProofParser.formats adds domain: ["https://"]. index.ts imports DomainProofParser and DOMAIN_PROOF_PATH and extends the internal verifier parser union.
Domain verification in proof flow
src/libs/abstraction/index.ts
New case "domain" in verifyWeb2Proof parses payload.proof as a URL, requires https: scheme, exact DOMAIN_PROOF_PATH pathname, and hostname matching payload.username (lowercased); selects DomainProofParser on success.
Network endpoint
src/libs/network/handlers/identityHandlers.ts
getDomainProof handler validates data.url and pathname, calls fetchDomainProof(), and returns { success: true, hostname, body } or HTTP 400 on failure with logging.
Protocol opcode and registry
src/libs/omniprotocol/protocol/opcodes.ts, src/libs/omniprotocol/protocol/registry.ts
Added OmniOpcode.GET_DOMAIN_PROOF = 0x55 and a registry descriptor mapping to getDomainProof with authRequired: false and an HTTP fallback handler.

Sequence Diagram

sequenceDiagram
  participant Client
  participant getDomainProof_Handler
  participant fetchDomainProof
  participant HTTPS_Server
  participant DomainProofParser

  Client->>getDomainProof_Handler: GET_DOMAIN_PROOF (url)
  getDomainProof_Handler->>getDomainProof_Handler: validate URL structure
  getDomainProof_Handler->>fetchDomainProof: fetch proof from URL
  fetchDomainProof->>HTTPS_Server: HTTPS request (with TLS agent)
  HTTPS_Server->>fetchDomainProof: proof body
  fetchDomainProof->>getDomainProof_Handler: { hostname, body }
  getDomainProof_Handler->>Client: HTTP 200 { success, hostname, body }

  Note over Client,DomainProofParser: Later verification flow
  Client->>verifyWeb2Proof: verify domain proof
  verifyWeb2Proof->>DomainProofParser: readData(proofUrl)
  DomainProofParser->>fetchDomainProof: fetch proof
  fetchDomainProof->>DomainProofParser: { hostname, body }
  DomainProofParser->>Client: { message, type, signature }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Suggested labels

Possible security concern, Review effort 2/5

Suggested reviewers

  • cwilvx
  • Shitikyan

Poem

🐰 I hopped to fetch a proof so true,
HTTPS paths and DNS checks too,
TLS snug, no private IP in sight,
Parser reads the message, signature right,
A tiny rabbit cheers the secure byte!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '[WIP] Verify website ownership for domain identities' is partially related to the changeset. It captures a key aspect of the work (verifying website ownership for domain identities), but uses the '[WIP]' prefix suggesting work-in-progress status, which may be unclear in a merged commit history.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 feature/add-domain-identity

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.

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review Bot commented Jun 1, 2026

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0)

Grey Divider


Action required

1. Unauthenticated SSRF RPC ✓ Resolved 🐞 Bug ⛨ Security
Description
The publicly reachable nodeCall method getDomainProof lets any caller trigger an outbound HTTPS
fetch to a caller-chosen URL (with only the path constrained) and returns the response body,
creating an SSRF/open-proxy primitive that can be used for internal probing or data exfiltration.
The risk is amplified because fetchDomainProof lacks DNS/IP allow/deny checks and disables
certificate validation in non-PROD, making SSRF significantly easier to exploit.
Code

src/libs/network/handlers/identityHandlers.ts[R163-199]

Evidence
manageNodeCall dispatches nodeCall handlers by method name without an authentication gate, and the
getDomainProof handler directly calls fetchDomainProof(data.url) and returns `{ hostname, body
}` to the caller, which exposes an unauthenticated fetch of a caller-controlled URL and leaks the
fetched response body. In addition, fetchDomainProof performs no hostname resolution or
private-address blocking before issuing the request, and while the codebase’s web2 Proxy contains an
existing SSRF preflight approach (DNS resolution plus rejecting private/link-local/loopback
targets), that protection is not applied to the domain-proof fetch path; coupled with non-PROD
rejectUnauthorized being disabled, this broadens exploitability.

src/libs/network/handlers/identityHandlers.ts[163-201]
src/libs/network/manageNodeCall.ts[18-28]
src/libs/abstraction/web2/domain.ts[26-46]
src/libs/abstraction/index.ts[262-276]
src/features/web2/proxy/Proxy.ts[235-254]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`getDomainProof` can be invoked without authentication and triggers `fetchDomainProof` to retrieve a caller-supplied `https://...` URL (only validating `pathname`), returning the fetched body to the caller. This creates an SSRF/open-proxy surface, and because `fetchDomainProof` does not preflight DNS/IPs to block private/loopback/link-local/etc. targets (or domains resolving to them) and disables TLS verification in non-PROD, it can be abused for internal probing and data exfiltration.
## Issue Context
- `manageNodeCall` dispatches by method name without auth gating, making `getDomainProof` publicly reachable.
- `getDomainProof` calls `fetchDomainProof(data.url)` and returns `{hostname, body}` to the caller.
- `fetchDomainProof` lacks hostname resolution and private-address blocking before issuing outbound requests.
- In PROD, `rejectUnauthorized` is enabled (helps in some cases but does not prevent SSRF to internal services with valid certs); in non-PROD it is disabled, turning this into a stronger SSRF primitive.
- The repository already has robust SSRF preflight logic in the web2 Proxy (DNS lookup + blocking private/link-local/loopback ranges); this should be reused/extracted for consistency.
## Fix Focus Areas
- src/libs/network/manageNodeCall.ts[18-28]
- src/libs/network/handlers/identityHandlers.ts[163-201]
- src/libs/abstraction/web2/domain.ts[26-46]
- src/features/web2/proxy/Proxy.ts[235-254]
- src/libs/abstraction/index.ts[262-276]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Domain host match not normalized ✓ Resolved 🐞 Bug ≡ Correctness
Description
verifyWeb2Proof() compares proofUrl.hostname to payload.username with strict equality, but
URL.hostname is normalized (lowercased/punycode) while payload.username is not, causing valid
domains to fail verification. This will produce false negatives for domain identity assignment.
Code

src/libs/abstraction/index.ts[R219-229]

Evidence
The domain flow uses a strict string equality check between a parsed URL hostname and the raw
payload username, while the same module shows a precedent of normalizing user-provided identifiers
for comparison in the Telegram verifier.

src/libs/abstraction/index.ts[199-233]
src/libs/abstraction/index.ts[90-107]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Domain verification rejects valid proofs because it compares the normalized `URL.hostname` directly to an unnormalized user-provided `payload.username`.
### Issue Context
- `new URL(...).hostname` is normalized by the URL parser (lowercase and punycode for IDNs).
- The same file already normalizes user-provided identifiers for Telegram (`toLowerCase().trim()`), indicating normalization is expected.
### Fix Focus Areas
- Normalize both sides before comparing:
- `const claimed = domainToASCII(payload.username.trim().toLowerCase())` (or equivalent)
- Compare against `proofUrl.hostname` (already normalized) or normalize it too for clarity.
- Optionally validate that `payload.username` is a bare hostname (no scheme/path) to prevent surprising inputs.
#### Code pointers
- src/libs/abstraction/index.ts[199-233]
- src/libs/abstraction/index.ts[90-107]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@HaykK-Solicy HaykK-Solicy changed the title feat(identity): verify website ownership for domain identities [WIP] Verify website ownership for domain identities Jun 1, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jun 1, 2026

Greptile Summary

This PR adds node-side domain ownership verification: the node fetches a well-known proof file over HTTPS, validates its signature against the sender's wallet, and enforces that the proof URL's hostname matches the claimed domain. The implementation includes an SSRF guard with DNS pinning, a size cap, and redirect suppression.

  • domain.ts — New fetchDomainProof helper with resolveAndValidateHost SSRF guard (resolves all A/AAAA records, blocks non-public IPs, pins the socket to the validated IP to defeat DNS rebinding) and DomainProofParser integrating with the existing Web2ProofParser base.
  • index.ts — New "domain" case in verifyWeb2Proof that checks protocol, path, and hostname before delegating to DomainProofParser; the hostname comparison uses URL.hostname which strips the port, allowing proofs to be fetched from non-standard ports.
  • identityHandlers.ts / registry.ts / opcodes.ts — Adds the unauthenticated getDomainProof protocol message so clients can retrieve a domain's proof file via the node before submitting a verification.

Confidence Score: 3/5

The domain ownership check can be satisfied from a non-standard HTTPS port, so a party who controls port 9999 (or any non-443 port) on a host could forge a proof for that domain.

The core hostname match in verifyWeb2Proof uses URL.hostname, which is port-stripped. A proof at https://example.com:9999/.well-known/demos-cci.txt passes the hostname matches claimed domain check against example.com and then connects to port 9999. The same gap exists in fetchDomainProof and the getDomainProof handler. Without an explicit port guard, the ownership model is weaker than intended.

src/libs/abstraction/index.ts (verifyWeb2Proof domain case), src/libs/abstraction/web2/domain.ts (fetchDomainProof missing port check), and src/libs/network/handlers/identityHandlers.ts (getDomainProof handler missing port check).

Important Files Changed

Filename Overview
src/libs/abstraction/web2/domain.ts New file implementing SSRF-guarded HTTPS proof fetch with DNS-pinning; non-standard port is not rejected in fetchDomainProof, allowing connections to arbitrary ports on a target host.
src/libs/abstraction/index.ts Adds "domain" case to verifyWeb2Proof; hostname match uses URL.hostname (port-stripped), so non-standard ports pass silently — proof should only be accepted from port 443.
src/libs/network/handlers/identityHandlers.ts Adds unauthenticated getDomainProof handler with protocol and path validation but no port restriction; duplicates validation logic already present in fetchDomainProof.
src/libs/abstraction/web2/parsers.ts Adds domain format entry ["https://"] with a comment explaining that deeper validation is handled upstream; no structural issues.
src/libs/omniprotocol/protocol/opcodes.ts Adds GET_DOMAIN_PROOF opcode 0x55 in the correct sequential position; no issues.
src/libs/omniprotocol/protocol/registry.ts Registers getDomainProof handler with authRequired: false, consistent with getTweet/getDiscordMessage peers; no structural issues.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Node
    participant DNS
    participant TargetDomain

    Note over Client,Node: getDomainProof (unauthenticated helper)
    Client->>Node: "GET_DOMAIN_PROOF {url}"
    Node->>Node: validate protocol + path
    Node->>DNS: resolveAndValidateHost(hostname)
    DNS-->>Node: resolved IPs (all validated as public)
    Node->>Node: pin socket to resolved[0]
    Node->>TargetDomain: HTTPS GET /.well-known/demos-cci.txt
    TargetDomain-->>Node: proof file body
    Node-->>Client: "{hostname, body}"

    Note over Client,Node: verifyWeb2Proof (domain context)
    Client->>Node: "REGISTER_WEB2_IDENTITY {context:domain, username, proof:url}"
    Node->>Node: check protocol, path, hostname vs username
    Node->>Node: DomainProofParser.readData(proofUrl)
    Node->>DNS: resolveAndValidateHost(hostname)
    DNS-->>Node: resolved IPs
    Node->>TargetDomain: HTTPS GET (pinned socket)
    TargetDomain-->>Node: proof body
    Node->>Node: parsePayload
    Node->>Node: verify signature
    Node-->>Client: "{success: true/false}"
Loading

Reviews (4): Last reviewed commit: "fixed error from fetchDomainProof" | Re-trigger Greptile

Comment thread src/libs/network/handlers/identityHandlers.ts
Comment thread src/libs/network/handlers/identityHandlers.ts
Comment thread src/libs/abstraction/web2/parsers.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/libs/abstraction/web2/domain.ts (1)

2-2: 💤 Low value

Prefer node: protocol prefix for Node.js built-in modules.

Using node:https explicitly identifies this as a Node.js built-in module, improving clarity and avoiding potential conflicts with npm packages of the same name.

Suggested fix
-import https from "https"
+import https from "node:https"
🤖 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 `@src/libs/abstraction/web2/domain.ts` at line 2, Replace the built-in module
import to use the Node.js protocol prefix: change the import of https (the line
importing https in src/libs/abstraction/web2/domain.ts) to use "node:https" so
the runtime and readers clearly see this is a core Node module and avoid
conflicts with similarly named npm packages.
🤖 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 `@src/libs/abstraction/index.ts`:
- Around line 225-230: The hostname check using proofUrl.hostname vs
payload.username should be done case-insensitively; update the comparison (where
proofUrl.hostname and payload.username are used) to normalize both sides (e.g.,
toLowerCase()) before comparing so "Example.COM" and "example.com" match, and
keep the same return shape when the comparison fails.

In `@src/libs/abstraction/web2/domain.ts`:
- Around line 70-76: The log currently concatenates the caught error which can
become "[object Object]"; update the catch in the domain proof fetch block that
calls fetchDomainProof(proofUrl) to log the real error message/stack (e.g.,
log.error(`[DOMAIN] Failed to fetch proof for ${proofUrl}: ${error?.message ??
String(error)}`, { stack: error?.stack })) and when rethrowing either include
the original error as the cause or append the error message to the new Error so
the underlying error details are preserved; reference the fetchDomainProof call,
the catch block, log.error, and the proofUrl variable when making this change.

In `@src/libs/network/handlers/identityHandlers.ts`:
- Around line 192-199: The catch block in getDomainProof should stop
concatenating the error into the message; instead pass the error as a structured
argument to the logger so stack and metadata are preserved (e.g., call log.error
with a message and the error object or an object containing the error) and keep
setting response.result and response.response as before; update the catch in
identityHandlers.ts where log.error is called to use structured logging
(reference: getDomainProof and log.error).
- Around line 188-189: fetchDomainProof currently enforces HTTPS but allows SSRF
by resolving arbitrary hostnames; update fetchDomainProof (and callers like
getDomainProof) to perform DNS resolution (dns.promises.lookup with { all: true
}) and reject requests if any resolved address is
private/loopback/link-local/unique-local/metadata (check RFC1918 10.0.0.0/8,
172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, 169.254.0.0/16, 169.254.169.254,
::1, fe80::/10, fc00::/7, plus carrier-grade 100.64.0.0/10) or if the hostname
is an IP literal in those ranges; optionally add an allowlist of explicit public
hostnames and short-circuit to allow only those. Implement a helper like
isPrivateOrLocalAddress(ip) to centralize range checks and throw/return an error
before creating the https.Agent or making the request. Ensure getDomainProof
remains authRequired: false but relies on the hardened fetchDomainProof to block
internal targets.

---

Nitpick comments:
In `@src/libs/abstraction/web2/domain.ts`:
- Line 2: Replace the built-in module import to use the Node.js protocol prefix:
change the import of https (the line importing https in
src/libs/abstraction/web2/domain.ts) to use "node:https" so the runtime and
readers clearly see this is a core Node module and avoid conflicts with
similarly named npm packages.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b2a6a8d7-9d1e-4010-9e50-3cd8840eeae5

📥 Commits

Reviewing files that changed from the base of the PR and between f62a609 and 55dcf4e.

📒 Files selected for processing (6)
  • src/libs/abstraction/index.ts
  • src/libs/abstraction/web2/domain.ts
  • src/libs/abstraction/web2/parsers.ts
  • src/libs/network/handlers/identityHandlers.ts
  • src/libs/omniprotocol/protocol/opcodes.ts
  • src/libs/omniprotocol/protocol/registry.ts

Comment thread src/libs/abstraction/index.ts Outdated
Comment thread src/libs/abstraction/web2/domain.ts
Comment thread src/libs/network/handlers/identityHandlers.ts
Comment thread src/libs/network/handlers/identityHandlers.ts
Comment thread src/libs/network/handlers/identityHandlers.ts
- add SSRF guard to fetchDomainProof: resolve all A/AAAA records and reject
  private/loopback/link-local/metadata/CGNAT targets before the request
  (link-local/metadata blocked in all envs; loopback/private dev-only)
- getDomainProof: explicit https protocol check with a clear error
- verifyWeb2Proof: case-insensitive proof-host vs claimed-domain comparison
- domain proof fetch: preserve real error message/detail in logs + rethrow
- getDomainProof: structured error logging instead of string concat
- clarify the "domain" parser format only checks scheme (binding enforced upstream)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@src/libs/abstraction/web2/domain.ts`:
- Around line 34-64: assertAllowedHostname currently resolves the hostname and
classifies addresses but fetchDomainProof calls axios.get with the original
hostname allowing DNS rebinding between check and connect; fix by resolving once
with dns.promises.lookup (as in assertAllowedHostname), validate each IP against
DEV_ALLOWED_RANGES, then force the HTTP(S) connection to that validated IP by
passing the IP as the request host (for IPv6 use bracketed form), set the
original hostname in the Host header and set the TLS SNI/servername on the HTTPS
agent (e.g., via new https.Agent({ servername: hostname, ... })) so TLS and Host
header preserve the hostname while the socket connects to the pinned IP, and
ensure axios is configured with maxRedirects:0 to avoid re-checks; update
fetchDomainProof to call the resolution+validation logic (reusing
assertAllowedHostname or extracting its logic) and to construct the custom
agent/headers before calling axios.get.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 871438b4-809b-4356-a075-9fbbbca8f5c9

📥 Commits

Reviewing files that changed from the base of the PR and between 55dcf4e and ac0eb44.

📒 Files selected for processing (4)
  • src/libs/abstraction/index.ts
  • src/libs/abstraction/web2/domain.ts
  • src/libs/abstraction/web2/parsers.ts
  • src/libs/network/handlers/identityHandlers.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/libs/abstraction/web2/parsers.ts
  • src/libs/network/handlers/identityHandlers.ts
  • src/libs/abstraction/index.ts

Comment thread src/libs/abstraction/web2/domain.ts Outdated
Comment thread src/libs/abstraction/web2/domain.ts Outdated
Comment thread src/libs/abstraction/web2/domain.ts
Comment thread src/libs/abstraction/index.ts
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.

1 participant