You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tooling.apache.org by as...@apache.org on 2026/05/05 21:01:16 UTC
(tooling-agents) branch main updated: ASVS audit: 11.1.1.md (redacted) [source: apache/steve/v3 @ d0aa7e9]
This is an automated email from the ASF dual-hosted git repository.
asf-tooling pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-agents.git
The following commit(s) were added to refs/heads/main by this push:
new 1da2f94 ASVS audit: 11.1.1.md (redacted) [source: apache/steve/v3 @ d0aa7e9]
1da2f94 is described below
commit 1da2f942b04f5574a4ae976597a8d1c1994a3e82
Author: ASF Tooling Team <ro...@apache.org>
AuthorDate: Tue May 5 22:51:43 2026 +0200
ASVS audit: 11.1.1.md (redacted) [source: apache/steve/v3 @ d0aa7e9]
---
ASVS/reports/steve/v3/d0aa7e9/all/11.1.1.md | 153 ++++++++++++++++++++++++++++
1 file changed, 153 insertions(+)
diff --git a/ASVS/reports/steve/v3/d0aa7e9/all/11.1.1.md b/ASVS/reports/steve/v3/d0aa7e9/all/11.1.1.md
new file mode 100644
index 0000000..0d0b33c
--- /dev/null
+++ b/ASVS/reports/steve/v3/d0aa7e9/all/11.1.1.md
@@ -0,0 +1,153 @@
+# Security Audit Report: ASVS 11.1.1
+
+## Executive Summary
+
+| Field | Value |
+|-------|-------|
+| **Repository** | apache/steve/v3 |
+| **Audit Date** | May 05, 2026 |
+| **Auditor** | Tooling Agents (bundled-pass mode) |
+| **ASVS Requirement** | ASVS 11.1.1 |
+| **Files Analyzed** | 8 relevant / 49 total |
+| **Files Skipped** | 12 |
+
+**Requirement description:** Verify that there is a documented policy for management of cryptographic keys and a cryptographic key lifecycle that follows a key management standard such as NIST SP 800-57. This should include ensuring that keys are not overshared (for example, with more than two entities for shared secrets andβ¦
+
+### Findings Overview
+
+| Severity | Count |
+|----------|-------|
+| π΄ Critical | 0 |
+| π High | 0 |
+| π‘ Medium | 1 |
+| π’ Low | 1 |
+
+---
+
+## ASVS-11.1.1: Cryptographic Key Management Policy
+
+### Findings for 11.1.1
+
+#### [MEDIUM]
+**Finding ID:** ASVS-1111-MED-001
+**Title:** No Documented Cryptographic Key Management Policy or Key Lifecycle
+
+**Location:** Project-wide (particularly `v3/steve/crypto.py`, `v3/docs/schema.md`)
+
+**Description:**
+The codebase contains multiple cryptographic keys and secrets (election salt, opened_key, vote_token, vote encryption keys) but there is no documented key management policy conforming to NIST SP 800-57 or an equivalent standard. While `schema.md` provides some documentation of what keys exist, it does not constitute a key lifecycle policy addressing:
+
+- Key generation procedures and responsibilities
+- Key storage and protection requirements
+- Key distribution controls
+- Key usage periods / expiration
+- Key revocation and destruction procedures
+- Key recovery mechanisms
+
+**Evidence:**
+
+```python
+# crypto.py - Keys are generated but no lifecycle management exists
+def gen_opened_key(edata: bytes, salt: bytes) -> bytes:
+ "Generate the OpenedKey for this election."
+ # No expiration, no rotation, no revocation mechanism
+ ...
+
+def gen_vote_token(opened_key: bytes, pid: str, iid: str, salt: bytes) -> bytes:
+ "Generate a person or issue token."
+ # Token persists indefinitely in database
+ ...
+```
+
+```sql
+-- schema.sql - Keys stored without expiration or lifecycle metadata
+opened_key BLOB CHECK (opened_key IS NULL OR length(opened_key) = 32),
+salt BLOB CHECK (salt IS NULL OR length(salt) = 16),
+```
+
+**Data flow:** Key generation β database storage β indefinite persistence (no rotation/expiration)
+
+**Impact:** Without a documented key lifecycle, keys may persist beyond their intended use period, accumulate risk, and lack clear procedures for compromise response. The `opened_key` persists in the database indefinitely after an election closes, with no documented destruction schedule.
+
+**Remediation:**
+Create a formal cryptographic key management policy document covering:
+1. Key types, purposes, and authorized users
+2. Key generation procedures (already using `secrets` module)
+3. Maximum key lifetime per key type
+4. Key storage protection requirements
+5. Key destruction procedures (e.g., zeroing opened_key after tally completion)
+6. Incident response for key compromise
+
+#### [LOW]
+**Finding ID:** ASVS-1111-LOW-001
+**Title:** Key Sharing Scope Not Formally Documented
+
+**Location:** `v3/steve/crypto.py`, `v3/steve/election.py`
+
+**Description:**
+The `opened_key` in each election effectively acts as a shared secret used by the system to derive per-voter vote tokens. While the key is only accessible to the application server (single entity), the sharing boundaries are not formally documented. The key derivation chain (opened_key β vote_token β vote_key) means compromise of the opened_key enables decryption of all votes in that election.
+
+**Impact:** Without formal documentation of key sharing boundaries, there's risk of architectural changes inadvertently exposing keys to additional entities.
+
+### Security Controls Inventory for 11.1.1
+
+| Control | Location | Status |
+|---------|----------|--------|
+| Cryptographically secure salt generation | `crypto.py:gen_salt()` | β Present |
+| Key derivation from election data | `crypto.py:gen_opened_key()` | β Present |
+| Per-voter key derivation | `crypto.py:gen_vote_token()` | β Present |
+| Key length constraints in schema | `schema.sql` (CHECK constraints) | β Present |
+| Key lifecycle documentation | Not found | β Missing |
+| Key rotation mechanism | Not found | β Missing |
+| Key destruction procedures | Not found | β Missing |
+
+### Positive Patterns for 11.1.1
+
+- Keys are generated using `secrets.token_bytes()` (CSPRNG)
+- Key lengths are enforced at the database level via CHECK constraints (16-byte salt, 32-byte opened_key, 32-byte vote_token)
+- The `opened_key` is never exposed via public API (`get_metadata()` explicitly excludes it)
+- Per-voter keys are derived, limiting blast radius per key compromise
+- Schema documentation (`schema.md`) documents cryptographic field purposes
+
+---
+
+
+
+## Cross-cutting Architecture Observations
+
+1. **Centralized Crypto Module:** All cryptographic operations are centralized in `v3/steve/crypto.py`. This is excellent for auditability but currently lacks the abstraction needed for agility. The centralization makes future refactoring feasible.
+
+2. **Key Derivation Chain:** The system uses a well-designed multi-level key derivation: `election_data β BLAKE2b β Argon2 β opened_key β (+ pid + iid + salt) β Argon2 β vote_token β HKDF β vote_key β Fernet(vote)`. This provides good key separation and limits blast radius, but the entire chain is hardcoded.
+
+3. **Documentation Gap:** The project has partial documentation (`schema.md`) but lacks formal security/crypto documentation. The existing documentation focuses on database schema rather than cryptographic design decisions.
+
+4. **Anti-Tamper Design:** The `opened_key` serves dual purposes: (1) tamper detection via `is_tampered()` and (2) vote token derivation. This coupling means the anti-tamper mechanism is tied to the same cryptographic algorithm as the voting mechanism β upgrading one requires upgrading both.
+
+5. **No Asymmetric Cryptography:** The system uses only symmetric primitives and key derivation. This reduces PQC urgency compared to systems using RSA/ECC, but the AES-128 effective key length under Grover's algorithm (64-bit) is a concern for long-term data confidentiality.
+
+6. **Inconsistency Between Production and Benchmark:** Production uses Argon2d while the benchmark uses Argon2id, suggesting either incomplete migration or a deliberate but undocumented choice.
+
+## Cross-cutting Recommendations
+
+### Immediate (Sprint-level)
+1. **Change Argon2d to Argon2id** in `_hash()` function (ASVS-1121-MED-001). This is a one-line change with significant security improvement. Note: this will change all derived values, so must be coordinated with any existing deployed databases.
+
+2. **Add `crypto_version` column** to the `vote` table to enable future algorithm transitions without data loss.
+
+### Short-term (1-3 months)
+3. **Create formal cryptographic inventory document** mapping all algorithms, keys, their purposes, access scopes, and protection requirements (satisfies 11.1.1, 11.1.2).
+
+4. **Implement crypto abstraction layer** in `crypto.py` with version-based algorithm selection and a configuration mechanism for algorithm parameters (satisfies 11.2.2).
+
+5. **Add cryptographic linting** to CI/CD pipeline using `semgrep` or equivalent with rules for:
+ - Flagging new crypto imports
+ - Detecting weak algorithms
+ - Ensuring CSPRNG usage (satisfies 11.1.3)
+
+### Long-term (3-12 months)
+6. **Complete Fernet β XChaCha20-Poly1305 migration** with proper versioning, re-encryption tooling, and rollback capability.
+
+7. **Document PQC migration plan** assessing quantum risk for each primitive and establishing upgrade timelines, particularly upgrading to AES-256 for long-term vote confidentiality (satisfies 11.1.4).
+
+8. **Implement key lifecycle management** including maximum key age, scheduled rotation for long-lived keys, and secure key destruction after election archival (satisfies 11.1.1).
+
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tooling.apache.org
For additional commands, e-mail: commits-help@tooling.apache.org