Security Findings Management and Remediation Tracking Questions
Managing the lifecycle of security and compliance findings from identification through closure. Covers triaging and prioritizing findings and large backlogs by business impact, assigning ownership, designing tracker states and remediation ticket workflows with SLAs, escalation and time-bound risk-accepted exceptions, tracking remediation to completion, verifying fixes and choosing a retest approach, ingesting, deduplicating and normalizing findings across scanners and manual tests, and turning post-incident and vendor-blocked issues into tracked, prioritized remediation plans. Also covers reporting on remediation status, aging and program metrics (and how those metrics get misread), building auditor-ready evidence and mapping findings to compliance controls, scripting and querying remediation data, and writing the findings report itself: structure for developer and executive audiences, reproducible evidence, remediation guidance and safe handling of exploit proof. Discovering vulnerabilities and scoring them are out of scope.
Design a remediation SLA policy for an engineering organization. How do you set the windows, decide when the clock starts and pauses, define escalation, allow exceptions, and get engineering leaders to accept and follow it?
Sample Answer
Direct answer
A remediation SLA (service-level agreement, here an internal promise about how fast a finding must be fixed) works when it is tied to real exposure, has clear start, pause and stop rules, and comes with an escalation ladder (a series of increasingly senior people notified as a deadline slips) and a time-boxed exception path (a controlled way to be late, covered in section 4). I would set windows by severity adjusted for exploitability and exposure, pilot with a few engineering leaders, and publish compliance as a shared number instead of a security-only stick.
1. Setting the windows
Start from severity, then let context move a finding up or down a tier. Severity alone (for example a CVSS score, the Common Vulnerability Scoring System 0-10 rating) ignores whether anyone can actually reach the flaw.
| Tier | Example trigger | Example window |
|---|---|---|
| P0 | Known to be exploited in the wild (for example listed in the US Cybersecurity and Infrastructure Security Agency's Known Exploited Vulnerabilities catalog), or critical and internet-facing | 7 days, or a same-week mitigation |
| P1 | High severity, or critical but internal only | 30 days |
| P2 | Medium | 90 days |
| P3 | Low | Next planned maintenance, reviewed twice a year |
These numbers are illustrative starting points, not a standard. Calibrate them against the fix capacity teams actually have: a window that teams miss 80% of the time teaches everyone to ignore the policy.
2. When the clock starts, pauses and stops
- Start: when the finding is validated (a person has confirmed it is real and reachable, not just a scanner alert that may be a false positive; not when a scanner first emits it), and validation itself has a short window, for example 2 business days, so a finding cannot sit unowned.
- Pause: only for reasons outside the owner's control and only with a recorded reason, such as waiting on a vendor patch (which moves to the exception path with a compensating control, meaning a substitute safeguard that lowers the risk while the real fix is pending). Never pause for "team is busy".
- Stop: when the fix is verified by a rescan or retest, not when the developer clicks "done". A fix that fails verification does not stop the clock.
3. Escalation
Tie each rung to a fraction of the window: at 50% the owner gets a reminder, at 100% (breach) the team manager is notified, at breach plus 7 days the director, at breach plus 14 days the VP or CISO (chief information security officer), and at that point the choice is fix it or sign a risk acceptance (a written decision by a senior business owner to live with the risk for a limited time, detailed in section 4).
4. Exceptions
A risk acceptance is a written decision that the business will live with a known risk. Require: the compensating control, a named approver whose seniority grows with severity, an expiry no longer than 90 days, and automatic reopening at expiry. Publish the count of active exceptions so they are visible, not a back door.
5. Getting leaders to follow it
- Co-design with two or three engineering leaders and ask them what they can hit, before publishing.
- Pilot on one organization for a quarter, starting with P0 and P1 only, then widen.
- Give them what they need to comply: an owner mapped to every asset, auto-created tickets, and dependency-update pull requests.
- Report compliance per team on a shared dashboard and give teams room to plan the work into the roadmap.
A co-design conversation sounds like this: "Last quarter your team closed about 10 high findings a month, and we have 25 open. A 30-day window would put you in breach on 15 of them. What window can you hit if security auto-opens the tickets and handles retesting, which means we rerun the original test to confirm each fix, and which findings would you want us to treat as P0?" Setting the window from a real throughput number, here 10 fixes a month against 25 open, is what makes leaders agree.
Worked example
A critical, internet-facing flaw is validated on day 0. It is P0 with a 7-day window. Day 3 (about 50%): reminder to the owner. Day 7: breach, the manager is notified. The team says a vendor library has no patch yet, so the clock moves to the exception path: a web application firewall rule blocks the exploit pattern, the VP of Engineering signs an acceptance that expires on day 30, and the ticket reopens automatically on day 30 if the patch has not landed.
Trade-offs and pitfalls
- Shorter windows look tough but increase breach volume and exception requests. If the backlog exceeds capacity, tighten the tier definitions (only exploited or exposed items are P0) instead of shrinking the windows.
- Counting only closed findings hides overdue ones, so measure open overdue items too.
- A policy the security team wrote alone gets exceptioned to death. What would change my call: if leaders still cannot comply after the pilot, I would treat that as a capacity problem and escalate it, not quietly relax the windows.
An auditor asks you to prove a remediation item was completed and verified. What evidence do you hand over, in what form, and how long do you keep it?
Sample Answer
Direct answer
I hand over a small, indexed evidence package that proves three things in order: the problem existed, a change was made, and an independent check showed the problem is gone. I give it as tamper-evident files (files where any later edit would be visible; exports, not screenshots pasted into a slide deck), and I keep it for the period set by our retention policy (the written rule for how long each kind of record is stored before deletion) and the strictest framework we are audited against, not a number I invent on the spot. In practice I would say to the auditor: "we keep remediation evidence for three years" (an illustrative policy: it covers the current audit period, the prior period an auditor compares against, and a buffer).
What goes in the package (an auditor wants a chain, not a pile)
| Link in the chain | Evidence | Form |
|---|---|---|
| The finding | Original report entry: ID, severity, affected asset, date found, who found it | Export from the findings tracker with timestamps |
| The decision | Owner assigned, due date, any approved extension | Ticket history export |
| The change | Change record, code review or pull request, deployment or config change ID, who approved and when | Links plus PDF/JSON exports |
| The verification | Retest (run the same test again after the fix, to see whether the problem still reproduces) by someone other than the fixer: same test that found the issue, now failing to reproduce it | Raw scanner or tool output plus the tester's short sign-off |
| The closure | Who closed it, when, and that the retest predates closure | Ticket history export |
One index page lists each item with its date and a checksum (a fingerprint of the file, such as SHA-256, that changes if anyone edits the file).
Worked example (illustrative)
Finding F-2041: an API host on api.example.com accepted an outdated TLS (the encryption used for web traffic) version. Found 3 March, due 2 April. The package holds: the March scan export showing the old version enabled; change ticket CHG-778 (config change, approved by the service owner, deployed 20 March); a rescan export dated 22 March showing only current versions accepted, run by the security team and not by the engineer who made the change; and the ticket history showing closure on 23 March. The auditor can check each date follows the previous one, and 20 days of a 30-day window were used.
Retention and handling
- Retention: follow the written policy. If none exists, propose one and get it approved; I would not quote a number as if a standard mandated it. For example, PCI DSS (the payment-card security standard) asks for at least 12 months of audit log history, with the most recent 3 months immediately available, while SOC 2 (an audit of a service company's controls) and ISO 27001 (an information-security management standard) set no fixed number but auditors expect evidence across the whole audit period, commonly 12 months. Check the current text of the framework that applies to you. Some frameworks require a minimum period of log or evidence history, and audit cycles usually need the current plus the prior period, so set the policy to the longest of what applies to you.
- Store in write-once or versioned storage (files cannot be overwritten, or every past version is kept) with restricted access, so the package cannot quietly change after the fact.
- Redact secrets, tokens and customer data from screenshots and logs before they go in.
Pitfalls
- Closing on the developer's say-so with no independent retest: the auditor sees an assertion, not proof.
- Evidence with no dates, or a retest dated after closure.
- Screenshots with no source: an auditor cannot tell what system or time they came from.
Three findings landed on a payment microservice. How do you turn each into a business-impact ranking, and what context do you gather about the service and data before ordering them?
Sample Answer
Direct answer
I rank findings by how much business harm each could cause, not by the scanner's severity label. That needs six kinds of context: three core ones (the service and how exposed it is, the data it touches, and how easy the flaw is to exploit) plus three further checks (the controls already in place, the blast radius, and the fix cost and timing). All six are listed below. Then I combine likelihood and impact into an ordering I can defend.
Context to gather first
- The service: is it internet-facing or internal, what calls it, who owns it, how much money flows through it, and what happens if it is down or abused.
- The data: does it handle cardholder data (card numbers, in scope of the Payment Card Industry Data Security Standard, PCI DSS), personal data, or only internal identifiers?
- Exploitability: does a public exploit exist, must the attacker be logged in, is the vulnerable code path actually reachable?
- Existing controls: a web application firewall (WAF), network segmentation, monitoring that would detect abuse.
- Blast radius: what an attacker could reach after the flaw, such as other services or customer accounts.
- Fix cost and timing: a one-line change versus a redesign, and any upcoming audit or launch.
Worked example on a payment service (illustrative)
| Finding | Likelihood (1-5) | Impact (1-5) | Score = L x I |
|---|---|---|---|
| A: Changing an order ID in the public API returns another customer's payment details (an insecure direct object reference, IDOR) | 4 | 5 | 20 |
| B: Critical-rated flaw (CVSS, the 0-10 Common Vulnerability Scoring System, score 9.8) in a JSON library used only by an offline reconciliation job that never processes outside input | 1 | 4 | 4 |
| C: Public error pages show stack traces with internal hostnames and library versions | 3 | 1 | 3 |
- A ranks first. It is public, needs only a normal account, and exposes payment data. Hotfix this sprint.
- B ranks second despite the highest scanner score. Likelihood is 1 because the vulnerable path receives no untrusted input. I would confirm that by reading the code, then still upgrade the library inside the normal critical window, because it is a cheap fix and inputs can change.
- C ranks third. Low impact on its own, but it helps an attacker map the system, and it is a quick fix to bundle with A.
The 1-5 scales are a simple aid I define with the team, not a standard, and the point is that the reasoning is written down so it can be challenged.
What would flip the order
If the reconciliation job began accepting uploaded files, B would jump to first. If a WAF rule already blocked A's abuse pattern, A would still be fixed first, but less urgently than an emergency.
Pitfalls
- Trusting CVSS alone is the classic error: it scores the flaw in the abstract, not in your environment.
- Ranking without the owner's input misses facts only they know, such as a batch job that is about to become internet-facing.
Design a lightweight evidence package and dashboard for auditors showing remediation closure status. What artifacts are needed, how is evidence collected automatically, and how do you handle evidence that has to be gathered by hand?
Sample Answer
Direct answer
Build an evidence chain, not a folder of screenshots: control (a rule the organisation promises to follow, for example "critical patches are applied within 14 days"), then finding, then remediation ticket, then proof of the fix, each linked by an ID and stamped with who and when. Let systems that already know the answer (the scanner, the ticketing tool, the deployment pipeline) write evidence automatically into a write-once store. Handle manual evidence as a labelled, reviewed, expiring exception that the dashboard shows separately, so auditors can see exactly how much of the story rests on human attestation.
Artifacts needed (the package an auditor opens)
| Artifact | What it proves | Source |
|---|---|---|
| Finding record (ID, severity, asset, discovered date, mapped control) | The issue was identified and classified | Scanner or pen test import |
| Remediation ticket (owner, due date, status history) | Someone owned it and it moved | Ticketing system webhook |
| Fix evidence (change/deploy record, config diff, patch version) | A change was actually made | CI/CD pipeline, config snapshot |
| Verification evidence (a clean rescan, meaning the scanner run again, or a retest by the pentester, for the same asset and check) | The fix worked | Scanner rescan, tester retest note |
| Exception record (a risk acceptance: a signed decision to live with a risk for a stated time, with approver, expiry date, and compensating control, a temporary safeguard that reduces the risk) | Anything not fixed was knowingly decided | GRC or ticket workflow |
| Closure summary (period, counts, methodology, data cut-off time) | How the dashboard numbers were produced | Generated report, hash recorded |
Automated collection
- Webhooks (the ticketing tool automatically calling our endpoint whenever a ticket changes) or nightly pulls copy ticket state changes and scanner results into an evidence store with a timestamp, source system, and SHA-256 hash of each file. A hash is a fingerprint of the file's bytes: if anyone later edits the file, recomputing the hash gives a different value, so an auditor can prove the file is unchanged.
- Storage is append-only (new records can be added, old ones cannot be altered) with a retention lock (write-once object storage or a locked bucket that refuses deletion until a date), so nobody can edit history after the audit window opens.
- A ticket cannot move to "Closed" unless a verification artifact for the same finding ID exists. That rule (a workflow gate) creates the evidence as a side effect of doing the work. The one deliberate exception is proof that only a person can supply: such an item may close as "closed, verification pending review" so the fix is not blocked on a reviewer, and it sits in the "Closed but unverified" bucket until the second person signs off. That is why the worked example below has 3 closed-but-unverified items even though the gate exists.
- Each evidence file carries the finding ID in its metadata, which is what lets the dashboard join everything.
What one evidence record looks like (illustrative)
finding_id: F-2041 (control: patch critical within 14 days; asset: billing-api)
ticket: SEC-2210, owner ana, opened 2026-09-01, closed 2026-09-12
fix evidence: deploy record D-88213, package version 3.4.1
verification: rescan 2026-09-13, result clean, file rescan-F-2041.pdf
sha256: a3f9... (64 hex characters, recorded at upload)
evidence_source: automated
collected_at: 2026-09-13T02:10:00Z
Handling evidence gathered by hand
- Manual evidence is an attestation (a person stating in writing that something is true). Some proof is inherently manual: a physical access review, a vendor's letter, a screenshot from a system with no API. Give it a form with required fields (finding ID, collector, date, what the file shows), a second person as reviewer, and an expiry (stale attestations decay).
- Tag it
evidence_source = manualand show the manual share on the dashboard. Auditors will sample it more heavily, so make it easy to defend. - Automate the reminder, not the judgement: overdue manual-evidence tasks appear as tickets with an owner.
Dashboard (one screen)
- Closure status by severity: open, fix in progress, closed and verified, closed but unverified, risk-accepted.
- Timeliness against the SLA (service-level agreement, the fix-by deadline for each severity), plus aging buckets of open items.
- Evidence completeness: share of closed findings with verification evidence, split automated versus manual.
- Data freshness stamp (last sync time), so nobody presents stale numbers.
Mock of the one screen using the worked example below (60 findings): Closed and verified 45 | Closed but unverified 3 | Fix in progress 9 | Risk-accepted 3 | Verified closure 75% | Evidence completeness 93.75% | Manual evidence 8 of 48 closed (5 reviewed, 3 waiting) | Data as of 2026-09-28 02:00.
Worked example (illustrative numbers)
Sixty in-scope findings in the quarter. 48 are closed; 40 of those have an automatic clean rescan and 8 need manual proof, of which 5 have been reviewed and 3 are waiting. Closed-and-verified = 40 + 5 = 45, so verified closure = 45 / 60 = 75%, and evidence completeness = 45 / 48 = 93.75% of closed items. The dashboard shows the 3 waiting items by name, which turns an audit gap into a visible to-do.
Trade-offs and pitfalls
- Building a full GRC platform (governance, risk and compliance software that manages policies, controls and audits) is overkill for a "lightweight" ask: a ticket system, a scanner API, and a locked bucket cover most needs.
- Automation captures that a fix was deployed, not that it was correct; keep independent verification (rescan) as the closing proof.
- Do not let the dashboard quietly redefine "closed"; version the definitions.
- Screenshots contain secrets and personal data; redact before storing.
You are setting up the lifecycle for security findings in a new tracker. Which states and transitions would you define, where would you put automated gates, and how would you catch findings that get stuck between states?
Sample Answer
Direct answer
I define a small number of states that each mean one verifiable thing, allow only the transitions that reflect real progress, put automated gates where a state change needs proof, and run a scheduled check that flags any finding whose age in a state exceeds a limit or whose tracker state disagrees with the scanner.
States and transitions
stateDiagram-v2
[*] --> New
New --> Triaged: validated
New --> FalsePositive: not real
New --> Duplicate: merged
Triaged --> Assigned: owner set
Assigned --> InProgress: work starts
InProgress --> FixDeployed: change released
FixDeployed --> Verified: rescan or retest clean
FixDeployed --> Assigned: still vulnerable
Verified --> Reopened: regression seen
Reopened --> Assigned
Triaged --> RiskAccepted: approved with expiry
RiskAccepted --> Assigned: expiry reached
Verified --> [*]
FalsePositive --> [*]
Reading the diagram (it is Mermaid, a text format that renders as a state diagram): follow one finding. It starts New, is validated (Triaged, meaning someone confirmed it is real and rated it), gets an owner (Assigned), work begins (InProgress), the fix ships (FixDeployed), and a clean rescan makes it Verified, the normal end of the path (Verified can still be left through Reopened if a regression appears). If the rescan still finds it, it goes back to Assigned. A regression is a fixed flaw coming back in a later scan, which sends it from Verified to Reopened. The state names in the diagram (InProgress, FixDeployed, RiskAccepted) are the same states as fix_in_progress, fix_deployed and accepted_risk in the code below, written in the database style. A gate is an automatic check that blocks a state change until a condition is met.
Where automated gates go
- Intake gate: no move to Assigned until an owner is mapped from asset ownership data and required fields (severity, asset, evidence) are present. Duplicates are merged automatically by matching asset and finding type.
- Verification gate: a finding cannot reach Verified without attached evidence: a clean rescan or a retest record (a tester's confirmation the fix works). Developers can move it to FixDeployed, but only the scanner or security can verify.
- Risk acceptance gate: (a risk acceptance is a signed decision to live with a risk for a limited time) requires an approver, a compensating control (another safeguard that reduces the risk while it stays open) and an expiry, and expiry returns the finding to Assigned automatically.
- Release gate: the deployment pipeline blocks new critical findings in code being released, with a time-boxed exception path.
Catching findings stuck between states
Two checks run daily. First, a per-state age limit. Second, drift detection: (drift means the tracker and the scanner disagree) tracker says Verified but the scanner still sees the finding, so reopen it; tracker says open but the scanner no longer sees it, so prompt verification.
Runnable example of the age-limit check (Python 3, built-in sqlite3). The limits are illustrative and follow the urgency of each state: triaged is 5 days because assigning an owner is quick, fix_in_progress 60 days because real engineering takes time, fix_deployed 14 days because a rescan is quick, and accepted_risk 180 days because acceptances are periodically re-reviewed:
import sqlite3
db = sqlite3.connect(":memory:")
db.execute("""CREATE TABLE findings(
id INTEGER PRIMARY KEY, state TEXT, state_changed DATE)""")
db.executemany("INSERT INTO findings VALUES (?,?,?)", [
(101, "triaged", "2026-08-28"),
(102, "triaged", "2026-08-05"),
(103, "fix_in_progress", "2026-06-20"),
(104, "fix_deployed", "2026-08-01"),
(105, "fix_deployed", "2026-08-29"),
(106, "accepted_risk", "2026-03-01"),
])
# max days allowed in each state before a finding counts as stuck
LIMITS = {"triaged": 5, "fix_in_progress": 60, "fix_deployed": 14, "accepted_risk": 180}
AS_OF = "2026-09-01"
for fid, state, changed in db.execute("SELECT * FROM findings ORDER BY id"):
age = int(db.execute("SELECT julianday(?)-julianday(?)", (AS_OF, changed)).fetchone()[0])
if age > LIMITS[state]:
print(f"STUCK #{fid} {state} for {age}d (limit {LIMITS[state]}d)")
Output:
STUCK #102 triaged for 27d (limit 5d)
STUCK #103 fix_in_progress for 73d (limit 60d)
STUCK #104 fix_deployed for 31d (limit 14d)
STUCK #106 accepted_risk for 184d (limit 180d)
Finding 106 has sat in accepted_risk for 184 days against a 180-day review limit, so its acceptance is overdue for re-review or expiry (the table stores no expiry date, so the age limit stands in for it), and 104 was deployed but never verified. Those are the typical stuck shapes.
False positive and reopened branches
A false positive needs a reason and a reviewer, and its signature (a fingerprint such as asset plus finding type plus location) is remembered so the scanner stops re-raising it. A false positive is a scanner alert that is not a real vulnerability. Reopened increments a counter, and a high count flags a weak fix.
Pitfalls
Too many states (people stop updating them), no verification gate (closure means nothing), and no owner on Reopened.
Unlock Full Question Bank
Get access to all 14 Security Findings Management and Remediation Tracking interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.