Harden some security issues based on Pentest scan - Report attached.#228
Closed
rafaelfoster wants to merge 2 commits into
Closed
Harden some security issues based on Pentest scan - Report attached.#228rafaelfoster wants to merge 2 commits into
rafaelfoster wants to merge 2 commits into
Conversation
ulsklyc
pushed a commit
that referenced
this pull request
Jun 3, 2026
Harden information-disclosure surface flagged by a pentest scan, without adopting a frontend build step (the esbuild/minification part of #228 was dropped to keep the no-bundler / zero-build constraint intact): - /openapi.json + /api/v1/openapi.json now require an admin session/token. - /docs is admin-only and returns 404 in production unless ENABLE_API_DOCS=true. - GET /api/v1/version returns the exact version only to authenticated callers; unauthenticated login/setup pages still get app_name + setup_required. - POST /api/v1/auth/setup responds 404 (not 403) in production once set up. - Strip deployment host and SQLite implementation details from the OpenAPI spec. Docs: document ENABLE_API_DOCS (.env.example, installation.md) and the new auth model for version/openapi in SPEC.md. Co-Authored-By: Rafael Foster <rafaelfoster@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ulsklyc
pushed a commit
that referenced
this pull request
Jun 3, 2026
Owner
|
Thanks for the thorough pentest report and the hardening work, @rafaelfoster! 🙏 The security hardening has been merged and shipped in v0.60.3:
I did not take the esbuild/JS-minification part (Dockerfile build step, Because the merged subset landed via a separate commit ( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/docsin production unless explicitly enabled, and require admin auth otherwise./api/v1/version.Testing
docker compose build oikosdocker run --rm --entrypoint node ghcr.io/ulsklyc/oikos:latest test/test-setup.jsWorking tree is clean on security-review-001.
Security validation report:
Penetration Test Report: OIKOS. pentest (2026-06-03) - Jun 3, 2026, 3:28 PM-
Asset: OIKOS.
Date: 6/3/2026
Total Findings: 5
Executive Summary
A penetration test was conducted against the OIKOS. web application, resulting in an overall medium security posture with 5 total findings: 0 critical, 0 high, 1 medium, 1 low, and 3 informational. The assessment revealed that the application exposes significant internal technical details — including its complete operational blueprint and internal structure — to any unauthenticated visitor on the internet. An attacker could leverage this freely available information to map the entire application's functionality, identify potential weaknesses in authentication and data-handling workflows, and craft highly targeted attacks against user accounts and family data without requiring any prior access or credentials.
Security Posture: MEDIUM
Key Concerns:
Immediate Actions: While no critical or high-severity vulnerabilities were identified in this free-tier assessment, the medium-severity finding warrants prompt attention as it provides attackers with a comprehensive understanding of the application's inner workings that could facilitate more damaging attacks. We recommend engaging for the full penetration test report to uncover deeper vulnerabilities that typically accompany this level of information exposure. Detailed findings, reproduction steps, and remediation guidance are available in the full pentest report.
Findings Summary
Detailed Findings
1. Info Disclosure via /openapi.json - Full API Schema Exposed
Severity: MEDIUM
Status: Open
Occurrences: 2
Description
The full OpenAPI/Swagger specification is exposed at /openapi.json without authentication. This 99KB JSON file reveals the complete API surface of the Oikos family planner application, including:
This information provides an attacker with a complete roadmap for targeted attacks against the API.
Proof of Concept
Step 1: Access the OpenAPI specification without any authentication
Expected output: {"info":{"title":"Oikos API","version":"0.55.13","description":"OpenAPI documentation for the Oikos family organizer backend."},"servers":[{"url":"https://OIKOS.","description":"Current server"}],"paths_count":107,"security_schemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API token sent in the Authorization header as
Bearer <token>."},"apiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API token sent in theX-API-Keyheader."},"cookieAuth":{"type":"apiKey","in":"cookie","name":"oikos.sid","description":"Browser session cookie. State-changing requests also requireX-CSRF-Token."}}}Step 2: Extract the backup database endpoint details showing SQLite database download capability and admin endpoints
Expected output: {"backup_download":"Download database backup","setup_endpoint":"Initial setup: create first admin","user_schema":["avatar_color","avatar_data","birth_date","display_name","email","family_role","id","phone","role","username"]}
Solution
2. Info Disclosure via Exposed Swagger UI and API Documentation at /docs
Severity: LOW
Status: Open
Occurrences: 2
Description
The application serves an interactive Swagger UI documentation page at /docs (which returns a 301 redirect to /docs/) and exposes the full OpenAPI specification at both /openapi.json and /api/v1/openapi.json without any authentication. While /docs/ is intercepted by the SPA catch-all router and doesn't render the Swagger UI properly, the underlying Express route exists and the redirect response confirms the Swagger documentation framework is installed. Combined with the unauthenticated /openapi.json endpoint (reported separately), an attacker gains complete knowledge of the API surface area, including admin-only endpoints, database backup download paths, authentication schemes (Bearer, API key, session cookie), and all request/response schemas. The /docs 301 redirect itself confirms Express with swagger-ui-express middleware is running, adding to technology fingerprinting.
Proof of Concept
Step 1: Access /docs to confirm the Swagger UI route exists - it returns a 301 redirect to /docs/
Expected output: HTTP/2 301
date: Wed, 03 Jun 2026 15:20:06 GMT
content-type: text/html; charset=UTF-8
content-security-policy: default-src 'none'
cross-origin-opener-policy: same-origin
cross-origin-resource-policy: same-origin
location: /docs/
Step 2: Confirm the OpenAPI specification is also available at /api/v1/openapi.json
Expected output: {"title":"Oikos API","version":"0.55.13","description":"OpenAPI documentation for the Oikos family organizer backend."}
Solution
3. Info Disclosure via Complete Source Code Exposure in Unminified JavaScript
Severity: INFO
Status: Open
Occurrences: 2
Description
The Oikos application serves all client-side JavaScript as unminified, fully commented ES modules without bundling or obfuscation. Over 500KB of source code is directly accessible at well-known paths (/api.js, /router.js, /pages/settings.js, /pages/dashboard.js, etc.) with full German/English code comments explaining the architecture, security mechanisms, and implementation details. Key exposures include:
While frontend code is inherently client-accessible, the unminified commented source code significantly reduces the effort for an attacker to map the entire application architecture and identify targeted attack vectors.
Proof of Concept
Step 1: Download the api.js file showing the complete API client implementation with CSRF handling
Expected output: /**
*/
const API_BASE = '/api/v1';
/** In-Memory CSRF-Token (zuverlaessiger als document.cookie auf iOS Safari/PWA). */
let _csrfToken = '';
/** Liest den CSRF-Token: bevorzugt In-Memory, Fallback auf Cookie. */
function getCsrfToken() {
if (_csrfToken) return _csrfToken;
return document.cookie.split(';')
.map((c) => c.trim())
.find((c) => c.startsWith('csrf-token='))
?.slice('csrf-token='.length) ?? '';
}
Step 2: Download the settings page JS showing admin-only functionality like user management, backup, and API token creation
Expected output: 15
Solution
4. Info Disclosure via /api/v1/auth/setup - Setup Endpoint Active in Production
Severity: INFO
Status: Open
Occurrences: 2
Description
The /api/v1/auth/setup endpoint, designed for initial admin user creation during application setup, remains active and accessible in production. While it correctly returns HTTP 403 with "Setup has already been completed" (indicating the initial setup was done), the endpoint's existence in production reveals several things:
The endpoint should be disabled or removed in production after initial setup is complete.
Proof of Concept
Step 1: Attempt to use the setup endpoint to create a new admin user
Expected output: {"error":"Setup has already been completed.","code":403}
Step 2: Confirm the setup endpoint schema is exposed in the OpenAPI specification, revealing the exact fields needed for admin creation
Expected output: {"summary":"Initial setup: create first admin","requestBody":{"$ref":"#/components/schemas/SetupRequest"}}
Solution
5. Info Disclosure via /api/v1/version - Application Version Exposed
Severity: INFO
Status: Open
Occurrences: 2
Description
The /api/v1/version endpoint is accessible without authentication and reveals the application name and exact version number (Oikos FamilyPlanner v0.55.13). This information can be used by attackers to identify known vulnerabilities specific to this version, or to fingerprint the application for targeted attacks.
Proof of Concept
Step 1: Access the version endpoint without authentication to retrieve the application name and version
Expected output: {"version":"0.55.13","app_name":"FamilyPlanner"}
Step 2: Confirm the endpoint does not require any authentication cookies or tokens
Expected output: HTTP/2 200
content-type: application/json; charset=utf-8
Solution