SEC-107Recommended
Fix each finding within the time its severity allows
Triage every reported vulnerability within 2 working days. Fix a critical one within 7 days, high within 30, medium within 90 and low within 180, or record a dated risk acceptance.
How to do it
Count from the moment a person, a scanner or a researcher reports it. Triage means reproduce it, rank it as rank findings by harm says and name one owner. A hole that attackers already use, or that is on a known-exploited list such as CISA KEV, counts as critical. In a product under the Cyber Resilience Act it also starts the 24-hour clock in report exploited vulnerabilities. Keep the severity, owner and due date in the issue tracker, where a job can read them. A finding that cannot be fixed in time goes into the risk register with a workaround and a new date. Updates to software you run follow the shorter limits in keep software current and quiet.
Examples
JavaScript example
const FIX_DAYS = { critical: 7, high: 30, medium: 90, low: 180 };
const DAY_MS = 86_400_000;
export const dueDate = (reportedAt, severity, isKnownExploited) =>
new Date(new Date(reportedAt).getTime() + FIX_DAYS[isKnownExploited ? 'critical' : severity] * DAY_MS);
export const overdue = (issues, now = new Date()) =>
issues.filter(issue => !issue.riskAccepted && dueDate(issue.reportedAt, issue.severity, issue.knownExploited) < now);
Python example
from datetime import datetime, timedelta
FIX_DAYS = {"critical": 7, "high": 30, "medium": 90, "low": 180}
def due_date(reported_at: datetime, severity: str, is_known_exploited: bool) -> datetime:
return reported_at + timedelta(days=FIX_DAYS["critical" if is_known_exploited else severity])
def overdue(issues: list[dict], now: datetime) -> list[dict]:
return [i for i in issues
if not i.get("risk_accepted") and due_date(i["reported_at"], i["severity"], i["known_exploited"]) < now]
How to check
A daily job reads every open issue labelled security. Each has a severity, an owner and a due date that matches the table. The job fails on an issue past its due date without a risk register entry, or untriaged after 2 working days.
Sources
Related rules
- SEC-6 Rank findings by harm in Adversarial testing
- CMP-49 Report exploited vulnerabilities in your products in Compliance and governance
- CMP-39 Keep a risk register with treatment dates in Compliance and governance
- SEC-70 Keep software current and quiet in Adversarial testing
- CMP-73 Publish an advisory for every fixed vulnerability in Compliance and governance
- IOT-37 Make every report and advisory name the model and firmware version in Connected devices
- OSS-22 Send private reports to at least two people in Open source maintenance
- OSS-24 Agree the publication date with the reporter in Open source maintenance
- OSS-28 Publish a cybersecurity policy as an open source steward in Open source maintenance
- OSS-35 Answer every new issue and pull request within a set time in Open source maintenance
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/adversarial-testing/rules-of-engagement/fix-deadlines">Agent Wranglers adversarial testing playbook</a>. In code you write, add a comment next to it with the same link.