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:27 UTC
(tooling-agents) branch main updated: ASVS audit: 3.7.2.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 b6d2e33 ASVS audit: 3.7.2.md (redacted) [source: apache/steve/v3 @ d0aa7e9]
b6d2e33 is described below
commit b6d2e335369232fdc8db34abced11fb84b720940
Author: ASF Tooling Team <ro...@apache.org>
AuthorDate: Tue May 5 22:56:04 2026 +0200
ASVS audit: 3.7.2.md (redacted) [source: apache/steve/v3 @ d0aa7e9]
---
ASVS/reports/steve/v3/d0aa7e9/all/3.7.2.md | 133 +++++++++++++++++++++++++++++
1 file changed, 133 insertions(+)
diff --git a/ASVS/reports/steve/v3/d0aa7e9/all/3.7.2.md b/ASVS/reports/steve/v3/d0aa7e9/all/3.7.2.md
new file mode 100644
index 0000000..18062c4
--- /dev/null
+++ b/ASVS/reports/steve/v3/d0aa7e9/all/3.7.2.md
@@ -0,0 +1,133 @@
+# Security Audit Report: ASVS 3.7.2
+
+## Executive Summary
+
+| Field | Value |
+|-------|-------|
+| **Repository** | apache/steve/v3 |
+| **Audit Date** | May 05, 2026 |
+| **Auditor** | Tooling Agents (bundled-pass mode) |
+| **ASVS Requirement** | ASVS 3.7.2 |
+| **Files Analyzed** | 12 relevant / 49 total |
+| **Files Skipped** | 12 |
+
+**Requirement description:** Verify that the application will only automatically redirect the user to a different hostname or domain (which is not controlled by the application) where the destination appears on an allowlist.
+
+### Findings Overview
+
+| Severity | Count |
+|----------|-------|
+| đź”´ Critical | 0 |
+| đźź High | 0 |
+| 🟡 Medium | 1 |
+| 🟢 Low | 0 |
+
+---
+
+## ASVS-3.7.2: Redirect Allowlist for External Domains
+
+### Findings for 3.7.2
+
+#### [MEDIUM]
+**Finding ID:** ASVS-372-MED-001
+**Location:** `v3/server/templates/header.ezt`, lines 26 and 36
+**Description:** Authentication endpoints accept URL parameters (`login=`, `logout=`) that appear to control post-authentication redirect destinations. While the current usage is hardcoded to `/`, the endpoint design pattern potentially allows open redirects if the `/auth` handler doesn't validate the destination.
+
+```html
+<a class="dropdown-item" href="/auth?logout=/">Sign Out</a>
+<!-- ... -->
+<a class="nav-link" href="/auth?login=/">Sign In</a>
+```
+
+**Data flow:** User → `/auth?login=<attacker-controlled-URL>` → authentication flow → redirect to attacker URL without validation
+
+**Proof of Concept:**
+```
+https://steve.example.org/auth?login=https://evil.com/phish
+```
+
+If the `/auth` endpoint (provided by `asfquart` framework, not in scope) redirects to the `login` parameter value after authentication, this is an open redirect.
+
+**Impact:** Could enable phishing attacks where users are redirected to a malicious site after authenticating, potentially capturing credentials or session tokens.
+
+**Remediation:**
+```python
+# In the auth handler (asfquart framework), validate redirect target:
+ALLOWED_REDIRECT_PATHS = {'/', '/voter', '/admin', '/profile'}
+
+def validate_redirect(target):
+ from urllib.parse import urlparse
+ parsed = urlparse(target)
+ # Only allow relative paths on same origin
+ if parsed.scheme or parsed.netloc:
+ return '/' # Default to home
+ if target not in ALLOWED_REDIRECT_PATHS and not target.startswith('/manage/'):
+ return '/'
+ return target
+```
+
+**Note:** The `/auth` endpoint code is not provided in the audit scope. This finding is based on the observable pattern in templates and requires validation against the `asfquart` framework implementation.
+
+### Security Controls Inventory for 3.7.2
+
+| Control | Location | Status |
+|---------|----------|--------|
+| Hardcoded internal redirects (server-side) | `pages.py` all `quart.redirect()` calls | âś… Applied |
+| Redirect allowlist | Not found | ⚠️ Unknown (depends on `/auth` handler) |
+| URL validation on redirect parameters | Not in scope | ⚠️ Unknown |
+| No user-controlled redirect in visible endpoints | `pages.py` | âś… Confirmed |
+
+### Positive Patterns for 3.7.2
+
+1. **All server-side redirects use hardcoded paths**: Every `quart.redirect()` call in `pages.py` uses a hardcoded internal path pattern (e.g., `/manage/{election.eid}`, `/voter`, `/vote-on/{election.eid}`).
+2. **No user-supplied redirect parameters in application code**: The application endpoints do not accept `next=`, `redirect=`, or `return_to=` parameters.
+3. **Redirect targets derived from database objects**: Election EIDs used in redirect paths come from verified database records (via `load_election` decorator), not from user input.
+4. **POST-redirect-GET pattern**: State-changing operations properly redirect to internal pages using 303 status codes.
+
+---
+
+
+
+## Cross-cutting Architecture Observations
+
+1. **Missing Security Header Middleware**: The application lacks a centralized response header middleware to set security headers (`X-Content-Type-Options`, `Cross-Origin-Resource-Policy`, `X-Frame-Options`, `Content-Security-Policy`). This creates Type B gaps—where controls should exist application-wide but don't.
+
+2. **Self-Hosting Pattern (Positive)**: The architecture decision to self-host all third-party assets via `fetch-thirdparty.sh` with version pinning eliminates CDN compromise risks and makes SRI defense-in-depth rather than critical. This is a strong architectural decision for a voting application.
+
+3. **Authentication Framework Dependency**: The application delegates authentication and redirect handling to the `asfquart` framework, creating an audit boundary. The security of redirect validation (3.7.2) depends entirely on the framework's implementation of `/auth` endpoints.
+
+4. **Inline JavaScript Pattern**: The application embeds authorized data in inline `<script>` blocks within HTML pages rather than as separate authenticated JavaScript resources. This inherently prevents XSSI attacks (3.5.7) through the Same-Origin Policy applied to HTML responses.
+
+5. **Document Serving Without Resource Policy**: The `serve_doc` endpoint correctly implements authentication and authorization but lacks modern browser-side protections (CORP, Sec-Fetch validation), creating a false sense of security—the authorization check alone doesn't prevent cross-origin resource embedding by an already-authenticated user's browser (Type B gap).
+
+6. **Template Security**: EZT templates use `[format "js,html"]` escaping for user-generated content injected into JavaScript contexts, showing awareness of XSS prevention, which indirectly supports browser origin separation requirements.
+
+## Cross-cutting Recommendations
+
+### Immediate (Critical/High Priority)
+1. **Add `Cross-Origin-Resource-Policy: same-origin` to authenticated responses**, particularly `serve_doc()`. This is a single-header addition that prevents the most impactful cross-origin resource theft scenario (ASVS-358-HIGH-001).
+
+2. **Implement Sec-Fetch validation middleware** for all authenticated endpoints:
+ ```python
+ @APP.before_request
+ async def validate_sec_fetch():
+ if quart.request.path.startswith('/docs/') or quart.request.path.startswith('/do-'):
+ sec_fetch_site = quart.request.headers.get('Sec-Fetch-Site', '')
+ if sec_fetch_site not in ('same-origin', 'none', ''):
+ quart.abort(403)
+ ```
+
+### Short-term (Medium Priority)
+3. **Add centralized security headers middleware** to set `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY`, and `Cross-Origin-Resource-Policy` on all responses.
+
+4. **Self-host the Apache feather SVG** to eliminate the last external resource dependency and achieve full resource isolation.
+
+5. **Verify `/auth` endpoint redirect validation** in the `asfquart` framework—confirm that `login=` and `logout=` parameters are validated against an allowlist or restricted to same-origin paths.
+
+### Long-term (Low Priority / Defense-in-Depth)
+6. **Add SRI to `bootstrap-icons.css`** for consistency with other third-party assets.
+
+7. **Implement external link interstitial** for ASVS L3 compliance—either a JavaScript confirmation dialog or a dedicated redirect page for the small number of external links.
+
+8. **Add `rel="noopener noreferrer"` to external links** to prevent reverse tabnapping via the `target` attribute on the Privacy Policy link.
+
\ 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