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 12:16:21 UTC

(tooling-agents) branch main updated: ASVS audit: 5.2.5.md (redacted)

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 d72ac85  ASVS audit: 5.2.5.md (redacted)
d72ac85 is described below

commit d72ac853f8b22f379b6dcffa928ea0f200641245
Author: ASF Tooling Team <ro...@apache.org>
AuthorDate: Tue May 5 14:07:57 2026 +0200

    ASVS audit: 5.2.5.md (redacted)
---
 ASVS/reports/steve/v3/d0aa7e9/all/5.2.5.md | 128 +++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)

diff --git a/ASVS/reports/steve/v3/d0aa7e9/all/5.2.5.md b/ASVS/reports/steve/v3/d0aa7e9/all/5.2.5.md
new file mode 100644
index 0000000..67fb1ed
--- /dev/null
+++ b/ASVS/reports/steve/v3/d0aa7e9/all/5.2.5.md
@@ -0,0 +1,128 @@
+# Security Audit Report: ASVS 5.2.5
+
+## Executive Summary
+
+| Field | Value |
+|-------|-------|
+| **Repository** | apache/steve/v3 |
+| **Audit Date** | May 05, 2026 |
+| **Auditor** | Tooling Agents (bundled-pass mode) |
+| **ASVS Requirement** | ASVS 5.2.5 |
+| **Files Analyzed** | 4 relevant / 49 total |
+| **Files Skipped** | 12 |
+
+**Requirement description:** Verify that the application does not allow uploading compressed files containing symlinks unless this is specifically required (in which case it will be necessary to enforce an allowlist of the files that can be symlinked to).
+
+### Findings Overview
+
+| Severity | Count |
+|----------|-------|
+| 🔴 Critical | 0 |
+| 🟠 High | 0 |
+| 🟡 Medium | 1 |
+| 🟢 Low | 0 |
+
+---
+
+## ASVS-5.2.5: Symlink Prevention in Compressed Files
+
+### Findings for 5.2.5
+
+#### MEDIUM
+**Finding ID:** ASVS-525-MED-001
+**Location:** `v3/server/pages.py` — entire application scope
+
+**Description:** There is no handling of compressed files visible in the provided code, and consequently no symlink detection or prevention. If documents placed in `DOCSDIR` originated from extracted archives, symbolic links within those archives could allow access to sensitive files outside the intended directory. While `send_from_directory` provides some protection against traversal, symlinks resolved at the filesystem level could bypass this.
+
+**Impact:** If an attacker can place a compressed file containing symlinks (e.g., pointing to `/etc/passwd` or the database file) and it gets extracted into `DOCSDIR`, the `serve_doc` endpoint could serve sensitive system files to authorized users.
+
+**Remediation:**
+```python
+import zipfile
+import os
+
+def validate_no_symlinks(archive_path):
+    """Ensure archive contains no symbolic links."""
+    with zipfile.ZipFile(archive_path, 'r') as zf:
+        for info in zf.infolist():
+            # Check for symlink attribute in external_attr
+            # Unix symlink: (0o120000 << 16)
+            if (info.external_attr >> 16) & 0o170000 == 0o120000:
+                raise ValueError(f'Symlink detected in archive: {info.filename}')
+    return True
+
+def safe_extract(archive_path, extract_dir):
+    """Extract archive safely, rejecting symlinks and path traversal."""
+    validate_no_symlinks(archive_path)
+    
+    with zipfile.ZipFile(archive_path, 'r') as zf:
+        for info in zf.infolist():
+            # Prevent path traversal
+            target_path = os.path.realpath(os.path.join(extract_dir, info.filename))
+            if not target_path.startswith(os.path.realpath(extract_dir)):
+                raise ValueError(f'Path traversal detected: {info.filename}')
+        
+        zf.extractall(extract_dir)
+```
+
+Additionally, ensure the `DOCSDIR` filesystem is mounted with `nosymfollow` (Linux) or equivalent to prevent symlink resolution at the OS level:
+```python
+# In serve_doc, verify file is not a symlink
+filepath = DOCSDIR / iid / docname
+if filepath.is_symlink():
+    _LOGGER.warning(f'Symlink detected: {filepath}')
+    quart.abort(403)
+```
+
+### Security Controls Inventory for 5.2.5
+
+| Control | Location | Status |
+|---------|----------|--------|
+| Symlink detection in archives | Not present | **MISSING** |
+| Symlink allowlist | Not present | **MISSING** |
+| Symlink check on file serve | Not present | **MISSING** |
+| Filesystem-level symlink prevention | Not verifiable from code | **UNKNOWN** |
+
+### Positive Patterns for 5.2.5
+
+- The route parameter `<docname>` (without `<path:>`) restricts filenames to single path segments, reducing (but not eliminating) symlink exploitation via the URL.
+- `send_from_directory` provides path safety but does not check for symlinks.
+
+---
+
+
+
+## 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