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/04/22 09:41:40 UTC
(tooling-agents) branch main updated: ASVS L3 audit: 3.3.1 (ch03_general)
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 e50e2ab ASVS L3 audit: 3.3.1 (ch03_general)
e50e2ab is described below
commit e50e2ab3952ed78c821528e15d75a3d37e64b76a
Author: ASF Tooling Team <ro...@apache.org>
AuthorDate: Wed Apr 22 11:41:36 2026 +0200
ASVS L3 audit: 3.3.1 (ch03_general)
---
.../reports/steve/v3/d0aa7e9/ch03_general/3.3.1.md | 238 +++++++++++++++++++++
1 file changed, 238 insertions(+)
diff --git a/repos/apache/ASVS/reports/steve/v3/d0aa7e9/ch03_general/3.3.1.md b/repos/apache/ASVS/reports/steve/v3/d0aa7e9/ch03_general/3.3.1.md
new file mode 100644
index 0000000..e68a305
--- /dev/null
+++ b/repos/apache/ASVS/reports/steve/v3/d0aa7e9/ch03_general/3.3.1.md
@@ -0,0 +1,238 @@
+# ASVS 3.3.1 Security Audit Report: Cookie Setup
+
+## Executive Summary
+
+**Repository:** apache/steve
+**Audit Date:** Apr 22, 2026
+**Auditor:** Tooling Agents
+**ASVS Requirement:** 3.3.1 — Verify that cookies have the 'Secure' attribute set, and if the '__Host-' prefix is not used for the cookie name, the '__Secure-' prefix must be used for the cookie name.
+**Level:** 1
+**Section:** Cookie Setup
+**Section Description:** This section outlines requirements for securely configuring sensitive cookies to provide a higher level of assurance that they were created by the application itself and to prevent their contents from leaking or being inappropriately modified.
+**Chapter:** Web Frontend Security
+**Control Objective:** This category focuses on requirements designed to protect against attacks executed via a web frontend. These requirements do not apply to machine-to-machine solutions.
+
+**Files Analyzed:** 3 relevant out of 49 total, 12 skipped
+
+### Finding Counts
+
+| Severity | Count |
+|----------|-------|
+| Critical | 0 |
+| High | 1 |
+| Medium | 1 |
+| Low | 0 |
+| **Total** | **2** |
+
+**Summary:** Analysis of the provided source code reveals that the application uses session-based authentication via `asfquart.session` (built on Quart/Flask) but does not configure cookie security attributes required by ASVS 3.3.1. Neither the `Secure` attribute nor the `__Host-`/`__Secure-` cookie name prefix requirements are addressed in the visible application code.
+
+---
+
+## Security Controls Inventory
+
+| Control | Defined? | Where | Applied? | Coverage |
+|---------|----------|-------|----------|----------|
+| Session cookie creation | Yes | `asfquart.session` (framework) | Yes — `asfquart.session.read()` called in `basic_info()` and throughout | All authenticated endpoints |
+| `Secure` cookie attribute | **Not found** | — | **No** | 0% |
+| `__Host-` / `__Secure-` prefix | **Not found** | — | **No** | 0% |
+| TLS enforcement | Conditional | `main.py:79-80` | Only if `app.cfg.server.certfile` is set | Deployment-dependent |
+| Flash messages (session-stored) | Yes | `quart.flash()` via helper functions | Yes — `flash_success`, `flash_danger`, etc. | All POST endpoints |
+
+---
+
+## Critical File Review
+
+### `v3/server/main.py`
+
+| Line(s) | Function | Security Relevance | Status |
+|---------|----------|-------------------|--------|
+| 36-38 | `create_app()` | App construction — cookie config location | ❌ No cookie security config |
+| 77-80 | `run_standalone()` | Conditional TLS setup | ⚠️ TLS optional |
+| 84 | `run_standalone()` | `app.runx(port=...)` | No HTTPS enforcement |
+
+### `v3/server/pages.py`
+
+| Line(s) | Function | Security Relevance | Status |
+|---------|----------|-------------------|--------|
+| 86 | `basic_info()` | Session read — triggers cookie | ⚠️ Cookie attrs inherited from app config |
+| 94 | `basic_info()` | `csrf_token = 'placeholder'` | ❌ Related technical debt |
+| 119-127 | Flash helpers | Session-stored flash messages | ⚠️ Same cookie transport |
+
+---
+
+## Findings
+
+### High Severity
+
+#### ASVS-331-HIGH-001: Session Cookies Lack `Secure` Attribute Configuration
+
+| Field | Value |
+|-------|-------|
+| **Severity** | HIGH |
+| **Finding ID** | ASVS-331-HIGH-001 |
+| **Gap Type** | Type A — Entry point with NO control |
+| **File** | `v3/server/main.py`, lines 30-44 (`create_app()`) |
+| **Also relevant** | `v3/server/pages.py`, line 86 (`asfquart.session.read()`) |
+
+**Vulnerable Code (`main.py:30-44`):**
+```python
+def create_app():
+ "Create the asfquart app and its endpoints."
+ # ...
+ app = asfquart.construct('steve', app_dir=THIS_DIR, static_folder=None)
+ # No SESSION_COOKIE_SECURE configuration
+ import pages # noqa: F401
+ import api # noqa: F401
+ return app
+```
+
+**Data Flow:**
+1. `asfquart.construct()` creates the Quart application (source)
+2. Session cookies are created by the framework when `asfquart.session.read()` is called across all authenticated endpoints (sink)
+3. No `SESSION_COOKIE_SECURE = True` is set anywhere in the application configuration (missing control)
+
+**Evidence that TLS is not guaranteed (`main.py:77-80`):**
+```python
+if app.cfg.server.certfile:
+ kwargs['certfile'] = CERTS_DIR / app.cfg.server.certfile
+ kwargs['keyfile'] = CERTS_DIR / app.cfg.server.keyfile
+```
+TLS is conditionally configured only when `certfile` is present, meaning the application can run over plain HTTP. Without `Secure` attribute, session cookies would be transmitted in cleartext.
+
+**Affected Entry Points (all endpoints using sessions):**
+- All 17+ authenticated endpoints in `pages.py`
+- Session-based flash messages in all POST handlers
+- OAuth callback flows configured in `main.py:35-38`
+
+**Impact:** Session cookies can be intercepted over unencrypted connections (e.g., network sniffing, MITM). An attacker on the same network as a voter could steal session cookies and impersonate authenticated users, potentially casting fraudulent votes or manipulating elections.
+
+**Proof of Concept:**
+```
+# Attacker on same network captures HTTP traffic
+# Session cookie is transmitted without Secure flag:
+Cookie: session=eyJhbGci...
+
+# Attacker replays cookie over HTTPS to authenticated endpoint:
+GET /voter HTTP/1.1
+Host: steve.example.org
+Cookie: session=eyJhbGci...
+```
+
+**Remediation:**
+```python
+def create_app():
+ app = asfquart.construct('steve', app_dir=THIS_DIR, static_folder=None)
+
+ # Enforce secure cookie attributes (ASVS 3.3.1)
+ app.config['SESSION_COOKIE_SECURE'] = True
+ app.config['SESSION_COOKIE_HTTPONLY'] = True # bonus: ASVS 3.4.2
+ app.config['SESSION_COOKIE_SAMESITE'] = 'Lax' # bonus: ASVS 3.4.3
+
+ import pages
+ import api
+ return app
+```
+
+---
+
+### Medium Severity
+
+#### ASVS-331-MED-001: Session Cookie Name Missing `__Host-` or `__Secure-` Prefix
+
+| Field | Value |
+|-------|-------|
+| **Severity** | MEDIUM |
+| **Finding ID** | ASVS-331-MED-001 |
+| **Gap Type** | Type A — Entry point with NO control |
+| **File** | `v3/server/main.py`, lines 30-44 (`create_app()`) |
+
+**Vulnerable Code (`main.py:36-38`):**
+```python
+app = asfquart.construct('steve', app_dir=THIS_DIR, static_folder=None)
+# No SESSION_COOKIE_NAME configuration with __Host- or __Secure- prefix
+```
+
+**Analysis:**
+Quart (and Flask) default the session cookie name to `session`. ASVS 3.3.1 requires that if the `__Host-` prefix is not used, the `__Secure-` prefix **must** be used. Neither prefix is configured anywhere in the provided application code.
+
+The `__Secure-` prefix instructs browsers to only send the cookie over HTTPS and requires the `Secure` attribute. The `__Host-` prefix additionally restricts the cookie to the exact host and root path, preventing subdomain attacks.
+
+**Impact:** Without the `__Secure-` or `__Host-` prefix, the browser does not enforce prefix-based cookie protections. Combined with the missing `Secure` attribute (Finding 1), this means:
+- No browser-enforced HTTPS-only transmission
+- Potential for subdomain cookie injection attacks
+- Cookies could be overwritten by a less-secure subdomain
+
+**Remediation:**
+```python
+def create_app():
+ app = asfquart.construct('steve', app_dir=THIS_DIR, static_folder=None)
+
+ # Use __Host- prefix for maximum cookie security (ASVS 3.3.1)
+ # __Host- requires: Secure, Path=/, no Domain attribute
+ app.config['SESSION_COOKIE_NAME'] = '__Host-steve_session'
+ app.config['SESSION_COOKIE_SECURE'] = True
+ app.config['SESSION_COOKIE_PATH'] = '/'
+ # Do NOT set SESSION_COOKIE_DOMAIN (required for __Host- prefix)
+
+ # Alternative: Use __Secure- prefix (less restrictive)
+ # app.config['SESSION_COOKIE_NAME'] = '__Secure-steve_session'
+ # app.config['SESSION_COOKIE_SECURE'] = True
+
+ import pages
+ import api
+ return app
+```
+
+---
+
+## Positive Security Patterns
+
+1. **Authentication enforcement**: Nearly all endpoints use `@asfquart.auth.require({R.committer})` or `@asfquart.auth.require({R.pmc_member})`, providing consistent authentication gating.
+2. **Session abstraction**: Session management is abstracted through `asfquart.session`, meaning a fix to cookie configuration in one place (`create_app()`) will propagate to all endpoints.
+3. **Logging of security-relevant actions**: All state-changing operations log the user ID and action, providing an audit trail.
+4. **Input validation**: The `_set_election_date()` function validates date input with proper error handling.
+5. **OAuth over HTTPS**: OAuth endpoints hardcoded to `https://oauth.apache.org/...`, ensuring token exchange is encrypted.
+
+---
+
+## Architecture Observations
+
+1. **Single configuration point**: The `create_app()` function in `main.py` is the correct and only place to configure cookie security attributes. A fix here covers all session cookies application-wide.
+2. **Framework dependency**: Cookie security depends entirely on `asfquart`/Quart framework defaults. Quart inherits from Flask, where `SESSION_COOKIE_SECURE` defaults to `False` and `SESSION_COOKIE_NAME` defaults to `"session"` — neither meeting ASVS 3.3.1.
+3. **Deployment ambiguity**: The conditional TLS configuration (`if app.cfg.server.certfile`) suggests the application may be deployed behind a reverse proxy that terminates TLS. Even so, the application must set `SESSION_COOKIE_SECURE = True` to ensure browsers handle the cookie correctly regardless of proxy configuration.
+
+---
+
+## Recommendations Summary
+
+### Immediate Actions (Priority 1)
+
+| Finding ID | Action | Effort |
+|-----------|--------|--------|
+| ASVS-331-HIGH-001 | Set `SESSION_COOKIE_SECURE = True` in `create_app()` | Low (1 line) |
+
+### Short-term Actions (Priority 2)
+
+| Finding ID | Action | Effort |
+|-----------|--------|--------|
+| ASVS-331-MED-001 | Set `SESSION_COOKIE_NAME = '__Host-steve_session'` in `create_app()` | Low (1 line + remove Domain config if any) |
+| — | Enforce HTTPS at deployment level (redirect HTTP→HTTPS, HSTS header) | Medium |
+
+### Long-term Actions (Priority 3)
+
+| Finding ID | Action | Effort |
+|-----------|--------|--------|
+| — | Audit `asfquart` framework defaults for additional cookie attributes (`HttpOnly`, `SameSite`) | Low |
+
+---
+
+## Appendix: Files Analyzed
+
+<details>
+<summary>Click to expand file list (3 files)</summary>
+
+- `v3/server/main.py` (relevance: 10)
+- `v3/server/pages.py` (relevance: 10)
+- `v3/TODO.md` (relevance: 2)
+
+</details>
\ 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