blackveil-dns 2.9.2 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -4
- package/dist/index.d.ts +5 -1
- package/dist/index.js +49 -7
- package/dist/index.js.map +1 -1
- package/dist/stdio.js +226 -145
- package/dist/stdio.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -82,7 +82,7 @@ Transport support:
|
|
|
82
82
|
## Tools
|
|
83
83
|
|
|
84
84
|
```
|
|
85
|
-
|
|
85
|
+
51 MCP tools · 7 prompts · 6 resources
|
|
86
86
|
|
|
87
87
|
Email Auth Infrastructure Brand & Threats Meta
|
|
88
88
|
──────────── ──────────────── ───────────────── ──────────────────────
|
|
@@ -111,10 +111,12 @@ Transport support:
|
|
|
111
111
|
|
|
112
112
|
## Quality & Reliability
|
|
113
113
|
|
|
114
|
-
The server is continuously validated using a **comprehensive chaos test suite** that covers all
|
|
114
|
+
The server is continuously validated using a **comprehensive chaos test suite** that covers all detected MCP client types:
|
|
115
115
|
|
|
116
|
-
- **Interactive clients**: `claude_code`, `cursor`, `vscode`, `claude_desktop`, `windsurf` (auto-format: `compact`)
|
|
117
|
-
- **Non-interactive clients**: `mcp_remote`, `blackveil_dns_action`, `bv_claude_dns_proxy`, `unknown` (auto-format: `full`)
|
|
116
|
+
- **Interactive clients**: `claude_mobile`, `claude_code`, `cursor`, `vscode`, `claude_desktop`, `windsurf` (auto-format: `compact`)
|
|
117
|
+
- **Non-interactive clients**: `mcp_remote`, `blackveil_dns_action`, `bv_claude_dns_proxy`, `bv_load_test`, `unknown` (auto-format: `full`)
|
|
118
|
+
|
|
119
|
+
The `bv_load_test` class identifies internal load/chaos/tranco-scan traffic so it stays out of real-client analytics segments.
|
|
118
120
|
|
|
119
121
|
The test suite ensures session stability, authentication precedence, and transport-specific edge cases across Streamable HTTP and Legacy SSE.
|
|
120
122
|
|
|
@@ -187,6 +189,28 @@ For full hosted setup examples, stdio usage, OAuth setup, and legacy fallback en
|
|
|
187
189
|
|
|
188
190
|
---
|
|
189
191
|
|
|
192
|
+
## Example prompts
|
|
193
|
+
|
|
194
|
+
These demonstrate core functionality — paste any of them into Claude with the Blackveil DNS connector enabled:
|
|
195
|
+
|
|
196
|
+
| Prompt | What it does |
|
|
197
|
+
|--------|-------------|
|
|
198
|
+
| `Scan blackveilsecurity.com and tell me what needs fixing` | Full security audit — score, grade, prioritized findings |
|
|
199
|
+
| `Compare the email security of google.com and microsoft.com` | Side-by-side comparison of two domains' postures |
|
|
200
|
+
| `Generate a DMARC record for example.com with reject policy` | Produces a ready-to-publish DNS record |
|
|
201
|
+
| `What attack paths exist for example.com?` | Enumerates spoofing, takeover, and hijack vectors |
|
|
202
|
+
| `Map example.com's compliance against NIST 800-177` | Maps findings to compliance framework controls |
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Support
|
|
207
|
+
|
|
208
|
+
- **Bug reports & feature requests:** [GitHub Issues](https://github.com/MadaBurns/bv-mcp/issues)
|
|
209
|
+
- **Security vulnerabilities:** [security@blackveilsecurity.com](mailto:security@blackveilsecurity.com) (see [SECURITY.md](SECURITY.md))
|
|
210
|
+
- **General questions:** [GitHub Discussions](https://github.com/MadaBurns/bv-mcp/discussions)
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
190
214
|
## Responsible use
|
|
191
215
|
|
|
192
216
|
This tool is intended for **authorized security assessments** of domains you own or have explicit permission to test. Do not use it for unauthorized reconnaissance, harassment, or any activity that violates applicable laws. Findings from attack simulation, spoofability, and subdomain discovery tools should be used to **improve your own security posture**, not to exploit others.
|
package/dist/index.d.ts
CHANGED
|
@@ -192,7 +192,7 @@ declare function sanitizeDomain(input: string): string;
|
|
|
192
192
|
declare function sanitizeInput(input: string, maxLength?: number): string;
|
|
193
193
|
|
|
194
194
|
/** Server version — keep in sync with package.json */
|
|
195
|
-
declare const SERVER_VERSION = "2.
|
|
195
|
+
declare const SERVER_VERSION = "2.10.0";
|
|
196
196
|
|
|
197
197
|
/**
|
|
198
198
|
* Map of every tool name to its Zod argument schema.
|
|
@@ -296,6 +296,10 @@ declare function checkNs(domain: string, dnsOptions?: QueryDnsOptions): Promise<
|
|
|
296
296
|
* Check SPF records for a domain.
|
|
297
297
|
* Looks for v=spf1 TXT records and validates their configuration.
|
|
298
298
|
* Recursively expands include chains to compute true DNS lookup count.
|
|
299
|
+
*
|
|
300
|
+
* Top-level DNS failures (timeout, DoH HTTP error, invalid response) are
|
|
301
|
+
* converted to a high-severity finding so callers receive a structured
|
|
302
|
+
* CheckResult instead of a thrown error.
|
|
299
303
|
*/
|
|
300
304
|
declare function checkSpf(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult>;
|
|
301
305
|
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { PROFILE_WEIGHTS, buildCheckResult, createFinding, detectDomainContext, getProfileWeights, computeScanScore, scoreToGrade } from '@blackveil/dns-checks/scoring';
|
|
3
3
|
export { CATEGORY_DISPLAY_WEIGHTS, SEVERITY_PENALTIES, buildCheckResult, computeCategoryScore, computeScanScore, createFinding, detectDomainContext, getProfileWeights, inferFindingConfidence, scoreToGrade } from '@blackveil/dns-checks/scoring';
|
|
4
4
|
import * as punycode from 'punycode/';
|
|
5
|
-
import { checkBIMI, checkCAA, checkDKIM, checkDMARC, checkDNSSEC, checkMTASTS, checkMX, createFinding as createFinding$1, checkNS, checkSPF, checkSSL, checkSubdomainTakeover as checkSubdomainTakeover$1, checkTLSRPT, buildCheckResult as buildCheckResult$1, checkSubdomailing as checkSubdomailing$1, checkSVCBHTTPS, checkDANEHTTPS, checkDANE,
|
|
5
|
+
import { checkBIMI, checkCAA, checkDKIM, checkDMARC, checkDNSSEC, checkMTASTS, checkMX, createFinding as createFinding$1, checkNS, checkSPF, checkSSL, checkSubdomainTakeover as checkSubdomainTakeover$1, checkTLSRPT, buildCheckResult as buildCheckResult$1, checkSubdomailing as checkSubdomailing$1, checkSVCBHTTPS, checkDANEHTTPS, checkDANE, parseDmarcTags, checkHTTPSecurity } from '@blackveil/dns-checks';
|
|
6
6
|
export { parseDmarcTags } from '@blackveil/dns-checks';
|
|
7
7
|
import 'cloudflare:workers';
|
|
8
8
|
import 'drizzle-orm';
|
|
@@ -587,7 +587,7 @@ function sanitizeInput(input, maxLength = 500) {
|
|
|
587
587
|
}
|
|
588
588
|
|
|
589
589
|
// src/lib/server-version.ts
|
|
590
|
-
var SERVER_VERSION = "2.
|
|
590
|
+
var SERVER_VERSION = "2.10.0";
|
|
591
591
|
var DomainSchema = z.string().min(1).max(253);
|
|
592
592
|
z.string().regex(/^[0-9a-f]{64}$/);
|
|
593
593
|
var DkimSelectorSchema = z.string().transform((s) => s.trim().toLowerCase()).pipe(z.string().max(63).regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/));
|
|
@@ -2028,11 +2028,29 @@ async function checkNs(domain, dnsOptions) {
|
|
|
2028
2028
|
);
|
|
2029
2029
|
}
|
|
2030
2030
|
async function checkSpf(domain, dnsOptions) {
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2031
|
+
try {
|
|
2032
|
+
return await checkSPF(
|
|
2033
|
+
domain,
|
|
2034
|
+
makeQueryDNS(dnsOptions),
|
|
2035
|
+
{ timeout: dnsOptions?.timeoutMs ?? 5e3 }
|
|
2036
|
+
);
|
|
2037
|
+
} catch (err) {
|
|
2038
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2039
|
+
const isTimeout = /timed? out|timeout/i.test(message);
|
|
2040
|
+
return buildCheckResult("spf", [
|
|
2041
|
+
createFinding(
|
|
2042
|
+
"spf",
|
|
2043
|
+
isTimeout ? "SPF check timed out" : "SPF check could not complete",
|
|
2044
|
+
"high",
|
|
2045
|
+
isTimeout ? `DNS lookup for the domain timed out before the SPF record could be resolved: ${message}` : `DNS lookup failed before the SPF record could be resolved: ${message}`,
|
|
2046
|
+
{
|
|
2047
|
+
errorKind: isTimeout ? "timeout" : "dns_error",
|
|
2048
|
+
confidence: "heuristic",
|
|
2049
|
+
missingControl: true
|
|
2050
|
+
}
|
|
2051
|
+
)
|
|
2052
|
+
]);
|
|
2053
|
+
}
|
|
2036
2054
|
}
|
|
2037
2055
|
async function checkSsl(domain) {
|
|
2038
2056
|
return checkSSL(domain, fetch, { timeout: HTTPS_TIMEOUT_MS });
|
|
@@ -3205,7 +3223,31 @@ async function fetchBodyForWafDetection(url, timeoutMs) {
|
|
|
3205
3223
|
return "";
|
|
3206
3224
|
}
|
|
3207
3225
|
}
|
|
3226
|
+
var TOTAL_BUDGET_MS = 1e4;
|
|
3208
3227
|
async function checkHttpSecurity(domain) {
|
|
3228
|
+
let budgetTimeoutId;
|
|
3229
|
+
const budgetExceeded = new Promise((resolve) => {
|
|
3230
|
+
budgetTimeoutId = setTimeout(() => resolve("budget_exceeded"), TOTAL_BUDGET_MS);
|
|
3231
|
+
});
|
|
3232
|
+
try {
|
|
3233
|
+
const raced = await Promise.race([checkHttpSecurityInner(domain), budgetExceeded]);
|
|
3234
|
+
if (raced === "budget_exceeded") {
|
|
3235
|
+
const finding = createFinding(
|
|
3236
|
+
"http_security",
|
|
3237
|
+
"HTTP security check timed out",
|
|
3238
|
+
"high",
|
|
3239
|
+
`Could not complete HTTP security header analysis for ${domain} within ${TOTAL_BUDGET_MS}ms. Host was likely unreachable or extremely slow.`,
|
|
3240
|
+
{ missingControl: true, confidence: "heuristic", errorKind: "timeout" }
|
|
3241
|
+
);
|
|
3242
|
+
const base = buildCheckResult("http_security", [finding]);
|
|
3243
|
+
return { ...base, score: 0, passed: false, checkStatus: "timeout" };
|
|
3244
|
+
}
|
|
3245
|
+
return raced;
|
|
3246
|
+
} finally {
|
|
3247
|
+
if (budgetTimeoutId !== void 0) clearTimeout(budgetTimeoutId);
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
async function checkHttpSecurityInner(domain) {
|
|
3209
3251
|
const dualResult = await dualFetchHeaders(domain, HTTPS_TIMEOUT_MS);
|
|
3210
3252
|
if (dualResult) {
|
|
3211
3253
|
const headersForWaf = dualResult.headers;
|