Seven detections, all under the free tier. The line Joe and I settled on is scope rather than capability: an individual protecting their own machine gets every check at full depth, and what is sold is the same protection made continuous, enforced, and shared across a team. **Containers.** The Docker socket is the one that matters. Mounting /var/run/docker.sock into a container is not access to Docker, it is root on the host — anything that can talk to that socket can start a privileged container with the host filesystem mounted — and the explanation says exactly that. Also privileged: true, host networking, bind mounts of /, /etc, ~/.ssh and ~/.aws, secrets baked into image layers (with the part people learn too late: docker history keeps them after a later instruction deletes them), curl piped into a shell during a build nobody watches, ADD from a URL, running as root, and COPY . . with no .dockerignore shipping the .env and the whole .git directory into a published image. **Disabled certificate checking**, across nine ecosystems. Reported as a warning rather than a critical because it is often deliberate, and skipped entirely in test files — turning verification off in a fixture is normal, and flagging it there is how a check gets switched off wholesale. The explanation leads with the trap: the connection still looks encrypted. **Prompt injection inside dependencies.** Hound already read the project's own CLAUDE.md; an assistant working in a repository reads far more than that, including the README of every package it touches. All of that is attacker-controlled text, and publishing a package whose README addresses the assistant instead of the reader costs nothing to try. The finding names the package, including scoped ones, and resolves nested dependencies to the innermost package — the one that actually shipped the file. An injected instruction file inside a dependency used to produce two findings, one from each check. It reports once now, as the dependency finding: "the package awesome-agents ships an injection" is something a person can act on, and "there is an injection in this file" is not. **CI beyond GitHub** — GitLab, Jenkins, CircleCI, Bitbucket, Azure, Drone. The GitLab equivalent of pull_request_target requires both merge request pipelines and a protected-variable reference before it reports; merge request pipelines alone are how everybody uses GitLab, and flagging them would fire on nearly every project. Also adds crates/hound-api/src/license.rs: an entitlement check so nothing ships untiered by accident. It does not try to stop anybody — the binary is Apache-2.0 and the check can be deleted — and there is no phone-home, so a machine with no network still knows what it bought and we never learn where our software runs. An expired licence falls back to Free rather than failing closed: somebody whose card lapsed must not end up with less protection than a stranger who installed Hound this morning, and there is a test for it. Every message about an absent capability has to name what still works, which is also tested. 466 tests pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
31 lines
817 B
TOML
31 lines
817 B
TOML
[workspace]
|
|
resolver = "2"
|
|
members = ["crates/*"]
|
|
|
|
[workspace.package]
|
|
version = "0.1.9"
|
|
edition = "2021"
|
|
license = "MIT"
|
|
repository = "https://git.joelovestech.com/Hound/Antivirus.git"
|
|
|
|
[workspace.dependencies]
|
|
hound-supply = { path = "crates/hound-supply" }
|
|
anyhow = "1"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
clap = { version = "4", features = ["derive"] }
|
|
colored = "2"
|
|
time = { version = "0.3", features = ["serde", "std", "formatting"] }
|
|
inotify = "0.10"
|
|
yara-x = "1.19"
|
|
libc = "0.2"
|
|
sha2 = "0.10"
|
|
ed25519-dalek = { version = "2", features = ["rand_core"] }
|
|
ureq = { version = "2", default-features = false, features = ["tls", "gzip"] }
|
|
hound-defs = { path = "crates/hound-defs" }
|
|
hound-mcp = { path = "crates/hound-mcp" }
|
|
|
|
[profile.release]
|
|
lto = true
|
|
strip = true
|
|
codegen-units = 1
|