Skip to content

Use dns.lookup and dns.resolve4 not just dns.resolve4 alone#102

Merged
HackingRepo merged 1 commit into
mainfrom
HackingRepo-patch-10
Jun 9, 2026
Merged

Use dns.lookup and dns.resolve4 not just dns.resolve4 alone#102
HackingRepo merged 1 commit into
mainfrom
HackingRepo-patch-10

Conversation

@HackingRepo

@HackingRepo HackingRepo commented Jun 9, 2026

Copy link
Copy Markdown
Owner

PR Summary by Qodo

Fallback to dns.lookup when resolve4/resolve6 return no A/AAAA records
🐞 Bug fix ✨ Enhancement 🕐 10-20 Minutes

Grey Divider

Walkthroughs

Description
• Resolve A/AAAA/CNAME in parallel and return a single consolidated result.
• Fall back to dns.lookup(all:true) when resolve4/resolve6 return no addresses.
• Improve hostname resolution reliability for internal-IP and URL-safety checks.
Diagram
graph TD
  A["is_url_safe()"] --> B["is_hostname_resolve_to_internal_ip()"] --> C["resolve_all_records()"]
  C --> D{{"dns.resolve4/6/cname"}} --> E{"A/AAAA empty?"}
  E -->|"yes"| F{{"dns.lookup(all:true)"}} --> G["Merge A/AAAA"] --> H["Return records"]
  E -->|"no"| H

  subgraph Legend
    direction LR
    _fn["Function"] ~~~ _ext{{"Node.js DNS"}} ~~~ _dec{"Decision"}
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Prefer dns.lookup first, then record-specific resolves
  • ➕ Matches OS resolver behavior (search domains, /etc/hosts) consistently
  • ➕ May reduce false negatives where authoritative queries return empty
  • ➖ Can mask DNS misconfigurations by relying on system-specific resolver state
  • ➖ May return fewer record types (e.g., no CNAME chain visibility)
2. Use dns.resolveAny as a single query path
  • ➕ Single call can return multiple record types without separate resolve4/6 calls
  • ➕ Simplifies the decision of 'no records' vs 'some records'
  • ➖ Record parsing/normalization is more complex and varies by record kind
  • ➖ Still may not reflect OS resolver behavior like dns.lookup
3. Add caching for resolution results (short TTL)
  • ➕ Reduces repeated DNS calls in hot paths (URL checks at scale)
  • ➕ Improves latency and limits resolver load
  • ➖ Cache invalidation/TTL tuning adds complexity and potential correctness risks
  • ➖ Security-sensitive code must avoid over-caching stale results

Recommendation: The PR’s approach (parallel resolve4/6/cname plus a lookup-based fallback only when A/AAAA are empty) is a good balance: it keeps explicit DNS-record queries as the primary source while addressing real-world cases where lookup succeeds but resolve4/6 yields no addresses. If this code runs frequently, consider a small TTL cache later, but it’s not required for correctness.

Grey Divider

File Changes

Bug fix (1)
helpers.ts Add dns.lookup fallback and parallel DNS record resolution +17/-11

Add dns.lookup fallback and parallel DNS record resolution

• Refactors resolve_all_records() to resolve A/AAAA/CNAME concurrently via Promise.all. When both A and AAAA results are empty, it falls back to dns.lookup({ all: true }) and merges returned IPv4/IPv6 addresses into the existing arrays before returning.

src/helpers.ts


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Jun 9, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0)

Grey Divider


Action required

1. Dist build not updated 🐞 Bug ≡ Correctness
Description
The PR updates resolve_all_records() in src/helpers.ts, but the runtime entrypoint is
dist/utils.js which uses dist/helpers.js; since dist/helpers.js still contains the old
resolver implementation, the shipped behavior will not include the new dns.lookup fallback.
Code

src/helpers.ts[R273-290]

+    const [A, AAAA, CNAME] = await Promise.all([
+        dns.resolve4(host).catch(() => [] as string[]),
+        dns.resolve6(host).catch(() => [] as string[]),
+        dns.resolveCname(host).catch(() => [] as string[])
+    ]);
+
+    if (A.length === 0 && AAAA.length === 0) {
+        try {
+            const lookups = await dns.lookup(host, { all: true });
+            for (const entry of lookups) {
+                if (entry.family === 4) A.push(entry.address);
+                if (entry.family === 6) AAAA.push(entry.address);
+            }
+        } catch {}
+    }

+    return { A, AAAA, CNAME };
+}
Evidence
The repository’s published entrypoint is the compiled dist/ output, but only the TypeScript source
was modified in this PR. The current dist/helpers.js still shows the old sequential
resolve4/resolve6/resolveCname implementation without the new dns.lookup fallback, so consumers
loading dist/utils.js will not execute the updated logic.

package.json[20-36]
dist/helpers.js[253-263]
src/helpers.ts[270-290]
.gitignore[1-2]

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

### Issue description
The package runtime entrypoint is `dist/utils.js` (CommonJS), which pulls in `dist/helpers.js`. This PR changes DNS behavior only in `src/helpers.ts`, leaving the compiled `dist/` artifacts stale. As a result, consumers will not receive the new `dns.lookup` fallback.

### Issue Context
- `package.json` declares `main: dist/utils.js` and exports `./dist/utils.js`.
- `dist/helpers.js` still contains the pre-change `resolve_all_records()` implementation.
- `dist/` is not ignored, and there is no `prepublishOnly`/`prepare` script shown that would automatically rebuild `dist/` on publish.

### Fix Focus Areas
- src/helpers.ts[270-290]
- dist/helpers.js[253-263]
- package.json[20-36]
- .gitignore[1-2]

### Suggested fix
1. Run `npm run build` (tsc) to regenerate `dist/helpers.js`, `dist/utils.js`, and the corresponding `.d.ts` outputs.
2. Commit the updated `dist/` artifacts.
3. (Optional but recommended) Add a `prepublishOnly` (or `prepare`) script to ensure `dist/` is always rebuilt before publishing.

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


Grey Divider

Qodo Logo

@HackingRepo HackingRepo merged commit 668c217 into main Jun 9, 2026
10 of 13 checks passed
@HackingRepo HackingRepo deleted the HackingRepo-patch-10 branch June 9, 2026 11:13
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Comment thread src/helpers.ts
Comment on lines +273 to +290
const [A, AAAA, CNAME] = await Promise.all([
dns.resolve4(host).catch(() => [] as string[]),
dns.resolve6(host).catch(() => [] as string[]),
dns.resolveCname(host).catch(() => [] as string[])
]);

if (A.length === 0 && AAAA.length === 0) {
try {
const lookups = await dns.lookup(host, { all: true });
for (const entry of lookups) {
if (entry.family === 4) A.push(entry.address);
if (entry.family === 6) AAAA.push(entry.address);
}
} catch {}
}

return { A, AAAA, CNAME };
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Dist build not updated 🐞 Bug ≡ Correctness

The PR updates resolve_all_records() in src/helpers.ts, but the runtime entrypoint is
dist/utils.js which uses dist/helpers.js; since dist/helpers.js still contains the old
resolver implementation, the shipped behavior will not include the new dns.lookup fallback.
Agent Prompt
### Issue description
The package runtime entrypoint is `dist/utils.js` (CommonJS), which pulls in `dist/helpers.js`. This PR changes DNS behavior only in `src/helpers.ts`, leaving the compiled `dist/` artifacts stale. As a result, consumers will not receive the new `dns.lookup` fallback.

### Issue Context
- `package.json` declares `main: dist/utils.js` and exports `./dist/utils.js`.
- `dist/helpers.js` still contains the pre-change `resolve_all_records()` implementation.
- `dist/` is not ignored, and there is no `prepublishOnly`/`prepare` script shown that would automatically rebuild `dist/` on publish.

### Fix Focus Areas
- src/helpers.ts[270-290]
- dist/helpers.js[253-263]
- package.json[20-36]
- .gitignore[1-2]

### Suggested fix
1. Run `npm run build` (tsc) to regenerate `dist/helpers.js`, `dist/utils.js`, and the corresponding `.d.ts` outputs.
2. Commit the updated `dist/` artifacts.
3. (Optional but recommended) Add a `prepublishOnly` (or `prepare`) script to ensure `dist/` is always rebuilt before publishing.

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

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