NVD에 무료 API가 있다 — 프로그래밍 방식으로 250,000개 이상의 취약점 검색

발행: (2026년 3월 25일 AM 08:35 GMT+9)
5 분 소요
원문: Dev.to

Source: Dev.to

번역할 텍스트를 제공해 주시면 한국어로 번역해 드리겠습니다.

Alex Spinov

Alex Spinov

왜 이것이 중요한가

제가 아는 보안 연구원은 스택에 영향을 주는 취약점을 찾기 위해 NVD 웹사이트를 수동으로 검색하고, CVE 세부 정보를 스프레드시트에 복사‑붙여넣기하고 있었습니다. 매주 몇 시간이 걸렸습니다.

NVD API를 발견한 뒤, 이제 단일 스크립트가 전체 의존성 목록을 알려진 취약점과 몇 초 만에 비교합니다.

빠른 시작 — 취약점 검색

지난 7 일간 모든 심각한 취약점 찾기

import requests
from datetime import datetime, timedelta

base_url = "https://services.nvd.nist.gov/rest/json/cves/2.0"

# Last 7 days of critical CVEs
end   = datetime.utcnow()
start = end - timedelta(days=7)

params = {
    "pubStartDate": start.strftime("%Y-%m-%dT00:00:00.000"),
    "pubEndDate":   end.strftime("%Y-%m-%dT23:59:59.999"),
    "cvssV3Severity": "CRITICAL"
}

response = requests.get(base_url, params=params)
data = response.json()

print(f"Found {data['totalResults']} critical CVEs this week")
for vuln in data.get("vulnerabilities", [])[:5]:
    cve      = vuln["cve"]
    cve_id   = cve["id"]
    desc     = cve["descriptions"][0]["value"][:100]
    print(f"\n{cve_id}: {desc}...")

키가 필요 없습니다. 가입도 필요 없습니다. 바로 작동합니다.

키워드로 검색

특정 기술을 언급하는 취약점을 찾습니다:

params = {
    "keywordSearch": "apache log4j",
    "resultsPerPage": 5
}
response = requests.get(base_url, params=params)
data = response.json()

print(f"Total Log4j vulnerabilities: {data['totalResults']}")
for vuln in data["vulnerabilities"]:
    cve = vuln["cve"]
    metrics = cve.get("metrics", {})

    # Get CVSS score if available
    score = "N/A"
    if "cvssMetricV31" in metrics:
        score = metrics["cvssMetricV31"][0]["cvssData"]["baseScore"]

    print(f"{cve['id']} | Score: {score} | {cve['descriptions'][0]['value'][:80]}")

CPE(특정 소프트웨어)로 검색

실제 힘 — 특정 제품 버전의 모든 취약점을 찾습니다:

# All vulns for Python 3.11
params = {
    "cpeName": "cpe:2.3:a:python:python:3.11:*:*:*:*:*:*:*",
    "resultsPerPage": 20
}
response = requests.get(base_url, params=params)
data = response.json()

print(f"Python 3.11 vulnerabilities: {data['totalResults']}")
for vuln in data["vulnerabilities"]:
    cve = vuln["cve"]
    print(f"  {cve['id']}: {cve['descriptions'][0]['value'][:90]}")

전체 CVE 세부 정보 가져오기

cve_id = "CVE-2021-44228"   # Log4Shell
response = requests.get(f"{base_url}?cveId={cve_id}")
data = response.json()
cve = data["vulnerabilities"][0]["cve"]

print(f"ID: {cve['id']}")
print(f"Published: {cve['published']}")
print(f"Description: {cve['descriptions'][0]['value'][:200]}")

# CVSS v3.1 details
if "cvssMetricV31" in cve.get("metrics", {}):
    cvss = cve["metrics"]["cvssMetricV31"][0]["cvssData"]
    print(f"CVSS Score: {cvss['baseScore']} ({cvss['baseSeverity']})")
    print(f"Attack Vector: {cvss['attackVector']}")
    print(f"Attack Complexity: {cvss['attackComplexity']}")

# References (first three)
for ref in cve.get("references", [])[:3]:
    print(f"Reference: {ref['url']}")

종속성 취약점 스캐너 만들기

실제로 유용한 것을 소개합니다 — requirements.txt를 스캔해 보세요:

import requests
import time

def scan_dependencies(requirements_file):
    """Scan Python dependencies for known vulnerabilities."""
    base_url = "https://services.nvd.nist.gov/rest/json/cves/2.0"

    with open(requirements_file) as f:
        deps = [
            line.strip().split("==")[0]
            for line in f
            if line.strip() and not line.startswith("#")
        ]

    print(f"Scanning {len(deps)} dependencies...\n")

    for dep in deps:
        params = {
            "keywordSearch": dep,
            "cvssV3Severity": "HIGH",
            "resultsPerPage": 3
        }

        response = requests.get(base_url, params=params)

        if response.status_code == 200:
            data = response.json()
            count = data["totalResults"]
            if count > 0:
                print(f"⚠ {dep}: {count} HIGH+ vulnerabilities")
                for v in data["vulnerabilities"][:2]:
                    cve = v["cve"]
                    print(f"  └─ {cve['id']}: {cve['descriptions'][0]['value'][:70]}")
            else:
                print(f"✓ {dep}: No high‑severity CVEs found")
        else:
            print(f"❌ {dep}: Request failed ({response.status_code})")

        time.sleep(0.6)  # Rate limit: ~100 requests per minute

# Example usage
scan_dependencies("requirements.txt")

속도 제한

접근 유형30초당 요청 수
API 키 없이5
API 키 사용 (무료)50

키를 얻으려면:

키를 헤더에 추가하세요:

headers = {"apiKey": "your-api-key-here"}
response = requests.get(base_url, params=params, headers=headers)

만들 수 있는 것

  • Vulnerability scanner for your CI/CD pipeline → CI/CD 파이프라인용 Vulnerability scanner
  • Security dashboard monitoring new CVEs daily → 새로운 CVE를 매일 모니터링하는 Security dashboard
  • Dependency checker for open‑source projects → 오픈소스 프로젝트용 Dependency checker
  • Threat‑intelligence feed for your security team → 보안 팀을 위한 Threat‑intelligence feed
  • Compliance tool tracking CVEs by severity and vendor → 심각도와 공급업체별 CVE를 추적하는 Compliance tool

NVD API는 비용이 많이 드는 보안 도구가 수천 달러를 청구하는 동일한 데이터를 제공합니다. 차이점은? 이 API는 무료이며 NIST에서 관리합니다.

보안 도구? 저는 무료 API와 개발자 도구를 만들고 있습니다 — 자세한 내용은 제 GitHub를 확인하세요.

0 조회
Back to Blog

관련 글

더 보기 »

위성 데이터가 무기가 될 때

전쟁이 걸프를 재편함에 따라, 세계가 갈등을 명확히 보기 위해 의존하는 satellite infrastructure가 지연되고, spoofed되며, 사적으로 통제되고 있으며—그리고 아무도…