A self-hosted web scanner that shows you how both people and bots see your websites & web applications.
| Type | Dependencies | Status | Description |
|---|---|---|---|
| Domain | rdapper, whois, subfinder | ✅ | Gets basic domain info (e.g. registrar, registration/expiry dates, etc) & records |
| Probe | httpx | ✅ | Gets basic info about the web server, and the tech stack |
| SEO | @seomator/seo-audit, playwright | ✅ | TypeScript-based SEO audit and scoring across 251 rules in 20 categories |
| SSL | - | ✅ | Uses node:tls to get basic certificate info |
| WCAG | @axe-core/playwright, playwright | ✅ | Check against Web Accessibility rules (also takes a full-height screenshot) |
| Whois | whois | ✅ | Gets IP whois info |
| Security | nuclei, wapiti, nikto | ✅ | Standard vulnerability scanning |
| Stress Test | vegeta | ✅ | HTTP load testing |
A Sveltekit dashboard is in beta. The main functionality is:
- CRUD for users/websites/jobs
- Website verification instructions and verification checks
- View scan results
All the dashboard functionality is available through OpenAPI.
Apprise is now integrated for notification messages and emails.
Invite/forgot flows use NOTIFICATION_EMAIL_TARGET_TEMPLATE as the delivery target.
User-level notification targets are stored in users.notification_targets for in-app managed channels (WIP).
- JavaScript runtimes: Node.js & Bun
- Containerization & Deployment: Docker & dockerode
- Database: SurrealDB
- Download, a.k.a.
git clone https://github.com/rallisf1/hesperida.git && cd hesperida cp .env.example .envand edit it with your information- Start it up:
- With a self-hosted database
docker compose --profile aio up -d - With SurrealDB SaaS
docker compose --profile backend up -d
- Open
http://localhost:3000(or according to your configuration)
email: [email protected]
password: the value of SURREAL_PASS
You can change both later
docker compose --profile aio downto stop the running containersdocker compose pullto update all the docker imagesdocker compose --profile aio up -dto start
- Download, a.k.a.
git clone https://github.com/rallisf1/hesperida.git && cd hesperida cp .env.example .envand edit it with your information. UseNODE_ENV=development.- create a shortcut to the .env for the sveltekit project:
ln -s .env web/.env - Start it up
docker compose --profile dev up - (optional) you can pre-build the tools containers using
docker compose --profile tools build. If you skip this the first run will take a few minutes. - In another terminal run the sveltekit project with
cd web && bun install && bun run dev - Open
http://localhost:5173(or the port indicated in the terminal output)
- Task execution reliability still needs tuning under heavy concurrency. Known culprits:
- Document locks on rocksdb can conflict with high parallel workloads (e.g. multiple
whoistasks) - Not enough resources, upgrade your host
- Document locks on rocksdb can conflict with high parallel workloads (e.g. multiple
- There is no cleanup cron for the
job_queueyet (TODO) - Orphan containers may be left behind if the orchestrator crashes. When I tried using
AutoRemove: truein the container settings the containers exited before finishing. AFAIK it's a bug with Bun. This is not a big deal as they're not left running, but a cleanup cron will be needed for those as well. (TODO)
Things that I don't personally need, but would be helpful to some users. Check the issues for the one you need and like the first post. Don't reply to feature requests unless you have something meaningful to add. If there's no issue yet, open a new one.
- Ability to test form submissions (POST requests)
- Ability to use authentication (login)
- Ability to check subpages (a.k.a. crawl)
- Highlight errors on the screenshot
- SERP Ranking (integrate with SerpBear ?)
- Content checking
- A.I. generated content
- Plagiarism
- Grammar
- Placeholders (e.g. lorem ipsum)
- Public dashboards (e.g. to share with a client/colleague), although the
/jobs/[id]/pdflinks are public. - AI assistant to help you fix any errors found
- Auth.js authentication integration
- MCP server
- n8n node
k6 could be added to address complex workflows (e.g. login).
The current stress tool options are:
STRESS_RATESTRESS_DURATIONSTRESS_METHODSTRESS_TIMEOUTSTRESS_WORKERSSTRESS_MAX_WORKERSSTRESS_HEADERSSTRESS_BODYSTRESS_LATENCY_WARN_MS
The more the merrier, but at least:
- 2 CPU Cores / 4 threads (a.k.a. 4 vCores on a standard VPS)
- 4GB RAM
- 6GB of available Storage (5GB for the images + 1GB for the actual data)
There is a distinction between light (CLI/Node tools) and heavy (full browsers) tool containers, and the orchestrator won't run more heavy containers than the available CPU threads.
Those are just there for developer testing and pre-building, you'd never need to run them over docker compose in production.
Currently you can run the database on a different host than the orchestrator using the database and backend compose profiles.
You will also be able to host the API and Dashboard separately.
Running the scan tools on different hosts than the backend (a.k.a. orchestrator) is out of the scope of this FOSS project.
axe-core provides an impact rating per rule check, which is scored like this:
| Impact | Score |
|---|---|
| critical | 10 |
| serious | 7 |
| moderate | 3 |
| minor | 1 |
The total score percentage formula is 100 - (pass_score / (pass_score / error_score)). Inapplicable and incomplete rule checks are not scored for the time being.
If you have a better formula submit your issue.
Before making this I was using WAVE. Compared to that, axe-core is a bit less reliable, but more strict: All the websites I have checked have given more errors on axe-core, but way less warnings. My take-away from this is that if there are no errors in axe-core, there won't be any errors on WAVE as well. If you just need to fix WCAG errors (e.g. to pass an inspection) you'll be fine, but if your goal is a perfectly WCAG aligned web interface this isn't the tool for you.
Each finding gets a penalty score according to the following table:
| Impact | Score |
|---|---|
| critical | 10 |
| high | 7 |
| medium | 3 |
| low | 1 |
Then all the scores are added and a percentage is calculated according to the SECURITY_SCORE_THRESHOLD environment variable, which has a default value of 400. If the total score exceeds 400 you get a 0% Security score (hacker heaven). If the penalty score is 0 you get a 100% Security score (bulletproof). The number 400 is arbitary and based on a few tests. It might need tuning for your use-case, or even after updates (e.g. when more/new severe errors become common).
That said; score calculations used by Hesperida can change between configurations and versions. Thus; there's no point comparing scores across instances.
A DNS / web root file verification process has been added in v0.4.1, thus you can only scan websites you have access to their DNS zones or web root.
Verification is shared per (group, registrable_domain) and stored in dedicated verification records.
To verify your website either:
- add a TXT DNS record for
hesperida.yourdomain.comwithverification_codeas its value, or - add a
hesperida-${verification_code}.txt(empty) file to your web root
then verify it via the dashboard or use the /api/v1/websites/[id]/verify API endpoint.
Yes, as long as you use a proper (a.k.a. with a live domain) staging environment.
In theory, as long as you respect the AGPL license, yes; multi-tenancy is baked in. In practice, it would take a lot of effort to scale this in its current form (self-managed docker containers), and be a nightmare to maintain. If I decide to spin up a SaaS, I will write a proprietary kubernetes orchestrator from scratch and use SurrealDB cloud as well.
Only superusers can do that. As a non-superuser all you can do is delete or transfer the ownership of any websites you own and delete your account. If you want to start a new group sign up (provided sign ups are enabled), else ask a user to invite you.
Hesperida is an AI assisted developed project. More specifically; all the architecture, schema, and design decisions are my own. All the code for the first couple minor versions (most tools, db, and orchestrator) was hand-written. Since v0.3.0 about 90% of the code is AI generated using OpenAI Codex.
Open an issue and we'll see.
- Open an Issue
- Fork the repo
- Do your changes
- Test them
- Submit a PR that closes your issue
AGPL v3