This project provides a client-side risk assessment questionnaire and lightweight domain scanning utility intended for MSPs / security teams to quickly baseline a prospect or environment. It is fully static (GitHub Pages friendly) and stores data locally (no backend persistence).
You can access a hosted version at https://assess.blacksmithinfosec.com. Alternatively, you can fork this repo and setup your own free, personalized scanner by customizing the CSS and images. Instructions for how to set this up are coming soon.
[!IMPORTANT] If you are planning to host the application you should use a reverse proxy or load balancer as the docker image only provides self-signed certificates and the built in node webserver is not suited for production hosting needs.
bash
npm install
npm run start
Open http://localhost:3000
bash
docker build -t risk-assessments:latest .
bash
docker run risk-assessments:latest -d -p 3000:443
bash
docker compose up --build -d
Now that you've built the application / image / container locally you're ready to open it by visiting: https://localhost:3000 in your browser.
[!NOTE] The docker containers are configured to serve over HTTPS by default and to direct all traffic to HTTPS. They will generate a self-signed certificate to facilitate this.
Questions are defined in src/data/questions.json with schema:
{
"questions": [
{
"id": "unique_id",
"text": "Readable question?",
"category": "identity",
"options": [
{ "label": "Good", "value": "good", "points": 10, "risk": "" },
{ "label": "Average", "value": "avg", "points": 5, "risk": "Without better identity management, average things happen" },
{ "label": "Poor", "value": "poor", "points": 0, "risk": "Without better identity management, bad things happen" }
]
}
]
}
Add 20 total questions. Keep id stable to preserve stored answers.
Client-side functions in src/utils/domainChecks.ts use public unauthenticated endpoints:
https://dns.google/resolvecrt.sh JSON outputNote on CORS Proxy: The security headers scanner uses a third-party CORS proxy (corsproxy.io) to access publicly available data from securityheaders.com. This is safe because:
Limitations (static environment):
The UI now displays independent scanner statuses. Each scanner runs in parallel and reports its own issues.
The scanner framework is modular with each scanner in its own file. See the Scanner Documentation for detailed information on:
Quick overview:
src/utils/scanners/ (one file per scanner)src/utils/scanners/index.tssrc/types/domainScan.tsThe modular structure allows multiple developers to work on different scanners simultaneously without merge conflicts.
{ "answers": {"question_id": "value"}, "domainScan": { ... } }.Assessment data is stored in browser localStorage. While this is convenient for a client-side only application, users should be aware:
For sensitive assessments, users should:
Domain inputs are validated using the URL constructor (src/utils/domainValidation.ts) to prevent:
JSON imports are thoroughly validated (src/utils/importValidation.ts) to prevent:
The application includes CSP headers to mitigate XSS attacks. The policy allows:
Domain scans are rate-limited (src/utils/scannerCache.ts) to prevent abuse:
The Vite dev server and preview mode include security headers:
X-Content-Type-Options: nosniff - Prevents MIME sniffingX-Frame-Options: DENY - Prevents clickjackingX-XSS-Protection: 1; mode=block - Enables XSS protectionReferrer-Policy: strict-origin-when-cross-origin - Controls referer informationPermissions-Policy - Restricts browser featuresUnit tests (Vitest) focus on scoring logic (src/utils/scoring.test.ts). Run with:
npm test
Add further tests for recommendation mapping and domain parsing as needed.
Report view uses print-aware CSS (hides nav and buttons). Improve ARIA semantics as the UI evolves.
Apache-2.0
Disclaimer: This tool provides indicative data only. Always perform deeper validation and manual review for production security decisions.
$ claude mcp add risk-assessments \
-- python -m otcore.mcp_server <graph>