Commit Graph

3 Commits

Author SHA1 Message Date
CarterPerez-dev 998b5268e0 fix: close audit-pass-1 MAJOR systemic findings (Findings 7-13)
Brings the older pre-ML modules up to the same standard as the
newer ML pipeline. Closes Findings 7 (file headers), 8 (inline
comments), 9 (NIH reimplementations), 11 (selectWeightedRR partial
function + O(n^2)), 12 (weak LoadBalancer tests), 13 (placeholder
Backend / ConnLimit tests), and 32 (locally-redefined HTTP status
constants).

Module rewrites with new file header + zero inline comments:
- src/Aenebris/Proxy.hs
- src/Aenebris/LoadBalancer.hs
- src/Aenebris/HealthCheck.hs
- src/Aenebris/Middleware/Security.hs
- src/Aenebris/Middleware/Redirect.hs
- src/Aenebris/Config.hs
- src/Aenebris/Backend.hs
- app/Main.hs

Algorithmic + structural fixes:
- LoadBalancer.selectWeightedRR no longer uses partial (!!) and a
  separate find/maximum/index pass; replaced with a single STM fold
  that tags each backend with its current weight and picks via
  Data.List.maximumBy + Data.Ord.comparing. O(n) instead of O(n^2),
  no Maybe fallback.
- Proxy.proxyApp deduplicates the regular-HTTP code path that was
  copy-pasted across the WebSocket and `_` connection-type branches
  (Finding 16). Single forwardRegular helper called from both.
- Proxy.logRequest removed; per-request stdout logging was
  inconsistent with the stderr error pattern used elsewhere and a
  perf hazard at scale (Finding 17). Defer real structured logging
  to Phase 4 per docs/status/MASTER_PLAN_2026.md.
- Backend.recordFailure now increments rbTotalFailures uniformly
  across all states (Finding 22), not just Unhealthy.
- Backend.Show instance now includes weight (Finding 21).
- Connection.hs gains microsPerSecond and httpOkStatusCode named
  constants. tcUpstreamReadSeconds added to TimeoutConfig.
- HealthCheck uses the shared microsPerSecond constant instead of
  inline 1000000 (Finding 18). Compares status against the named
  httpOkStatusCode constant.

NIH reimplementations replaced with stdlib:
- LoadBalancer: filterM, forM_ from Control.Monad; minimumBy,
  maximumBy from Data.List; comparing from Data.Ord.
- Proxy: zipWithM from Control.Monad.
- HealthCheck: zipWithM_ from Control.Monad.
- Middleware.Security: catMaybes from Data.Maybe.
- Config: nub from Data.List (replaces local nubText).
- Fingerprint.JA4H, ML.Features: built-in lookup over
  [(CI ByteString, ByteString)] (CI ByteString already has Eq).
- RateLimit, DDoS.ConnLimit: intercalate ":" from Data.List
  (replaces duplicated joinColons in two files).
- Honeypot: status200, status404 from Network.HTTP.Types (drops
  local mkStatus duplications).
- WAF.Engine: status403 from Network.HTTP.Types.

Test strengthening (test/Spec.hs):
- loadBalancerSpec: round-robin now asserts even distribution
  ([3,3,3] across 3 backends in 9 rounds); weighted RR asserts the
  4-weight backend wins >= 35 of 50 picks; least-connections asserts
  the lower-count backend is selected after manually bumping the
  other to 5 active connections.
- backendSpec: "tolerates repeated failures" replaced with a real
  state-transition test ('Healthy after 1 failure, Healthy after 2,
  Unhealthy after 3'). 'records successes without crashing'
  replaced with assertion that recordSuccess on Healthy resets
  rbConsecutiveFailures to 0.
- connLimitSpec: 'release decrements counter' now reads
  currentCount before and after release to assert the count
  actually went 1 -> 0.

Build clean, 358 examples passing, 0 failures, 0 GHC warnings on
any touched module. Audit findings 14, 15, 18 (residual MAJOR) and
19-31 (MINOR) deferred to subsequent passes.
2026-04-29 02:12:00 -04:00
CarterPerez-dev 2c7e743f57 fix: close audit-pass-1 CRITICAL findings (Findings 1-6)
Closes the six CRITICAL findings from the 2026-04-29 audit:

- Tunnel.hs (Findings 1+2+4):
  - connectToBackend now returns Either ConnectError Socket with
    proper handling of resolution failures, connect timeouts, and
    connect errors. Replaces the partial `error` call.
  - parseUpgradeStatus uses safe pattern matching on BS8.lines
    rather than `head $ BS8.lines` (closes the -Wx-partial warning).
  - receiveUpgradeResponse is bounded at 16 KB and uses a tight
    inner loop with strict accumulator (closes the unbounded-read
    DoS). Adds a 30s timeout via System.Timeout.timeout.
  - Adds attemptConnect with bracketOnError to ensure socket is
    closed on partial-failure paths.
  - File header + remove inline comments.

- TLS.hs (Findings 1+15):
  - loadCredentials replaced with credentialsOrDefault that
    returns empty credentials and logs to stderr on failure
    rather than crashing the SNI handler with `error`.
  - Cipher names updated to non-deprecated forms
    (cipher13_AES_128_GCM_SHA256 etc.) to clear -Wdeprecations.
  - File header + remove inline comments.

- Connection.hs (supporting Finding 3):
  - File header + add microsPerSecond and httpOkStatusCode named
    constants. Add tcUpstreamReadSeconds (default 30) to
    TimeoutConfig.

- Proxy.hs (Findings 1+3):
  - All five `error` calls replaced with hPutStrLn stderr +
    exitFailure (matching Main.hs's pattern).
  - forwardRequest wraps withResponse in System.Timeout.timeout
    sized off Connection.tcUpstreamReadSeconds. Returns 504 when
    upstream does not respond within budget.

- Main.hs (supporting Finding 3):
  - HTTP client Manager now configured with managerResponseTimeout
    set to tcUpstreamReadSeconds * microsPerSecond. Belt-and-
    suspenders with the application-layer timeout in Proxy.hs.

- ML/Loader.hs (Finding 5):
  - Added maxNumLeaves (4096) and maxNumTrees (10000) constants.
  - finalizeTree rejects num_leaves <= 0 and num_leaves > maxNumLeaves
    BEFORE allocating SoA arrays. Closes a crafted-model-file DoS.
  - runTrees threads a tree counter and rejects when the parsed
    count would exceed maxNumTrees.

- WAF/Rule.hs (Finding 6):
  - CompiledRegex changed from newtype to data with an extra
    !ByteString field carrying the original pattern.
  - Eq instance now compares by stored pattern bytes; reflexivity
    holds (x == x is True). Show instance now reveals the pattern
    for debugging.

- test/Spec.hs:
  - +2 WAF tests verifying Eq CompiledRegex reflexivity and
    pattern-distinguishing.
  - +2 ML.Loader tests verifying num_leaves bound rejection
    (above maxNumLeaves and at zero).

358 total examples passing, 0 failures, 0 GHC warnings on touched
modules. Audit findings 7-32 (MAJOR systemic + remaining MAJOR +
MINOR) are deferred to subsequent passes per the audit plan.
2026-04-29 01:59:36 -04:00
CarterPerez-dev 9397b12a4a add learn folder, move hidden files, update root readme, add learn folder, add clang tidy, and format 2026-02-26 00:38:55 -05:00