Find the upstream commit that fixes the bug, then ask Git whether that commit is an ancestor of your branch. If not, check whether an equivalent patch exists, since a cherry-pick has a different ID. Version numbers on a fork can mislead, so test the commit, not the label.
Why version numbers fail
A fork often keeps upstream's version string while carrying different code. Your package may say 2.4.1 while missing a fix that shipped in 2.4.1, or include one that upstream shipped in 2.4.2. Scanners that match on version alone will answer wrongly in both directions. The reliable question is whether the fix commit is in your history.
Step 1: find the fix commit
Start from the advisory. Good advisories link the fixing commit or pull request. Note the full commit hash and the first release tag that contains it. If the advisory does not link a commit, search upstream history for the issue number or the changed file.
Step 2: test ancestry
The Git merge-base command has an ancestor check that exits with status 0 if the first commit is an ancestor of the second, and 1 if not.
git fetch upstream
git merge-base --is-ancestor FIX_COMMIT HEAD && echo "present" || echo "missing"
If the answer is present, your branch includes the commit through merge history. You can also list which tags contain the commit, using the contains option of the tag command, to learn the first release that has the fix.
Step 3: check for a cherry-pick
If you backported the fix by hand, the ancestry check will say missing, because your commit has a new ID. The documented way around this is patch equivalence. The log and rev-list commands have an option that omits commits introducing the same change as one on the other side, so a backported fix drops out of the difference.
git log --oneline --cherry-mark upstream/main...HEAD
The cherry-mark option marks equivalent commits with an equals sign and inequivalent ones with a plus sign. If your backport shows an equals sign against the upstream fix, you have it. If your backport edited the patch to resolve conflicts, the patch IDs differ and Git will not match it, so read the change yourself.
Step 4: confirm by behavior
Ancestry shows the code is present, not that it works in your build. Where the advisory includes a proof of concept or a test, run it against your build. If the fix touched a file you replaced or rewrote, ancestry can pass while the vulnerable logic still exists in your version of the file.
A short decision table
| Ancestry check | Equivalent patch | Meaning | Action |
|---|---|---|---|
| Present | Not needed | Fix is in history | Verify behavior, close |
| Missing | Yes | Backported | Note the backport, close |
| Missing | No | Not fixed | Cherry-pick or sync now |
| Present | Yes (edited) | Partially adapted | Review by hand |
Record the answer
Write the result next to the advisory ID in your tracker: commit checked, method used, date. When an auditor or customer asks whether you were exposed, that note answers in one line. See vulnerabilities in vendored or copied code for the case where there is no Git history to test.
Where Safeguard fits
Safeguard's reachability analysis can help show whether a vulnerable function is actually called in your code, which complements the ancestry check when you need to prioritize.
Try it yourself
Click through it at your own pace, or open it full screen. Look at which findings are marked reachable and which are not.
Quick check
My fork says version 2.4.1. Is the 2.4.1 fix in it?
Not necessarily. Forks can keep a version string while missing or adding commits. Test the fix commit itself.
Why does the ancestry check fail for my backport?
A cherry-pick creates a new commit with a different ID, so it is not an ancestor match. Use patch equivalence instead.
Sources
Last reviewed: 19 October 2026.