andrewmusselman opened a new issue, #770:
URL: https://github.com/apache/tooling-trusted-releases/issues/770
**Source:** ASVS 2.3.1 — Finding 3.1
**CWE:** CWE-841 (Improper Enforcement of Behavioral Workflow)
**Location:** `atr/storage/writers/vote.py`, lines 100–127
#### Description
The `resolve_manually()` method allows transitioning a release from
`RELEASE_CANDIDATE` to `RELEASE_PREVIEW` without verifying that:
1. The release was configured for manual voting (`vote_manual` flag)
2. An actual vote occurred
3. Minimum vote requirements were met
4. Minimum vote duration has elapsed
A committee member could create a release draft, promote it to the candidate
phase, and immediately call `resolve_manually(vote_result="passed")` to skip
the entire vote process.
Also related:
### Podling two-round vote can be bypassed via manual resolution
**Source:** ASVS 2.3.1 — Finding 3.2
**CWE:** CWE-841 (Improper Enforcement of Behavioral Workflow)
**Location:** `atr/storage/writers/vote.py`, lines 100–127
#### Description
For podling projects, ASF policy requires two voting rounds: first by the
PPMC, then by the Incubator PMC. The `resolve_release()` method handles this
correctly by initiating a second vote when the first passes. However,
`resolve_manually()` contains no podling check and can transition directly to
`RELEASE_PREVIEW`, skipping the Incubator PMC vote entirely.
#### Recommendation
@dave2wave will test that PPMC voting works
### Vote thread URL validation insufficient (SSRF risk)
**Labels:** `ASVS`, `security`, `L1`
**Source:** ASVS 2.2.1 Finding HIGH-003, ASVS 2.2.2 Finding 2
**CWE:** CWE-918 (Server-Side Request Forgery)
**Location:** `atr/post/manual.py`, lines 37–42 and 56–66
#### Description
The manual vote resolution endpoint extracts thread IDs from user-provided
URLs using `removeprefix()`. This method does not validate that the URL
actually starts with the expected prefix — if it doesn't, the full original URL
is returned unchanged and may be used to fetch remote content, creating an SSRF
vector.
#### Affected Code
```python
vote_thread_id =
vote_thread_url.removeprefix("https://lists.apache.org/thread/")
# If URL doesn't start with prefix, original URL is returned unchanged
```
#### Recommendation
- Validate that URLs start with `https://lists.apache.org/thread/` using
`startswith()` before extraction
- Validate the thread ID portion matches expected format (e.g., alphanumeric)
--
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]