asf-tooling opened a new issue, #1060:
URL: https://github.com/apache/tooling-trusted-releases/issues/1060
**ASVS Level(s):** L2-only
**Description:**
### Summary
Quart's default SecureCookieSessionInterface serializes session data as
JSON, optionally compresses it, base64-encodes it, and HMAC-signs it using the
application secret_key. The payload is signed but not encrypted—the
base64-encoded data can be decoded by anyone with access to the raw cookie
value. The session cookie stores the complete user profile from the OAuth
provider without field filtering, including: `uid`, `dn` (LDAP Distinguished
Name), `fullname` (PII), `email` (PII), `isMember/isChair/isRoot`
(authorization flags), `pmcs` (committee memberships), `projects` (project
memberships), `mfa` (security configuration), and `metadata.admin` (admin
impersonation identity). ASVS 14.3.3 permits session tokens in cookies but not
other sensitive data.
### Details
The issue exists in `src/asfquart/generics.py` lines 81-82,
`src/asfquart/session.py` lines 86-96, and `atr/admin/__init__.py` lines
130-157. The session cookie is the session state, containing PII and
authorization details in a signed-but-readable format.
### Recommended Remediation
**Option A (Preferred):** Implement server-side sessions using a server-side
session store:
```python
# Use quart-session with Redis or database backend
from quart_session import Session
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = redis_client
Session(app)
# Only session ID is stored in cookie, data is server-side
```
**Option B:** Encrypt the session cookie payload:
```python
from cryptography.fernet import Fernet
class EncryptedSessionInterface(SecureCookieSessionInterface):
def __init__(self, encryption_key: bytes):
self.fernet = Fernet(encryption_key)
super().__init__()
def save_session(self, app, session, response):
# Encrypt before signing
serialized = self.get_signing_serializer(app).dumps(dict(session))
encrypted = self.fernet.encrypt(serialized.encode())
# ... set cookie with encrypted data
```
**Option C (Minimum):** Allowlist session fields to store only essential
data:
```python
# Store only uid, cts, uts in cookie
# Perform authorization lookups server-side on each request using uid
ALLOWED_SESSION_FIELDS = {'uid', 'cts', 'uts'}
def write_session(session_data: dict):
filtered_data = {k: v for k, v in session_data.items() if k in
ALLOWED_SESSION_FIELDS}
# Store filtered_data in cookie
```
### Acceptance Criteria
- [ ] Server-side session store implemented OR session encryption added OR
field allowlist implemented
- [ ] PII and authorization data no longer readable in cookie
- [ ] Unit tests verify cookie content is not readable
- [ ] Unit tests verify session functionality works with new approach
- [ ] Integration tests verify authentication and authorization work
- [ ] Performance impact assessed and acceptable
- [ ] Documentation updated with session storage approach
### References
- Source reports: L2:14.3.3.md
- Related findings: FINDING-305
- ASVS sections: 14.3.3
### Priority
Medium
---
---
**Related issue:**
https://github.com/apache/tooling-trusted-releases/issues/1035
---
**Triage notes:** wipe isRoot on atr side, related to
https://github.com/apache/tooling-trusted-releases/issues/1035
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]