Skip to content

Add Alpine security advisory importer#2203

Open
NucleiAv wants to merge 3 commits intoaboutcode-org:mainfrom
NucleiAv:feat/alpine-security-importer-2158
Open

Add Alpine security advisory importer#2203
NucleiAv wants to merge 3 commits intoaboutcode-org:mainfrom
NucleiAv:feat/alpine-security-importer-2158

Conversation

@NucleiAv
Copy link

@NucleiAv NucleiAv commented Mar 10, 2026

Adds AlpineSecurityImporterPipeline to collect advisories from https://security.alpinelinux.org via its JSON-LD API.

Active branches are discovered dynamically from the root endpoint so new branches are picked up automatically without code changes. HISTORICAL_BRANCHES covers EOL branches that still have data but no longer appear in the root index (3.10 through 3.18, 3.22-community). Branches 3.13 through 3.16 are excluded as the API returns 0 items.

Each advisory is parsed for CVE id, CVSS 3.x severity (version detected from the vector prefix), reference URLs, and fixed package versions as apk PURLs with distroversion and reponame qualifiers. Tests use real API fixture data and cover CVSS parsing, fixed states, missing advisory id, malformed package URLs, and unfixed states.

@NucleiAv NucleiAv force-pushed the feat/alpine-security-importer-2158 branch from 4e049cb to 2d68893 Compare March 11, 2026 15:24
Copy link
Collaborator

@ziadhany ziadhany left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NucleiAv Fetching JSON-LD is a good idea instead of parsing the HTML. We have a similar importer for Alpine
see: alpine_linux_importer_v2.AlpineLinuxImporterPipeline.

However, the alpine_linux_importer_v2 importer misses some data there, which is why I think we need this importer.

@@ -0,0 +1 @@
{"@context":"https://security.alpinelinux.org/static/context.jsonld","cpeMatch":[{"@context":"https://security.alpinelinux.org/static/context.jsonld","cpeUri":"","id":"https://security.alpinelinux.org/vuln/CVE-2025-46836#cpeMatch/940449","maximumVersion":"2.10","maximumVersionOp":"<=","minimumVersion":"0","minimumVersionOp":">=","package":"https://security.alpinelinux.org/srcpkg/net-tools","type":"CPEMatch","vuln":"https://security.alpinelinux.org/vuln/CVE-2025-46836"}],"cvss3":{"score":6.6,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:H"},"description":"net-tools is a collection of programs that form the base set of the NET-3 networking distribution for the Linux operating system. Inn versions up to and including 2.10, the Linux network utilities (like ifconfig) from the net-tools package do not properly validate the structure of /proc files when showing interfaces. `get_name()` in `interface.c` copies interface labels from `/proc/net/dev` into a fixed 16-byte stack buffer without bounds checking, leading to possible arbitrary code execution or crash. The known attack path does not require privilege but also does not provide privilege escalation in this scenario. A patch is available and expected to be part of version 2.20.","id":"https://security.alpinelinux.org/vuln/CVE-2025-46836","ref":[{"@context":"https://security.alpinelinux.org/static/context.jsonld","id":"https://security.alpinelinux.org/vuln/CVE-2025-46836#ref/588613","referenceType":"MISC","rel":"https://github.com/ecki/net-tools/commit/7a8f42fb20013a1493d8cae1c43436f85e656f2d","type":"Reference"},{"@context":"https://security.alpinelinux.org/static/context.jsonld","id":"https://security.alpinelinux.org/vuln/CVE-2025-46836#ref/588614","referenceType":"CONFIRM","rel":"https://github.com/ecki/net-tools/security/advisories/GHSA-pfwf-h6m3-63wf","type":"Reference"},{"@context":"https://security.alpinelinux.org/static/context.jsonld","id":"https://security.alpinelinux.org/vuln/CVE-2025-46836#ref/593944","referenceType":"af854a3a-2127-422b-91ae-364da2661108","rel":"https://lists.debian.org/debian-lts-announce/2025/05/msg00053.html","type":"Reference"}],"state":[{"@context":"https://security.alpinelinux.org/static/context.jsonld","fixed":false,"id":"https://security.alpinelinux.org/vuln/CVE-2025-46836#state/108203","packageVersion":"https://security.alpinelinux.org/srcpkg/net-tools/2.10-r3","repo":"edge-main","type":"VulnerabilityState","vuln":"https://security.alpinelinux.org/vuln/CVE-2025-46836"},{"@context":"https://security.alpinelinux.org/static/context.jsonld","fixed":false,"id":"https://security.alpinelinux.org/vuln/CVE-2025-46836#state/415014","packageVersion":"https://security.alpinelinux.org/srcpkg/net-tools/2.10-r3","repo":"3.23-main","type":"VulnerabilityState","vuln":"https://security.alpinelinux.org/vuln/CVE-2025-46836"},{"@context":"https://security.alpinelinux.org/static/context.jsonld","fixed":false,"id":"https://security.alpinelinux.org/vuln/CVE-2025-46836#state/125956","packageVersion":"https://security.alpinelinux.org/srcpkg/net-tools/2.10-r3","repo":"3.22-main","type":"VulnerabilityState","vuln":"https://security.alpinelinux.org/vuln/CVE-2025-46836"},{"@context":"https://security.alpinelinux.org/static/context.jsonld","fixed":false,"id":"https://security.alpinelinux.org/vuln/CVE-2025-46836#state/127510","packageVersion":"https://security.alpinelinux.org/srcpkg/net-tools/2.10-r3","repo":"3.21-main","type":"VulnerabilityState","vuln":"https://security.alpinelinux.org/vuln/CVE-2025-46836"},{"@context":"https://security.alpinelinux.org/static/context.jsonld","fixed":false,"id":"https://security.alpinelinux.org/vuln/CVE-2025-46836#state/127996","packageVersion":"https://security.alpinelinux.org/srcpkg/net-tools/2.10-r3","repo":"3.20-main","type":"VulnerabilityState","vuln":"https://security.alpinelinux.org/vuln/CVE-2025-46836"},{"@context":"https://security.alpinelinux.org/static/context.jsonld","fixed":false,"id":"https://security.alpinelinux.org/vuln/CVE-2025-46836#state/128449","packageVersion":"https://security.alpinelinux.org/srcpkg/net-tools/2.10-r3","repo":"3.19-main","type":"VulnerabilityState","vuln":"https://security.alpinelinux.org/vuln/CVE-2025-46836"}],"type":"Vulnerability"}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use a pretty format to make this JSON-LD more readable?

https://jsoneditoronline.org

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

"references": [
{
"reference_id": "",
"reference_type": "",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are missing reference_type

Suggested change
"reference_type": "",
"reference_type": "patch",

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, reference_type is now mapped directly from the referenceType field in each ref entry.

Comment on lines +117 to +131
cvss3 = data.get("cvss3") or {}
cvss_score = cvss3.get("score")
cvss_vector = cvss3.get("vector") or ""
if cvss_vector and cvss_score:
if cvss_vector.startswith("CVSS:3.1/"):
system = SCORING_SYSTEMS["cvssv3.1"]
else:
system = SCORING_SYSTEMS["cvssv3"]
severities.append(
VulnerabilitySeverity(
system=system,
value=str(cvss_score),
scoring_elements=cvss_vector,
)
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure we only have CVSS3 ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I sampled 20+ live advisories across multiple branches and the API only ever returns a cvss3 key at the top level. No cvss2 or cvss4 fields exist in the JSON-LD schema for this endpoint.

for ref in data.get("ref") or []:
ref_url = ref.get("rel") or ""
if ref_url:
references.append(ReferenceV2(url=ref_url))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cpe uri should be stored as a reference

      "cpeUri": "cpe:2.3:a:perl:perl:*:*:*:*:*:*:*:*",
      "id": "https://security.alpinelinux.org/vuln/CVE-2024-56406#cpeMatch/917070",
```l

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, non-empty cpeUri entries are now added as references with reference_id=cpe_uri and url=cpe_id.

resp = requests.get(url, headers=ADVISORY_HEADERS, timeout=30)
resp.raise_for_status()
data = resp.json()
except Exception as e:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please avoid general exception

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, replaced bare except Exception with (requests.RequestException, ValueError) in all catch sites.



Signed-off-by: Anmol Vats <anmolvats2003@gmail.com>
Signed-off-by: Anmol Vats <anmolvats2003@gmail.com>
Signed-off-by: Anmol Vats <anmolvats2003@gmail.com>
@NucleiAv NucleiAv force-pushed the feat/alpine-security-importer-2158 branch from 2d68893 to a5e8b61 Compare March 15, 2026 00:06
@NucleiAv
Copy link
Author

NucleiAv commented Mar 15, 2026

@ziadhany On it! Also, the feedback you gave on my ZDI PR has already been applied across all my other PRs as well (dateparser instead of strptime, find_all_cve from utils, no seen_ids, no repo_url). Pipeline logs are included in all of them too.

@NucleiAv NucleiAv requested a review from ziadhany March 15, 2026 00:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Collect Alpine Linux security advisories from https://security.alpinelinux.org/

2 participants