Files
admin/_docs/05_security/owasp_review.md
T
Oleksandr Bezdieniezhnykh 3a925b9b0f
ci/woodpecker/push/01-test Pipeline failed
ci/woodpecker/push/02-build-push unknown status
refactor: remove obsolete resource download and installer endpoints
- Deleted the `POST /resources/get/{dataFolder?}` and `GET /resources/get-installer` endpoints as part of the architectural shift towards simplified resource management.
- Removed associated methods and configurations, including `ResourcesService.GetEncryptedResource`, `ResourcesService.GetInstaller`, and related properties in `ResourcesConfig`.
- Cleaned up environment variables and configuration files to reflect the removal of installer-related settings.
- Eliminated the `GetResourceRequest` DTO and its validator, along with the `WrongResourceName` error code.
- Updated documentation to clarify the changes in resource handling and the retirement of per-user file encryption.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 04:17:55 +03:00

6.0 KiB

OWASP Top 10 Review (2021 edition)

Date: 2026-05-13 Framework: OWASP Top 10 — 2021 (the 2025 release is not yet finalized as of this audit; 2021 remains the current authoritative list). Scope cross-reference: every FAIL below cites a Phase 2 finding ID (F-N) for the underlying evidence.

Per-Category Assessment

# Category Status Findings
A01 Broken Access Control FAIL F-2 (path traversal via dataFolder) — F-1 closed via OTA feature revert
A02 Cryptographic Failures PASS_WITH_WARNINGS F-1 closed via revert; D-1 closed via Newtonsoft bump (13.0.4); F-7 (SHA-384 password hash, no salt/KDF) remains open as a hardening item
A03 Injection PASS linq2db parameterizes all queries; no string-concatenation SQL paths found in Azaion.Services/*Service.cs or Azaion.Common/Database/*. No Process.Start / subprocess usage in production code. No template injection paths.
A04 Insecure Design PASS_WITH_WARNINGS F-3 closed (UNIQUE INDEX users_email_uidx + RegisterUser/RegisterDevice consolidation); F-8 (no rate limiting on /login) remains as a hardening item
A05 Security Misconfiguration FAIL F-6 (container runs as root), F-13 (no HTTPS enforcement in code), F-9 (request DTOs missing validators), F-11 (placeholder credentials in 01_permissions.sql). F-5 closed automatically (EncryptionMasterKey field deleted with the OTA revert).
A06 Vulnerable & Outdated Components PASS All dotnet list package --vulnerable checks return clean. D-1 (Newtonsoft.Json) was the only manual finding; closed in this audit by bumping to 13.0.4. Three deprecated-but-not-vulnerable packages noted in dependency_scan.md.
A07 Identification & Authentication Failures PASS_WITH_WARNINGS F-3 closed (DB UNIQUE INDEX now enforces one-row-per-email). F-7 (weak password hashing) and F-8 (no rate limiting) remain open as hardening items.
A08 Software & Data Integrity Failures PASS OTA flow that introduced the unsigned-manifest concern was reverted. CI/CD: secrets are env-injected, no in-repo secrets in Dockerfile / compose files used by prod.
A09 Security Logging & Monitoring Failures PASS_WITH_WARNINGS Serilog console + rolling file sink configured. F-12 (one unstructured log line in ResourcesService). No security-event-specific logger — login successes/failures, role changes, deletes are not separately auditable.
A10 Server-Side Request Forgery (SSRF) NOT_APPLICABLE The API never makes outbound HTTP calls based on user-controlled URLs. CdnUrl from PublishResourceRequest is stored and forwarded but never fetched server-side.

Cross-Reference Against security_approach.md

The pre-cycle-1 security_approach.md "Known Security Observations" list is reconciled here:

Original observation Status post-cycle-1
1. SHA-384 without per-user salt Still open — F-7
2. hardware_hash DB column unused Resolved by AZ-197 — column-level removal pending follow-up; field is now dead but the column is still in the schema (02_structure.sql:9). Not a security risk; cleanup task.
3. No path traversal protection on dataFolder Still open — F-2
4. Hardcoded DB credentials in test files Confirmed test-only — F-10
5. No rate limiting on /login Still open — F-8
6. No audit trail for security-relevant operations Still open — A09 PASS_WITH_WARNINGS
7. No HTTPS enforcement in code Still open — F-13
8. Static encryption key salts hardcoded Resolved by cycle-2 cleanupSecurity.GetApiEncryptionKey was deleted entirely along with EncryptTo / DecryptTo and the encrypted-download endpoint. No hardcoded encryption-key salt remains in application code. (ResourceColumnEncryption was deleted along with the OTA revert.)

Cycle-2 Cleanup Verdict (2026-05-14)

The cycle-2 cleanup removed three obsolete endpoints (POST /resources/get/{dataFolder?}, GET /resources/get-installer, GET /resources/get-installer/stage) and their orphaned support code (Security.GetApiEncryptionKey / EncryptTo / DecryptTo, ResourcesService.GetEncryptedResource / GetInstaller, GetResourceRequest, WrongResourceName = 50, ResourcesConfig.SuiteInstallerFolder / SuiteStageInstallerFolder).

Net security impact:

  • Observation 8 closed (see table above) — the static encryption-key salt no longer exists in source.
  • Attack surface reduced under A02 (Cryptographic Failures): no more application-layer encryption stack means no more mis-keying, mis-IVing, or padding-oracle exposure to maintain. The remaining cryptographic surface in this codebase is JWT signing (HMAC-SHA256, library-managed) and SHA-384 password hashing.
  • No new findings introduced. Three endpoints fewer also means three fewer A01 / A05 surfaces to track.
  • F-2 (path traversal via dataFolder) remains open — the upload / list / clear endpoints still take dataFolder and still concatenate it directly with ResourcesFolder. The cleanup did not change this.

Cycle-1 Specific Verdict

The cycle-1 changes (AZ-513, AZ-196, AZ-183, AZ-197) introduced one new High-severity finding (F-1, on /get-update) and amplified one existing High (F-3, via RegisterDevice). Both were closed before any deploy:

  • F-1 (resolved by feature revert): AZ-183 was reverted in full; the OTA delivery model itself is obsolete in the target architecture.
  • F-3 (resolved): RegisterDevice now delegates to RegisterUser; users.email has a UNIQUE INDEX (users_email_uidx); UNIQUE-violation is translated to EmailExists.

Other cycle-1 endpoints (/devices, /classes/*) have correct authorization wiring (apiAdminPolicy).

Self-verification

  • All current OWASP Top 10 categories assessed
  • Each FAIL has at least one specific finding with evidence (F-N reference)
  • NOT_APPLICABLE category has justification (A10)