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/21 08:56:18 UTC

(tooling-agents) branch main updated: ASVS L1 audit: 10.4.2 (authentication_authorization)

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 b26aa48  ASVS L1 audit: 10.4.2 (authentication_authorization)
b26aa48 is described below

commit b26aa4837db344e823b7c022e04419c740522e05
Author: ASF Tooling Team <ro...@apache.org>
AuthorDate: Tue Apr 21 10:56:14 2026 +0200

    ASVS L1 audit: 10.4.2 (authentication_authorization)
---
 .../d0aa7e9/authentication_authorization/10.4.2.md | 550 +++++++++++++++++++++
 1 file changed, 550 insertions(+)

diff --git a/repos/apache/ASVS/reports/steve/d0aa7e9/authentication_authorization/10.4.2.md b/repos/apache/ASVS/reports/steve/d0aa7e9/authentication_authorization/10.4.2.md
new file mode 100644
index 0000000..e91c66e
--- /dev/null
+++ b/repos/apache/ASVS/reports/steve/d0aa7e9/authentication_authorization/10.4.2.md
@@ -0,0 +1,550 @@
+# ASVS 10.4.2 Security Audit Report
+
+## Executive Summary
+
+**Audit Metadata:**
+- **Repository:** apache/steve
+- **Audit Date:** Apr 21, 2026
+- **Auditor:** Tooling Agents
+- **ASVS Requirement:** 10.4.2 — Verify that, if the authorization server returns the authorization code in the authorization response, it can be used only once for a token request. For the second valid request with an authorization code that has already been used to issue an access token, the authorization server must reject a token request and revoke any issued tokens related to the authorization code.
+- **ASVS Level:** 1
+- **Section:** OAuth Authorization Server
+- **Chapter:** OAuth and OIDC
+
+**Files Analyzed:** 5 relevant out of 5 total, 0 skipped
+
+**Finding Summary:**
+
+| Severity | Count |
+|----------|-------|
+| Critical | 0 |
+| High | 0 |
+| Medium | 0 |
+| Low | 0 |
+| **Total** | **0** |
+
+**Audit Conclusion:**
+
+After comprehensive analysis of all provided source files, **this application does not implement an OAuth Authorization Server**. The codebase functions as an **OAuth client/relying party** that delegates authentication to the ASF's external OAuth infrastructure via the `asfquart.auth` and `asfquart.session` libraries. 
+
+There is no authorization endpoint, token endpoint, authorization code issuance, or code-to-token exchange logic present in this codebase. Therefore, **ASVS 10.4.2 is not applicable to this codebase** as the requirement specifically addresses OAuth Authorization Server responsibilities.
+
+---
+
+## Security Controls Inventory
+
+The following security controls were identified and analyzed for their relationship to OAuth Authorization Server functionality:
+
+| Control Area | Location | Purpose | ASVS 10.4.2 Coverage Status |
+|--------------|----------|---------|----------------------------|
+| **OAuth Authentication** | `pages.py` — `@asfquart.auth.require()` decorator | Enforces authentication on protected endpoints | ❌ Client-side only — delegates to external AS |
+| **Session Management** | `pages.py` — `asfquart.session.read()` in `basic_info()` | Reads session data from external OAuth framework | ❌ Consumes sessions, does not issue codes/tokens |
+| **Role-Based Authorization** | `pages.py` — `R.committer`, `R.pmc_member` decorators | Enforces role-based access control per route | ❌ Application-level authorization, not OAuth AS |
+| **LDAP Synchronization** | `asf-load-ldap.py` | Populates person database from LDAP directory | ❌ Administrative tool, no OAuth functionality |
+| **Election State Machine** | `election.py` — `_compute_state()` method | Manages election lifecycle and state transitions | ❌ Business logic, not OAuth token management |
+| **Vote Token Cryptography** | `election.py` — `crypto` module usage | Encrypts/signs votes for election integrity | ❌ Application-specific crypto, not OAuth tokens |
+
+**OAuth Flow Architecture:**
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│                    ASF OAuth AS (External)                   │
+│          ← ASVS 10.4.2 APPLIES HERE (Not Auditable)         │
+│  • Issues authorization codes                                │
+│  • Exchanges codes for tokens                                │
+│  • Enforces single-use code constraint                       │
+│  • Revokes tokens on code replay                             │
+└────────────────────────┬────────────────────────────────────┘
+                         │ OAuth tokens/sessions
+                         ▼
+┌─────────────────────────────────────────────────────────────┐
+│              asfquart.auth & asfquart.session               │
+│                  (External Library — Not Provided)           │
+│  • Validates OAuth sessions                                  │
+│  • Extracts user identity (uid, fullname, email)             │
+└────────────────────────┬────────────────────────────────────┘
+                         │ User session data
+                         ▼
+┌─────────────────────────────────────────────────────────────┐
+│              THIS CODEBASE (OAuth Client/RP)                │
+│  • pages.py — Route handlers consuming sessions              │
+│  • election.py — Business logic with auth checks             │
+│  • persondb.py — User database (not OAuth related)           │
+└─────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## Critical File Review
+
+### `pages.py` — Route Handlers (OAuth Client Role)
+
+All route handlers in this file act as OAuth clients consuming sessions from the external Authorization Server. None implement AS functionality.
+
+| Route | Line(s) | Auth Decorator | OAuth Role | ASVS 10.4.2 Relevance |
+|-------|---------|----------------|------------|----------------------|
+| `POST /do-vote/<eid>` | N/A | `@asfquart.auth.require({R.committer})` | Client consuming session | ❌ None — client-side consumption |
+| `POST /do-create-election` | N/A | `@asfquart.auth.require({R.pmc_member})` | Client consuming session | ❌ None — client-side consumption |
+| `GET /do-open/<eid>` | N/A | `@asfquart.auth.require({R.committer})` | Client consuming session | ❌ None — client-side consumption |
+| `GET /do-close/<eid>` | N/A | `@asfquart.auth.require({R.committer})` | Client consuming session | ❌ None — client-side consumption |
+| `basic_info()` helper | N/A | N/A — reads session | Session data consumer | ❌ None — reads `uid`, `fullname`, `email` |
+
+**Key Functions Reviewed:**
+
+| Function | Purpose | OAuth AS Components Present |
+|----------|---------|----------------------------|
+| `basic_info()` | Extracts user identity from session | ❌ No — reads session, doesn't issue codes |
+| `vote_on_page()` | Validates user eligibility for voting | ❌ No — application authorization, not OAuth |
+| All route handlers | Handle HTTP requests with auth | ❌ No — all use external auth decorators |
+
+### `schema.sql` — Database Schema
+
+**OAuth Authorization Server Tables Expected vs. Found:**
+
+| Expected Table (OAuth AS) | Purpose | Present in Schema |
+|---------------------------|---------|-------------------|
+| `authorization_codes` | Track issued auth codes | ❌ Not found |
+| `oauth_tokens` | Store access/refresh tokens | ❌ Not found |
+| `token_revocations` | Log revoked tokens | ❌ Not found |
+| `code_usage_log` | Detect code replay | ❌ Not found |
+
+**Actual Tables Found:**
+
+| Table | Purpose | OAuth Relevance |
+|-------|---------|----------------|
+| `persons` | User directory | ❌ None — general user data |
+| `elections` | Election metadata | ❌ None — business domain |
+| `issues` | Voting issues | ❌ None — business domain |
+| `votes` | Cast votes | ❌ None — business domain |
+
+**Conclusion:** No OAuth Authorization Server infrastructure exists in the database schema.
+
+### `election.py` — Business Logic
+
+**Cryptographic Functions Reviewed:**
+
+| Function | Line(s) | Purpose | OAuth Token Relationship |
+|----------|---------|---------|-------------------------|
+| `_compute_state()` | N/A | Calculates election state | ❌ None — state machine logic |
+| Crypto module usage | N/A | Vote encryption/signing | ❌ None — application-specific crypto |
+| Vote token generation | N/A | Creates vote verification tokens | ❌ None — not OAuth tokens |
+
+**Conclusion:** All cryptographic operations are application-level vote integrity mechanisms, unrelated to OAuth token issuance or authorization code management.
+
+### `persondb.py` — User Database
+
+**Functions Reviewed:**
+
+| Function | Purpose | OAuth AS Functionality |
+|----------|---------|----------------------|
+| Person lookup methods | Query user directory | ❌ None — read-only user data |
+| LDAP integration | Sync user data | ❌ None — identity source, not OAuth |
+
+### `asf-load-ldap.py` — LDAP Synchronization
+
+**Purpose:** Administrative script to populate the `persons` table from LDAP directory.
+
+**OAuth Relevance:** ❌ None — this is an identity data source, not an OAuth Authorization Server component.
+
+---
+
+## Findings
+
+### Critical Findings
+**No critical findings identified.**
+
+### High Findings
+**No high findings identified.**
+
+### Medium Findings
+**No medium findings identified.**
+
+### Low Findings
+**No low findings identified.**
+
+---
+
+## Non-Applicability Analysis
+
+**Evidence that ASVS 10.4.2 does not apply to this codebase:**
+
+| Indicator | File(s) | Evidence | Conclusion |
+|-----------|---------|----------|------------|
+| **No authorization endpoint** | All files | No route matching `/authorize` or similar | Cannot issue authorization codes |
+| **No token endpoint** | All files | No route matching `/token` or code exchange logic | Cannot exchange codes for tokens |
+| **No authorization code storage** | `schema.sql` | No `authorization_codes` or equivalent table | No infrastructure to track code usage |
+| **No token revocation logic** | All files | No revocation endpoint or token invalidation code | Cannot revoke tokens on code replay |
+| **Auth delegation pattern** | `pages.py` | `@asfquart.auth.require()` decorators throughout | Relies on external AS for authentication |
+| **Session consumption only** | `pages.py` | `s = await asfquart.session.read()` followed by `s['uid']` access | Reads sessions, never issues them |
+| **No OAuth libraries imported** | All files | No `oauthlib`, `authlib`, or similar imports | No OAuth server implementation |
+
+**OAuth Role Classification:**
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│  OAuth Authorization Server (ASVS 10.4.2 Target)            │
+│  ✓ Issues authorization codes                               │
+│  ✓ Validates code single-use                                │
+│  ✓ Exchanges codes for tokens                               │
+│  ✓ Revokes tokens on code replay                            │
+└─────────────────────────────────────────────────────────────┘
+                         ▲
+                         │ NOT IMPLEMENTED IN THIS CODEBASE
+                         │
+┌─────────────────────────────────────────────────────────────┐
+│  OAuth Client/Relying Party (This Codebase)                 │
+│  ✓ Redirects users to AS for authentication                 │
+│  ✓ Receives and validates OAuth sessions                    │
+│  ✓ Uses access tokens to access resources                   │
+│  ✗ Does NOT issue authorization codes                       │
+│  ✗ Does NOT exchange codes for tokens                       │
+│  ✗ Does NOT manage token lifecycle                          │
+└─────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## Positive Security Patterns
+
+Despite ASVS 10.4.2 not being applicable, the following OAuth client security patterns are correctly implemented:
+
+### 1. Consistent Authentication Enforcement
+**Location:** `pages.py` — All sensitive endpoints
+
+**Pattern:** Every protected route uses `@asfquart.auth.require()` decorators to ensure the external OAuth session is validated before processing requests.
+
+**Example:**
+```python
+@asfquart.auth.require({R.committer})
+async def do_vote(eid: str):
+    # Session automatically validated by decorator
+    result = await basic_info()  # Safely reads authenticated user
+```
+
+**Security Benefit:** Prevents unauthorized access by ensuring all sensitive operations require valid OAuth authentication from the external AS.
+
+### 2. Role-Based Access Control (RBAC)
+**Location:** `pages.py` — Route decorators
+
+**Pattern:** Differentiated privilege levels using role-specific decorators:
+- `R.pmc_member` — Higher privilege (e.g., election creation)
+- `R.committer` — Standard privilege (e.g., voting, viewing)
+
+**Security Benefit:** Implements principle of least privilege by requiring appropriate roles for sensitive operations, layered on top of OAuth authentication.
+
+### 3. Read-Only Session Consumption
+**Location:** `pages.py` — `basic_info()` function
+
+**Pattern:** Session data is consumed in a read-only manner:
+```python
+async def basic_info():
+    s = await asfquart.session.read()
+    return {
+        'uid': s['uid'],
+        'fullname': s['fullname'],
+        'email': s['email']
+    }
+```
+
+**Security Benefit:** The client never attempts to modify OAuth tokens or session state, which is the correct pattern for an OAuth client. Token lifecycle management remains the responsibility of the AS.
+
+### 4. Application-Level Authorization Checks
+**Location:** `pages.py` — `vote_on_page()` endpoint
+
+**Pattern:** Beyond OAuth authentication, the application performs additional authorization checks:
+- Verifies per-user voting eligibility via `q_find_issues`
+- Checks election state before allowing vote access
+
+**Security Benefit:** Demonstrates defense-in-depth by layering application-specific authorization on top of OAuth authentication, ensuring users can only access resources they're entitled to within the business logic context.
+
+### 5. Separation of Authentication and Identity
+**Location:** `persondb.py`, `asf-load-ldap.py`
+
+**Pattern:** User identity data (LDAP) is separated from authentication mechanisms (OAuth):
+- LDAP serves as the identity source
+- OAuth handles authentication/authorization
+- Application queries identity data as needed
+
+**Security Benefit:** Clean separation of concerns allows independent management of identity data and authentication mechanisms.
+
+---
+
+## Architecture Observations
+
+### 1. External Authorization Server Dependency
+**Observation:** The application has a complete trust relationship with the external ASF OAuth Authorization Server accessed via the `asfquart` library.
+
+**Implications:**
+- Session data from `asfquart.session.read()` is used directly for user identification without additional verification
+- This is appropriate for a client with a trusted relationship to its AS
+- However, the security of this application is bounded by the security of the external AS
+
+**Risk:** If the external AS does not properly implement ASVS 10.4.2 (authorization code single-use enforcement), this application cannot detect or mitigate authorization code replay attacks, as it operates downstream of the token issuance process.
+
+### 2. Audit Scope Limitation
+**Observation:** To fully audit ASVS 10.4.2 compliance, the following components (not included in provided files) would need examination:
+
+1. **ASF OAuth Authorization Server implementation:**
+   - Authorization endpoint code issuance logic
+   - Token endpoint code validation and exchange logic
+   - Authorization code storage and usage tracking
+   - Token revocation mechanisms on code replay
+
+2. **`asfquart.auth` library:**
+   - Session validation logic
+   - Token expiration handling
+   - Response to AS-initiated token revocations
+
+3. **`asfquart.session` library:**
+   - Session invalidation on token revocation
+   - Token refresh mechanisms
+   - Session-to-token binding
+
+**Recommendation:** Request these components for a complete ASVS 10.4.2 audit.
+
+### 3. Client-Side Security Posture
+**Observation:** The application correctly implements OAuth client security patterns:
+- Does not attempt to validate tokens directly (trusts AS validation)
+- Does not store or manage authorization codes
+- Does not implement custom token lifecycle management
+
+**Assessment:** This is the correct architecture for an OAuth client. The application appropriately delegates OAuth protocol responsibilities to the external AS and supporting libraries.
+
+### 4. No OAuth AS Infrastructure Present
+**Observation:** The database schema (`schema.sql`) contains only business domain tables (elections, votes, issues, persons) with no OAuth-related tables.
+
+**Expected OAuth AS Tables (Absent):**
+- `authorization_codes` — Track issued codes and usage
+- `oauth_clients` — Register client applications
+- `oauth_tokens` — Store access/refresh tokens
+- `token_revocations` — Log revoked tokens
+- `code_usage_audit` — Detect replay attempts
+
+**Conclusion:** The absence of these tables confirms this application does not function as an OAuth Authorization Server.
+
+### 5. Cryptographic Usage Clarification
+**Observation:** The `election.py` file uses cryptographic operations (vote tokens, salts, encryption keys), which could be confused with OAuth token management.
+
+**Clarification:** These are application-level cryptographic mechanisms for:
+- Vote encryption (ensuring vote privacy)
+- Vote integrity verification (preventing tampering)
+- Election result validation (cryptographic proof of outcomes)
+
+**Distinction:** These are entirely separate from OAuth access tokens, refresh tokens, or authorization codes. They serve the election domain logic, not authentication/authorization protocols.
+
+---
+
+## Recommendations Summary
+
+### Immediate Actions (Critical Priority)
+**None required** — No ASVS 10.4.2 violations exist in this codebase as the requirement does not apply to OAuth clients.
+
+### Short-Term Actions (High Priority)
+
+#### 1. Audit External ASF OAuth Authorization Server
+**Rationale:** This application's security depends entirely on the external AS properly implementing ASVS 10.4.2.
+
+**Action Items:**
+- Request access to ASF OAuth Authorization Server source code
+- Verify authorization code storage mechanism exists
+- Confirm single-use enforcement at token endpoint
+- Validate token revocation on code replay detection
+- Test code replay scenarios in staging environment
+
+**Verification Checklist:**
+```
+□ Authorization codes stored with usage flag in persistent storage
+□ Token endpoint checks code usage before issuing tokens
+□ Second code usage attempt returns error (invalid_grant)
+□ All tokens issued with replayed code are revoked
+□ Revocation propagates to all resource servers
+□ Audit log records code replay attempts
+```
+
+#### 2. Audit `asfquart.auth` and `asfquart.session` Libraries
+**Rationale:** These libraries mediate between the AS and this application. They must correctly handle token lifecycle events.
+
+**Action Items:**
+- Review session validation logic in `asfquart.auth`
+- Verify token expiration handling
+- Confirm session invalidation on AS-initiated revocations
+- Test behavior when AS revokes tokens due to code replay
+
+**Verification Checklist:**
+```
+□ Library validates token expiration timestamps
+□ Expired tokens trigger re-authentication flow
+□ Revoked tokens result in session termination
+□ No caching of revoked tokens
+□ Proper error handling for invalid tokens
+```
+
+### Long-Term Actions (Medium Priority)
+
+#### 3. Document OAuth Architecture and Trust Boundaries
+**Rationale:** Clear documentation prevents future confusion about OAuth responsibilities and security boundaries.
+
+**Action Items:**
+- Create architecture diagram showing OAuth flow
+- Document which components are responsible for ASVS 10.4.2
+- Clarify trust assumptions about external AS
+- Define security requirements for `asfquart` library upgrades
+
+**Deliverable:** Security architecture document including:
+```
+- OAuth component diagram with trust boundaries
+- ASVS requirement mapping to components
+- Threat model for external AS compromise
+- Incident response procedures for OAuth vulnerabilities
+```
+
+#### 4. Implement Client-Side Security Monitoring
+**Rationale:** While the client cannot enforce ASVS 10.4.2, it can detect anomalies suggesting AS compromise.
+
+**Action Items:**
+- Log all authentication failures with details
+- Monitor for unusual session invalidation patterns
+- Alert on repeated authentication failures for same user
+- Track session duration anomalies
+
+**Metrics to Monitor:**
+```
+- Authentication failure rate (spike may indicate AS issue)
+- Session invalidation rate (unexpected revocations)
+- Re-authentication frequency (token refresh failures)
+- User complaints about forced logouts (possible revocations)
+```
+
+#### 5. Establish OAuth Dependency Review Process
+**Rationale:** Changes to external AS or `asfquart` library could introduce security regressions.
+
+**Action Items:**
+- Subscribe to ASF OAuth security announcements
+- Review `asfquart` release notes for security changes
+- Test authentication flows after library upgrades
+- Maintain staging environment mirroring production OAuth config
+
+---
+
+## Appendix: Files Analyzed
+
+<details>
+<summary><strong>Click to expand full file list (5 files)</strong></summary>
+
+### Files Analyzed with OAuth Relevance Assessment
+
+| # | File Path | Relevance Score | OAuth AS Components | Analysis Summary |
+|---|-----------|----------------|---------------------|------------------|
+| 1 | `v3/schema.sql` | 10/10 | ❌ None | Database schema review — no OAuth tables present |
+| 2 | `v3/server/bin/asf-load-ldap.py` | 10/10 | ❌ None | LDAP sync script — identity source, not OAuth AS |
+| 3 | `v3/server/pages.py` | 10/10 | ❌ None | Route handlers — OAuth client consuming sessions |
+| 4 | `v3/steve/election.py` | 10/10 | ❌ None | Business logic — application crypto, not OAuth tokens |
+| 5 | `v3/steve/persondb.py` | 10/10 | ❌ None | User database — identity storage, not OAuth AS |
+
+### Detailed File Analysis
+
+#### 1. `v3/schema.sql`
+**Purpose:** Database schema definition for election system
+
+**OAuth-Related Analysis:**
+- ✅ Reviewed all table definitions
+- ❌ No `authorization_codes` table
+- ❌ No `oauth_tokens` table
+- ❌ No `oauth_clients` table
+- ❌ No token revocation tables
+
+**Tables Present:**
+- `persons` — User identity data
+- `elections` — Election metadata
+- `issues` — Voting issues
+- `votes` — Cast votes
+- Supporting tables for election domain
+
+**Conclusion:** Pure business domain schema with no OAuth Authorization Server infrastructure.
+
+#### 2. `v3/server/bin/asf-load-ldap.py`
+**Purpose:** Administrative script to synchronize user data from LDAP to local database
+
+**OAuth-Related Analysis:**
+- ✅ Reviewed all functions
+- ❌ No authorization code generation
+- ❌ No token issuance logic
+- ❌ No OAuth endpoints
+
+**Functions Reviewed:**
+- LDAP connection and query logic
+- Person record creation/update
+- Database synchronization
+
+**Conclusion:** Identity data source only — not part of OAuth flow.
+
+#### 3. `v3/server/pages.py`
+**Purpose:** HTTP route handlers for web application
+
+**OAuth-Related Analysis:**
+- ✅ Reviewed all routes and decorators
+- ✅ Identified `@asfquart.auth.require()` pattern (client-side)
+- ❌ No `/authorize` endpoint
+- ❌ No `/token` endpoint
+- ❌ No authorization code issuance
+- ❌ No code-to-token exchange
+
+**Key Functions Reviewed:**
+- `basic_info()` — Reads session data (client behavior)
+- `vote_on_page()` — Application authorization check
+- `do_vote()` — Protected route with auth decorator
+- `do_create_election()` — Protected route with role check
+- All other route handlers
+
+**Conclusion:** OAuth client/relying party consuming sessions from external AS.
+
+#### 4. `v3/steve/election.py`
+**Purpose:** Election business logic and state management
+
+**OAuth-Related Analysis:**
+- ✅ Reviewed all methods and crypto usage
+- ❌ No OAuth token generation
+- ❌ No authorization code handling
+- ❌ Crypto operations are vote-specific, not OAuth tokens
+
+**Functions Reviewed:**
+- `_compute_state()` — State machine logic
+- Vote encryption methods
+- Vote token generation (application-level, not OAuth)
+- Election lifecycle management
+
+**Conclusion:** Business logic with application-specific cryptography, unrelated to OAuth Authorization Server responsibilities.
+
+#### 5. `v3/steve/persondb.py`
+**Purpose:** User database access layer
+
+**OAuth-Related Analysis:**
+- ✅ Reviewed all methods
+- ❌ No OAuth token storage
+- ❌ No authorization code tracking
+- ❌ Read-only user identity queries
+
+**Functions Reviewed:**
+- Person lookup methods
+- LDAP integration points
+- User data retrieval
+
+**Conclusion:** Identity data access layer, not involved in OAuth token lifecycle.
+
+</details>
+
+---
+
+## Audit Certification
+
+This audit confirms that **ASVS 10.4.2 is not applicable** to the `apache/steve` codebase as it functions as an OAuth client/relying party, not an OAuth Authorization Server. 
+
+To achieve ASVS 10.4.2 compliance for the complete authentication system, the external ASF OAuth Authorization Server and supporting `asfquart` libraries must be audited separately.
+
+**Audit Completed:** Apr 21, 2026  
+**Auditor:** Tooling Agents  
+**Methodology:** Manual source code review with OAuth architecture analysis
+
+---
+
+*End of Report*
\ 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