Bug Description
When a PR is linked to a P1 issue and then the issue reference is removed or replaced with a non-existing issue number, the p1 label remains on the PR. This allows someone to game the priority ranking system.
Reproduction Steps
Step 1: Link PR to real P1 issue
Step 2: pr-labeler runs → copies p1 label to PR
Step 3: Edit PR, replace real issue with non-existing issue (e.g. closes #99999999)
Step 4: pr-labeler runs again → p1 label STAYS (should be removed/reset)
Flow Diagram
┌─────────────────────────────────────────────────────────────────────────┐
│ EXPECTED BEHAVIOR │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ PR body: "closes #123" PR body: "closes #99999999" │
│ (real P1 issue) (non-existing issue) │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ pr-labeler │ │ pr-labeler │ │
│ │ runs │ │ runs │ │
│ └──────┬──────┘ └────────┬────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ PR gets p1 │ │ PR p1 REMOVED │ ← should happen │
│ │ label │ │ (reset to p2) │ │
│ └─────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ ACTUAL BEHAVIOR (BUG) │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ PR body: "closes #123" PR body: "closes #99999999" │
│ (real P1 issue) (non-existing issue) │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ pr-labeler │ │ pr-labeler │ │
│ │ runs │ │ runs │ │
│ └──────┬──────┘ └────────┬────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ PR gets p1 │ │ 404 error OR │ │
│ │ label │ │ empty issueLabels│ │
│ └─────────────┘ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Fallback keeps │ ← BUG │
│ │ existing p1! │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Root Cause
Two issues in src/copy-issue-labels.ts:
1. No error handling for non-existing issues
issueLabels() calls the GitHub API without try/catch. A non-existing issue returns a 404, which causes Promise.all() to reject, aborting the entire operation — no labels are modified.
// This throws 404 for non-existing issues, crashing the whole flow
const issueLabels = new Set(
(await Promise.all(references.map((issue) => this.issueLabels(issue)))).flat(),
);
2. Fallback logic preserves existing PR priority
Even if the 404 were handled gracefully, highestPriorityLabel() falls back to the PR's current label:
private highestPriorityLabel(issueLabels, pullLabels): string {
return this.priorityLabels.find(l => issueLabels.has(l)) // 1. from issue
?? this.priorityLabels.find(l => pullLabels.has(l)) // 2. keep PR existing ← BUG
?? this.priorityLabels[this.priorityLabels.length-1]; // 3. default lowest
}
Security Concern
This can be exploited to artificially inflate PR priority in ranking/dashboards without detection — a user links a P1 issue, gets the label, then swaps to a bogus issue reference.
Suggested Fix
- Wrap
issueLabels() in try/catch — return [] for non-existing issues
- When no valid linked issues exist (all references are invalid), reset priority to lowest rather than preserving the current PR label
Reported from: aws/aws-cdk repo usage of this action in .github/workflows/pr-labeler.yml
Bug Description
When a PR is linked to a P1 issue and then the issue reference is removed or replaced with a non-existing issue number, the
p1label remains on the PR. This allows someone to game the priority ranking system.Reproduction Steps
Flow Diagram
Root Cause
Two issues in
src/copy-issue-labels.ts:1. No error handling for non-existing issues
issueLabels()calls the GitHub API without try/catch. A non-existing issue returns a 404, which causesPromise.all()to reject, aborting the entire operation — no labels are modified.2. Fallback logic preserves existing PR priority
Even if the 404 were handled gracefully,
highestPriorityLabel()falls back to the PR's current label:Security Concern
This can be exploited to artificially inflate PR priority in ranking/dashboards without detection — a user links a P1 issue, gets the label, then swaps to a bogus issue reference.
Suggested Fix
issueLabels()in try/catch — return[]for non-existing issuesReported from: aws/aws-cdk repo usage of this action in
.github/workflows/pr-labeler.yml