Initial commit
This commit is contained in:
commit
542ebdea34
40 changed files with 4592 additions and 0 deletions
125
checker/types.go
Normal file
125
checker/types.go
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
// This file is part of the happyDomain (R) project.
|
||||
// Copyright (c) 2020-2026 happyDomain
|
||||
// Authors: Pierre-Olivier Mercier, et al.
|
||||
//
|
||||
// This program is offered under a commercial and under the AGPL license.
|
||||
// For commercial licensing, contact us at <contact@happydomain.org>.
|
||||
|
||||
// Package checker implements an HTTP/HTTPS server checker for happyDomain.
|
||||
// It probes the abstract.Server it is attached to over HTTP (80) and HTTPS
|
||||
// (443), captures response headers, cookies and the (parsed) HTML body, then
|
||||
// evaluates a set of independent rules covering reachability, the HTTP→HTTPS
|
||||
// upgrade path, modern transport-security headers (HSTS, CSP), application
|
||||
// security headers (X-Frame-Options, X-Content-Type-Options, X-XSS-Protection)
|
||||
// and Subresource Integrity. Deep TLS / certificate analysis is intentionally
|
||||
// delegated to checker-tls.
|
||||
package checker
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
const ObservationKeyHTTP = "http"
|
||||
|
||||
const (
|
||||
OptionService = "service"
|
||||
OptionProbeTimeoutMs = "probeTimeoutMs"
|
||||
OptionMaxRedirects = "maxRedirects"
|
||||
OptionUserAgent = "userAgent"
|
||||
OptionRequireHTTPS = "requireHTTPS"
|
||||
OptionRequireHSTS = "requireHSTS"
|
||||
OptionMinHSTSMaxAgeDays = "minHSTSMaxAgeDays"
|
||||
OptionRequireCSP = "requireCSP"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultHTTPPort uint16 = 80
|
||||
DefaultHTTPSPort uint16 = 443
|
||||
DefaultProbeTimeoutMs = 10000
|
||||
DefaultMaxRedirects = 5
|
||||
DefaultUserAgent = "happyDomain-checker-http/1.0"
|
||||
DefaultMinHSTSMaxAge = 180 // days; 180d ≈ 15552000s, the commonly recommended minimum
|
||||
MaxConcurrentProbes = 8
|
||||
MaxBodyBytes = 1 << 20 // 1 MiB cap on HTML body to keep memory bounded
|
||||
)
|
||||
|
||||
// HTTPData is the full collected payload written under ObservationKeyHTTP.
|
||||
//
|
||||
// Probes/Domain/CollectedAt come from the root collector and are kept at
|
||||
// the top level for backward compatibility with the rules that have
|
||||
// always read them directly.
|
||||
//
|
||||
// Extensions holds the JSON-encoded outputs of every additional Collector
|
||||
// registered via RegisterCollector, keyed by Collector.Key(). Rules
|
||||
// access them via LoadExtension[T] to get a typed view.
|
||||
type HTTPData struct {
|
||||
Domain string `json:"domain,omitempty"`
|
||||
Probes []HTTPProbe `json:"probes"`
|
||||
CollectedAt time.Time `json:"collected_at"`
|
||||
|
||||
Extensions map[string]json.RawMessage `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPProbe is the outcome of a single (scheme, ip, port) probe.
|
||||
type HTTPProbe struct {
|
||||
Scheme string `json:"scheme"` // "http" or "https"
|
||||
Host string `json:"host"`
|
||||
IP string `json:"ip,omitempty"`
|
||||
Port uint16 `json:"port"`
|
||||
Address string `json:"address"`
|
||||
IsIPv6 bool `json:"ipv6,omitempty"`
|
||||
|
||||
TCPConnected bool `json:"tcp_connected"`
|
||||
ElapsedMS int64 `json:"elapsed_ms,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
|
||||
// Final response after following redirects (if any).
|
||||
StatusCode int `json:"status_code,omitempty"`
|
||||
FinalURL string `json:"final_url,omitempty"`
|
||||
Headers map[string]string `json:"headers,omitempty"`
|
||||
Cookies []CookieInfo `json:"cookies,omitempty"`
|
||||
RedirectChain []RedirectStep `json:"redirect_chain,omitempty"`
|
||||
|
||||
// Parsed HTML resource references (only populated for the primary
|
||||
// HTTPS probe, to keep payloads small).
|
||||
Resources []HTMLResource `json:"resources,omitempty"`
|
||||
HTMLBytes int `json:"html_bytes,omitempty"`
|
||||
BodyTruncated bool `json:"body_truncated,omitempty"`
|
||||
}
|
||||
|
||||
// RedirectStep records one hop of a redirect chain.
|
||||
type RedirectStep struct {
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
Status int `json:"status"`
|
||||
}
|
||||
|
||||
// CookieInfo summarises one Set-Cookie header.
|
||||
type CookieInfo struct {
|
||||
Name string `json:"name"`
|
||||
Domain string `json:"domain,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
Secure bool `json:"secure"`
|
||||
HttpOnly bool `json:"http_only"`
|
||||
SameSite string `json:"same_site,omitempty"` // "Strict", "Lax", "None", or ""
|
||||
HasExpiry bool `json:"has_expiry,omitempty"`
|
||||
}
|
||||
|
||||
// HTMLResource is a <script src=...> or <link href=...> reference extracted
|
||||
// from the HTML body, used to evaluate Subresource Integrity coverage.
|
||||
type HTMLResource struct {
|
||||
Tag string `json:"tag"` // "script" or "link"
|
||||
URL string `json:"url"`
|
||||
CrossOrigin bool `json:"cross_origin"`
|
||||
Integrity string `json:"integrity,omitempty"`
|
||||
Rel string `json:"rel,omitempty"`
|
||||
}
|
||||
|
||||
// Severity levels used internally by rules.
|
||||
const (
|
||||
SeverityCrit = "crit"
|
||||
SeverityWarn = "warn"
|
||||
SeverityInfo = "info"
|
||||
SeverityOK = "ok"
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue