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:54 UTC
(tooling-agents) branch main updated: ASVS audit: 5.2.4.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 49ea7d3 ASVS audit: 5.2.4.md (redacted) [source: apache/steve/v3 @ d0aa7e9]
49ea7d3 is described below
commit 49ea7d38da92290207490e80030c254518d015a3
Author: ASF Tooling Team <ro...@apache.org>
AuthorDate: Tue May 5 22:56:43 2026 +0200
ASVS audit: 5.2.4.md (redacted) [source: apache/steve/v3 @ d0aa7e9]
---
ASVS/reports/steve/v3/d0aa7e9/all/5.2.4.md | 139 +++++++++++++++++++++++++++++
1 file changed, 139 insertions(+)
diff --git a/ASVS/reports/steve/v3/d0aa7e9/all/5.2.4.md b/ASVS/reports/steve/v3/d0aa7e9/all/5.2.4.md
new file mode 100644
index 0000000..771f4a1
--- /dev/null
+++ b/ASVS/reports/steve/v3/d0aa7e9/all/5.2.4.md
@@ -0,0 +1,139 @@
+# Security Audit Report: ASVS 5.2.4
+
+## Executive Summary
+
+| Field | Value |
+|-------|-------|
+| **Repository** | apache/steve/v3 |
+| **Audit Date** | May 05, 2026 |
+| **Auditor** | Tooling Agents (bundled-pass mode) |
+| **ASVS Requirement** | ASVS 5.2.4 |
+| **Files Analyzed** | 4 relevant / 49 total |
+| **Files Skipped** | 12 |
+
+**Requirement description:** Verify that a file size quota and maximum number of files per user are enforced to ensure that a single user cannot fill up the storage with too many files, or excessively large files.
+
+### Findings Overview
+
+| Severity | Count |
+|----------|-------|
+| 🔴 Critical | 0 |
+| 🟠High | 0 |
+| 🟡 Medium | 1 |
+| 🟢 Low | 0 |
+
+---
+
+## ASVS-5.2.4: File Size Quota and Maximum File Count Per User
+
+### Findings for 5.2.4
+
+#### MEDIUM
+**Finding ID:** ASVS-524-MED-001
+**Location:** `v3/server/pages.py` — entire application scope; `v3/schema.sql` — database schema
+
+**Description:** There is no per-user file quota or maximum file count enforcement anywhere in the provided code or database schema. The database schema (`v3/schema.sql`) contains tables for elections, issues, persons, mayvotes, and votes — but nothing tracking file storage per user. Documents are served from `DOCSDIR/<iid>/` but there is no:
+1. Database table or column tracking per-user storage consumption
+2. Check limiting the total number of files a user can upload
+3. Check limiting total storage bytes per user
+4. Any quota enforcement mechanism
+
+**Vulnerable code quote (schema showing no file tracking):**
+```sql
+/* The set of Persons ever seen, across all Elections. */
+CREATE TABLE person (
+ pid TEXT PRIMARY KEY NOT NULL,
+ name TEXT,
+ email TEXT NOT NULL
+ ) STRICT;
+```
+
+**Impact:** A single user (or compromised account) could fill available storage by uploading an unlimited number of files or excessively large files, causing denial of service for all users.
+
+**Remediation:**
+```sql
+-- Add file tracking table
+CREATE TABLE user_files (
+ file_id TEXT PRIMARY KEY NOT NULL,
+ pid TEXT NOT NULL,
+ iid TEXT NOT NULL,
+ filename TEXT NOT NULL,
+ file_size INTEGER NOT NULL,
+ uploaded_at INTEGER NOT NULL,
+ FOREIGN KEY (pid) REFERENCES person(pid),
+ FOREIGN KEY (iid) REFERENCES issue(iid)
+) STRICT;
+```
+
+```python
+MAX_FILES_PER_USER = 50
+MAX_STORAGE_PER_USER = 500 * 1024 * 1024 # 500 MB
+
+async def check_user_quota(pid):
+ """Check if user has exceeded their file quota."""
+ db = steve.election.Election.open_database(DB_FNAME)
+
+ # Check file count
+ file_count = db.q_user_file_count.first_row(pid)
+ if file_count and file_count.count >= MAX_FILES_PER_USER:
+ return False, 'Maximum number of files reached'
+
+ # Check total storage
+ total_size = db.q_user_total_storage.first_row(pid)
+ if total_size and total_size.total >= MAX_STORAGE_PER_USER:
+ return False, 'Storage quota exceeded'
+
+ return True, None
+```
+
+### Security Controls Inventory for 5.2.4
+
+| Control | Location | Status |
+|---------|----------|--------|
+| Per-user file count limit | Not present | **MISSING** |
+| Per-user storage quota | Not present | **MISSING** |
+| File tracking database table | Not present in schema | **MISSING** |
+| Quota enforcement in upload handler | No upload handler present | **MISSING** |
+
+### Positive Patterns for 5.2.4
+
+- No findings of positive patterns for this requirement. File quota management is entirely absent.
+
+---
+
+
+
+## Cross-cutting Architecture Observations
+
+1. **Missing Upload Mechanism:** The application has a clear document serving architecture (`DOCSDIR/<iid>/<docname>`, `serve_doc` endpoint, `rewrite_description` link generation) but no visible upload handler in the provided code. This creates a Type B gap — the authorization control for serving documents exists, but without a corresponding upload handler with security controls, the safety of served files cannot be guaranteed.
+
+2. **Acknowledged Technical Debt:** The comment `### verify the propriety of DOCNAME.` in `serve_doc` (line 571) indicates the development team is aware of the gap but has not yet addressed it. This is a conscious risk acceptance without documented mitigation.
+
+3. **Framework-Level Protections:** The application relies on `quart.send_from_directory` for path safety, which is a reasonable baseline but insufficient for ASVS L2/L3 compliance. The framework prevents directory traversal via path manipulation but does not address file content safety, symlinks, or archive bombs.
+
+4. **Schema Has No File Metadata:** The `v3/schema.sql` database schema has no table for tracking uploaded files, their sizes, types, or ownership. This makes it architecturally impossible to enforce per-user quotas, file type policies, or audit file uploads without schema changes.
+
+5. **Defense-in-Depth Absent for Files:** The application has multiple layers for election security (cryptographic salts, anti-tamper keys, encrypted votes) but zero layers for file security. This asymmetry suggests file handling was not part of the initial security design.
+
+## Cross-cutting Recommendations
+
+### Immediate (Critical)
+1. **Add file extension allowlist to `serve_doc`** — Implement a whitelist of permitted extensions (`.pdf`, `.txt`, `.png`) and reject requests for unlisted types. This is the minimum viable control for the existing serving endpoint.
+2. **Add `X-Content-Type-Options: nosniff` and `Content-Disposition: attachment`** headers to all file serve responses to prevent content sniffing and force download behavior.
+3. **Add symlink check** — Before serving any file, verify `not filepath.is_symlink()`.
+
+### Short-term (High)
+4. **Implement a documented file upload handler** with:
+ - `MAX_CONTENT_LENGTH` configured in Quart
+ - Extension validation against an allowlist
+ - Magic bytes verification using `python-magic`
+ - Maximum file size per upload
+5. **Create file handling documentation** that satisfies ASVS 5.1.1 — define permitted types, extensions, sizes, and malicious file handling behavior.
+6. **Add a `user_files` tracking table** to the database schema to enable quota enforcement.
+
+### Long-term (Medium)
+7. **Implement compressed file validation** — detect archives, check uncompressed size and file count, reject symlinks.
+8. **Implement per-user storage quotas** with configurable limits and enforcement at upload time.
+9. **Add virus/malware scanning** integration (e.g., ClamAV) for uploaded documents.
+10. **Implement image rewriting** for any accepted image files to strip metadata and neutralize polyglot attacks.
+
\ 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