infrastructure tier

infrastructure-web-security-audit

Website security-configuration auditor implementing foundation-web-analysis::Analyzer -- TLS/certificate validity, HTTP security headers, DNS/SPF/DMARC/CAA record correctness, and exposed-path/WordPress/cookie/open-port checks against a standard

Website security-configuration auditor implementing foundation-web-analysis::Analyzer -- TLS/certificate validity, HTTP security headers, DNS/SPF/DMARC/CAA record correctness, and exposed-path/WordPress/cookie/open-port checks against a standard

Tierinfrastructure
Roleunclassified (baselined)
Pathcrates/infrastructure/web-security-audit
Edition2021
Targetsinfrastructure_web_security_audit
Public items62 across 3 modules
Tests142

What it is for

# infrastructure-web-security-audit

Website security-configuration auditor implementing foundation_web_analysis::Analyzer. Audits a website's TLS/certificate validity and HTTP security headers (tls_headers), DNS/SPF/DMARC/CAA record correctness (dns_email), and exposed sensitive paths/WordPress fingerprinting/cookie flags/open dangerous ports (exposed_paths) against a fixed standard, then derives a 0-100 score per concern plus an overall weighted score.

Lifted from plumber/src/analyzers/security_scanner.rs (sprint 3.46, wave 3 -- see CHANGELOG.md for full provenance). One crate, three internal check modules -- decided by Gate 1.5 Round 1's unanimous 4-seat consensus (docs/userstories/sprint-3.46-plumber-harvest.md): lift the source's coupled sequential analyze() path as-is, with module boundaries drawn now so a later crate-level split is mechanical, rather than inventing crate architecture mid-harvest.

A fourth module the sprint doc proposed, scheduling_alerting (scheduled-scan orchestration, alerting, scan-diff comparison), is a non-goal of this crate -- see the CHANGELOG.md "OQ6" entry for the traced evidence: it has zero callers anywhere in the source, including the source's own scan()/Analyzer::analyze() path, so the three check modules below are everything this crate needs to work identically to the source.

Naming

This crate's own name and this file's is deliberate: it audits configuration against a standard (TLS validity, header presence, DNS record correctness, cookie flags) -- infrastructure-security-scan/ tools-net-probe already own "scan"/"probe" for genuine network-liveness mechanisms, so this crate never uses "scan" in its public API even though its source used it throughout (SecurityScanner -> SecurityAuditor, SecurityScanResult -> SecurityAuditResult, scan() -> SecurityAuditor::audit).

Capabilities

crate root

# infrastructure-web-security-audit

Item
pub const DEFAULT_MAX_HEADERS_PROBE_BYTES: usize

IssueCategory

# infrastructure-web-security-audit

Item
pub enum IssueCategory

SecurityAuditResult

# infrastructure-web-security-audit

Item
pub struct SecurityAuditResult
SecurityAuditResult :: fn new(organization_id : Uuid, domain : & str, url : & str) -> Self
SecurityAuditResult :: fn add_issue(& mut self, issue : SecurityIssue)
SecurityAuditResult :: fn calculate_scores(& mut self)

SecurityAuditor

# infrastructure-web-security-audit

Item
pub struct SecurityAuditor
SecurityAuditor :: fn new() -> std::result::Result <Self, infrastructure_fetcher::SafeHttpError>
SecurityAuditor :: fn with_tls_timeout(mut self, timeout : Duration) -> Self
SecurityAuditor :: async fn audit(& self, url : & str) -> std::result::Result <SecurityAuditResult, String>
SecurityAuditor :: fn default() -> Self
SecurityAuditor :: fn name(& self) -> & 'static str
SecurityAuditor :: async fn analyze(& self, organization_id : Uuid, website_url : & str) -> Result <AnalysisResult>
SecurityAuditor :: fn cache_ttl_days(& self) -> u32

SecurityIssue

# infrastructure-web-security-audit

Item
pub struct SecurityIssue

Severity

# infrastructure-web-security-audit

Item
pub enum Severity

CaaRecord

DNS-security (nameservers, DNSSEC, CAA, IPv6) and email-authentication

Item
pub struct CaaRecord

DmarcPolicy

DNS-security (nameservers, DNSSEC, CAA, IPv6) and email-authentication

Item
pub enum DmarcPolicy

DnsCheckResult

DNS-security (nameservers, DNSSEC, CAA, IPv6) and email-authentication

Item
pub struct DnsCheckResult
fn calculate_dns_score(dns : & DnsCheckResult) -> u8
async fn check_dns(resolver : & TokioResolver, domain : & str) -> DnsCheckResult
fn generate_dns_issues(dns : & DnsCheckResult) -> Vec <SecurityIssue>

EmailCheckResult

DNS-security (nameservers, DNSSEC, CAA, IPv6) and email-authentication

Item
pub struct EmailCheckResult
fn calculate_email_score(email : & EmailCheckResult) -> u8
async fn check_email(resolver : & TokioResolver, domain : & str) -> EmailCheckResult
fn generate_email_issues(email : & EmailCheckResult) -> Vec <SecurityIssue>

SpfPolicy

DNS-security (nameservers, DNSSEC, CAA, IPv6) and email-authentication

Item
pub enum SpfPolicy

exposed_paths (other)

Exposed sensitive-path/WordPress-fingerprint, cookie-flag, and

Item
pub const DANGEROUS_PORTS: & (u16, & str, Severity)
pub const DEFAULT_PROBE_TIMEOUT: Duration
pub const DEFAULT_PORT_TIMEOUT: Duration
pub const DEFAULT_MAX_README_BYTES: usize
fn extract_wp_version_from_readme(html : & str) -> Option <String>

CookieCheckResult

Exposed sensitive-path/WordPress-fingerprint, cookie-flag, and

Item
pub struct CookieCheckResult
fn calculate_cookies_score(cookies : & CookieCheckResult) -> u8
async fn check_cookies(http : & SafeHttpClient, url : & str) -> CookieCheckResult
fn generate_cookie_issues(cookies : & CookieCheckResult) -> Vec <SecurityIssue>

CookieInfo

Exposed sensitive-path/WordPress-fingerprint, cookie-flag, and

Item
pub struct CookieInfo
fn parse_cookie(cookie_str : & str) -> Option <CookieInfo>

ExposedPath

Exposed sensitive-path/WordPress-fingerprint, cookie-flag, and

Item
pub struct ExposedPath

ExposedPathCategory

Exposed sensitive-path/WordPress-fingerprint, cookie-flag, and

Item
pub enum ExposedPathCategory
pub const SENSITIVE_PATHS: & (& str, ExposedPathCategory, Severity)

ExposedPathsCheckResult

Exposed sensitive-path/WordPress-fingerprint, cookie-flag, and

Item
pub struct ExposedPathsCheckResult
async fn check_exposed_paths(http : & SafeHttpClient, base_url : & str) -> ExposedPathsCheckResult
fn generate_exposed_paths_issues(exposed : & ExposedPathsCheckResult) -> Vec <SecurityIssue>

PortCheckResult

Exposed sensitive-path/WordPress-fingerprint, cookie-flag, and

Item
pub struct PortCheckResult
async fn check_ports(resolver : & TokioResolver, domain : & str) -> PortCheckResult
fn generate_port_issues(ports : & PortCheckResult) -> Vec <SecurityIssue>

PortInfo

Exposed sensitive-path/WordPress-fingerprint, cookie-flag, and

Item
pub struct PortInfo

SameSitePolicy

Exposed sensitive-path/WordPress-fingerprint, cookie-flag, and

Item
pub enum SameSitePolicy

TechnologyCheckResult

Exposed sensitive-path/WordPress-fingerprint, cookie-flag, and

Item
pub struct TechnologyCheckResult

WordPressCheckResult

Exposed sensitive-path/WordPress-fingerprint, cookie-flag, and

Item
pub struct WordPressCheckResult
async fn check_wordpress(http : & SafeHttpClient, base_url : & str,) -> Option <WordPressCheckResult>
fn generate_wordpress_issues(wordpress : Option <& WordPressCheckResult>) -> Vec <SecurityIssue>

tls_headers (other)

TLS/certificate validity and HTTP security-header checks.

Item
pub const DEFAULT_TLS_TIMEOUT: Duration
fn generate_issues(ssl : & SslCheckResult, headers : & HeadersCheckResult) -> Vec <SecurityIssue>

HeadersCheckResult

TLS/certificate validity and HTTP security-header checks.

Item
pub struct HeadersCheckResult
fn calculate_headers_score(h : & HeadersCheckResult) -> u8
fn parse_security_headers(headers : & HeaderMap) -> HeadersCheckResult
async fn check_headers(http : & SafeHttpClient, url : & Url, max_body_bytes : usize,) -> Result <HeadersCheckResult>

SslCheckResult

TLS/certificate validity and HTTP security-header checks.

Item
pub struct SslCheckResult
fn calculate_ssl_score(ssl : & SslCheckResult) -> u8
async fn check_ssl(resolver : & TokioResolver, domain : & str, timeout : Duration,) -> SslCheckResult

How to use it

No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.

Module structure

infrastructure_web_security_audit

flowchart TD
  n_infrastructure_web_security_audit["infrastructure_web_security_audit"]
  n_infrastructure_web_security_audit --> n_dns_email["dns_email"]
  n_infrastructure_web_security_audit --> n_exposed_paths["exposed_paths"]
  n_infrastructure_web_security_audit --> n_tls_headers["tls_headers"]

Public surface

`crate root`

ItemWhat it is
pub struct SecurityIssueSecurity issue found during an audit.
pub enum IssueCategoryCategory shared across all three check modules -- not owned by any one of them, so it lives at the crate root.
pub enum Severity
pub struct SecurityAuditResultSecurity audit result: per-concern check results, 0-100 scores, and the flattened issue list with severity counts
SecurityAuditResult :: fn new(organization_id : Uuid, domain : & str, url : & str) -> Self
SecurityAuditResult :: fn add_issue(& mut self, issue : SecurityIssue)
SecurityAuditResult :: fn calculate_scores(& mut self)Recompute every per-concern score plus Self::overall_score from the current check results and issue counts
pub const DEFAULT_MAX_HEADERS_PROBE_BYTES: usizeDefault per-fetch byte cap for the headers-check probe body drain (Gate 1.5.6 input limit) -- only headers are consumed, so this bounds a misbehaving/oversized response rather than sizing real content.
pub struct SecurityAuditorSecurity-configuration auditor: TLS/certificate validity, HTTP security headers, DNS/SPF/DMARC/CAA correctness, and exposed-path/WordPress/ cookie/open-port checks against a fixed standard
SecurityAuditor :: fn new() -> std::result::Result <Self, infrastructure_fetcher::SafeHttpError>Build an auditor with the default TLS timeout (tls_headers::DEFAULT_TLS_TIMEOUT) and headers-probe byte cap (DEFAULT_MAX_HEADERS_PROBE_BYTES).
SecurityAuditor :: fn with_tls_timeout(mut self, timeout : Duration) -> SelfOverride the TCP-connect + TLS-handshake timeout used by tls_headers::check_ssl.
SecurityAuditor :: async fn audit(& self, url : & str) -> std::result::Result <SecurityAuditResult, String>Run every check across the three modules against url, generate issues from each, and compute scores
SecurityAuditor :: fn default() -> Self# Panics Panics if the underlying SafeHttpClient cannot be built (TLS backend init failure) -- matches infrastructure-web-domain-intel's expect-on-construction Default impl.
SecurityAuditor :: fn name(& self) -> & 'static str
SecurityAuditor :: async fn analyze(& self, organization_id : Uuid, website_url : & str) -> Result <AnalysisResult>
SecurityAuditor :: fn cache_ttl_days(& self) -> u32

`dns_email`

ItemWhat it is
pub struct DnsCheckResultDNS security check results.
pub struct CaaRecordCAA (Certificate Authority Authorization) record.
pub struct EmailCheckResultEmail security check results (SPF, DKIM, DMARC).
pub enum SpfPolicy
pub enum DmarcPolicy
fn calculate_dns_score(dns : & DnsCheckResult) -> u8Compute the 0-100 DNS-security score from a DnsCheckResult.
fn calculate_email_score(email : & EmailCheckResult) -> u8Compute the 0-100 email-authentication score from an EmailCheckResult.
async fn check_dns(resolver : & TokioResolver, domain : & str) -> DnsCheckResult
async fn check_email(resolver : & TokioResolver, domain : & str) -> EmailCheckResultCheck MX presence and SPF/DMARC/DKIM records for domain's mail setup.
fn generate_dns_issues(dns : & DnsCheckResult) -> Vec <SecurityIssue>Generate SecurityIssues from the DNS check result.
fn generate_email_issues(email : & EmailCheckResult) -> Vec <SecurityIssue>Generate SecurityIssues from the email check result.

`exposed_paths`

ItemWhat it is
pub struct ExposedPathsCheckResultExposed paths/files check results.
pub struct ExposedPathAn exposed sensitive path or file.
pub enum ExposedPathCategory
pub struct TechnologyCheckResultTechnology/CMS-specific check results.
pub struct WordPressCheckResultWordPress-specific security checks.
pub struct CookieCheckResultCookie security check results.
pub struct CookieInfoInformation about a cookie's security properties.
pub enum SameSitePolicy
pub struct PortCheckResultPort scan check results.
pub struct PortInfoInformation about an open port.
pub const SENSITIVE_PATHS: & (& str, ExposedPathCategory, Severity)Paths to check for exposed sensitive files.
pub const DANGEROUS_PORTS: & (u16, & str, Severity)Common dangerous ports to check.
pub const DEFAULT_PROBE_TIMEOUT: DurationPer-request timeout used by the exposed-path/WordPress HEAD/GET probes (matches the source's own 5s per-request timeout).
pub const DEFAULT_PORT_TIMEOUT: DurationPer-port TCP connect timeout used by check_ports (matches the source's own 2s timeout).
pub const DEFAULT_MAX_README_BYTES: usizeResponse body byte cap applied when reading readme.html to extract a WordPress version string (Gate 1.5.6 input limit) -- generous headroom for a small static HTML file.
fn calculate_cookies_score(cookies : & CookieCheckResult) -> u8Compute the 0-100 cookie-security score from a CookieCheckResult.
fn parse_cookie(cookie_str : & str) -> Option <CookieInfo>Parse a Set-Cookie header value into CookieInfo
fn extract_wp_version_from_readme(html : & str) -> Option <String>Extract a WordPress version string ("Version X.X.X") from readme.html's body.
async fn check_exposed_paths(http : & SafeHttpClient, base_url : & str) -> ExposedPathsCheckResultHEAD each of SENSITIVE_PATHS against base_url and record any that respond 200/301/302 (403 means "exists but blocked" -- deliberately not counted as exposed; 404 means not found, which is good)
async fn check_wordpress(http : & SafeHttpClient, base_url : & str,) -> Option <WordPressCheckResult>Probe xmlrpc.php, the wp-json users endpoint, readme.html, and wp-content/debug.log for WordPress-specific exposure
async fn check_cookies(http : & SafeHttpClient, url : & str) -> CookieCheckResultFetch url and parse its Set-Cookie response headers.
async fn check_ports(resolver : & TokioResolver, domain : & str) -> PortCheckResultTCP-connect-probe each of DANGEROUS_PORTS against domain
fn generate_cookie_issues(cookies : & CookieCheckResult) -> Vec <SecurityIssue>Generate SecurityIssues from the cookie check result.
fn generate_port_issues(ports : & PortCheckResult) -> Vec <SecurityIssue>Generate SecurityIssues from the port check result.
fn generate_exposed_paths_issues(exposed : & ExposedPathsCheckResult) -> Vec <SecurityIssue>Generate SecurityIssues from the exposed-paths check result.
fn generate_wordpress_issues(wordpress : Option <& WordPressCheckResult>) -> Vec <SecurityIssue>Generate SecurityIssues from the WordPress check result.

`tls_headers`

ItemWhat it is
pub struct SslCheckResultSSL/TLS check results.
pub struct HeadersCheckResultHTTP security-headers check results.
pub const DEFAULT_TLS_TIMEOUT: DurationDefault TCP connect + TLS handshake timeout for check_ssl.
fn calculate_ssl_score(ssl : & SslCheckResult) -> u8Compute the 0-100 SSL/TLS score from a SslCheckResult
fn calculate_headers_score(h : & HeadersCheckResult) -> u8Compute the 0-100 HTTP security-headers score from a HeadersCheckResult.
fn parse_security_headers(headers : & HeaderMap) -> HeadersCheckResultParse the security-relevant subset of a response's headers.
fn generate_issues(ssl : & SslCheckResult, headers : & HeadersCheckResult) -> Vec <SecurityIssue>Generate SecurityIssues from the SSL and headers check results.
async fn check_ssl(resolver : & TokioResolver, domain : & str, timeout : Duration,) -> SslCheckResultFetch and inspect the peer TLS certificate for domain:443
async fn check_headers(http : & SafeHttpClient, url : & Url, max_body_bytes : usize,) -> Result <HeadersCheckResult>Fetch url and parse its response's security headers, through SafeHttpClient's pinned-resolver egress guard

Re-exports. Exported here, defined elsewhere.

ExportDefined in
{CaaRecord,DmarcPolicy,DnsCheckResult,EmailCheckResult,SpfPolicy}dns_email::{CaaRecord,DmarcPolicy,DnsCheckResult,EmailCheckResult,SpfPolicy}
{CookieCheckResult,CookieInfo,ExposedPath,ExposedPathCategory,ExposedPathsCheckResult,PortCheckResult,PortInfo,SameSitePolicy,TechnologyCheckResult,WordPressCheckResult,}exposed_paths::{CookieCheckResult,CookieInfo,ExposedPath,ExposedPathCategory,ExposedPathsCheckResult,PortCheckResult,PortInfo,SameSitePolicy,TechnologyCheckResult,WordPressCheckResult,}
{HeadersCheckResult,SslCheckResult}tls_headers::{HeadersCheckResult,SslCheckResult}

Boundary

Reaches into foundation.

Shares tier infrastructure with 82 other crates: infrastructure-acquire, infrastructure-adapters-google-calendar, infrastructure-adapters-google-gmail, infrastructure-adapters-google-places, infrastructure-adapters-google-trends, infrastructure-adapters-shodan, infrastructure-adapters-yelp, infrastructure-agent, … (82 total).

_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._

Where it sits

Tier (ontology)infrastructure
Architectural role (taxonomy)unclassified (baselined)
Locationcrates/infrastructure/web-security-audit
Vocabulary in force (lexicon)current

Tier flow. Which tiers this crate's own edges cross.

flowchart LR
  n_infrastructure["infrastructure"] --> n_foundation["foundation"]

Dependencies

Runtime, in this workspace.

CrateTierOptionalOnly on
`foundation-web-analysis`foundationnoalways
`infrastructure-fetcher`infrastructurenoalways

Runtime, from outside the workspace.

CrateRequirementFeaturesOptionalOnly on
async-trait^0.1noalways
chrono^0.4serdenoalways
hickory-resolver^0.26noalways
regex^1noalways
reqwest^0.12json, rustls-tls, streamnoalways
rustls^0.23ringnoalways
serde^1derivenoalways
serde_json^1noalways
thiserror^2noalways
tokio^1fullnoalways
tracing^0.1noalways
url^2noalways
uuid^1v4, v7, serde, jsnoalways
webpki-roots^0.26noalways
x509-parser^0.16noalways

Development, from outside the workspace.

CrateRequirementFeaturesOptionalOnly on
tokio^1full, full, test-utilnoalways
tokio-test^0.4noalways

Build. None.

Depended on by. Nothing in this workspace.

Signal flow — what reaches this crate, and what it reaches.

flowchart LR
  SELF["infrastructure-web-security-audit"]
  SELF -->|runtime| n_foundation_web_analysis["foundation-web-analysis"]
  SELF -->|runtime| n_infrastructure_fetcher["infrastructure-fetcher"]
  classDef self fill:#1f883d,stroke:#1f883d,color:#fff;
  class SELF self;

Feature flags

No Cargo features are defined: every capability is unconditional, so no consumer can receive a half-wired crate.

Targets

KindNameSource
libinfrastructure_web_security_audit`src/lib.rs`

Error model

No public error type was detected: no public item declares a type named *Error, and no public signature returns one.

Operational characteristics

PropertyEvidence
async public surfaceyes
async runtimeyes
database accessnone detected
network I/Oyes
unsafe codenone detected
environment variablesnone detected

No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.

Configuration

No environment variable is read with a literal name anywhere in this crate. A variable whose key is computed at run time cannot be listed here, and is not claimed to be absent.

No workspace crate depends on this one.

Verification

KindCount
Unit tests142
Integration tests0
Examples0
Doctests0

Evidence by module. How often each public module is named by something executable.

ModuleTestsExamplesConsumers
crate root600
dns_email1100
exposed_paths2600
tls_headers900

What the tests establish, by name:

Documentation coverage

MeasureDocumentedTotal
Public items with rustdoc5162
Public modules with a //! block33
pie showData
    title Public items with rustdoc
    "Documented" : 51
    "No rustdoc detected" : 11

Metrics

MetricValue
Rust source files4
Source lines4382
Code lines3663
Public API items62
Public modules3
Tests142
Examples0
Cargo features0
Direct runtime dependencies17
Workspace reverse dependencies0
pie showData
    title Public API by kind
    "constant" : 7
    "enum" : 6
    "function" : 23
    "method" : 10
    "struct" : 16
pie showData
    title Rust source composition
    "Code" : 3663
    "Blank or comment" : 719

Generation

Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.

All infrastructure · Manual