CVE检索工具 | 开发一款检索漏洞信息的小程序


开源地址:👉GitCode(国内友好)👈、👉GitHub👈

技术组合:Bun.jsElysia.jsuni-app

体验地址:小程序搜索CVE漏洞检索工具


初衷

转岗到网络安全后,我发现手机上没有专门用于漏洞信息查询的工具,至少在微信小程序这块没有。于是迸发了做一个的念头,也方便自己日常使用。

漏洞信息更新

首先,要感谢国家信息安全漏洞库免费的数据公开,给广大的网络安全工作人员提供了漏洞查询服务👍。

这里我们也是通过国家信息安全漏洞库平台提供的数据服务,构建自己的漏洞信息库。

历史数据导入


上图是我从官网下载的 XML 数据,我的笔记本配置如下:

项目
处理器 11th Gen Intel® Core™ i5-11300H @ 3.10GHz (3.11 GHz)
机带 RAM 16.0 GB (15.8 GB 可用)

对这251 MB 数据进行解析入库,资源占用很夸张,耗时 1358.14 秒(约23分钟),最终的 SQLite 数据文件有 180 MB。

增量数据更新

官网可以查看最新收录的漏洞信息。

获取清单的 fetch 代码如下:

js 复制代码
fetch("https://www.cnnvd.org.cn/web/homePage/cnnvdVulList", {
  "headers": {
    "accept": "application/json, text/plain, */*",
    "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,es;q=0.7",
    "content-type": "application/json;charset=UTF-8",
    "sec-ch-ua": "\"Google Chrome\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": "\"Windows\"",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-origin"
  },
  "referrer": "https://www.cnnvd.org.cn/home/loophole",
  "body": "{\"pageIndex\":1,\"pageSize\":50,\"keyword\":\"\",\"hazardLevel\":\"\",\"vulType\":\"\",\"vendor\":\"\",\"product\":\"\",\"dateType\":\"\"}",
  "method": "POST",
  "mode": "cors",
  "credentials": "omit"
});

我们的思路:

  1. 每日凌晨6点开始执行刷新任务;
  2. 获取前N日(默认为3)的最新漏洞信息;
  3. 将未入库的漏洞信息保存起来。

完整的数据获取代码:

js 复制代码
/**
 *
 * 从官网获取指定条件的漏洞信息并入库
 * @param {Object} conditions 查询条件
 *  {
        "pageIndex": 1,
        "pageSize": 10,
        "keyword": "",
        "hazardLevel": "",
        "vulType": "",
        "vendor": "",
        "product": "",
        "dateType": "",
        "beginpublishTime": "",
        "endpublishTime": ""
    }
 * @param {Number} pageIndex 页码
 * @param {Boolean} forceUpdate 强制刷新
 */
export const fetchVulnList = async (conditions, pageIndex=1, forceUpdate=false)=>{
    logger.debug(`获取条件 ${JSON.stringify(conditions)} 的漏洞信息...`)

    const method = 'POST'
    const pageSize = 50
    const today = date()
    /**
     * 返回结果示例
        {
            id: "d0a2ae627d4248e3bd1da952b93b8e5e",
            vulName: "WordPress plugin MTCaptcha 跨站请求伪造漏洞",
            cnnvdCode: "CNNVD-202601-1335",
            cveCode: "CVE-2025-13520",
            hazardLevel: 3,
            createTime: "2026-01-08",
            publishTime: "2026-01-07",
            updateTime: "2026-01-08",
            typeName: null,
            vulType: "0",
        }
     */
    const resp = await fetch({
        url: `https://www.cnnvd.org.cn/web/homePage/cnnvdVulList`,
        body: JSON.stringify(Object.assign({}, conditions, { pageIndex, pageSize })),
        headers,
        method
    })

    if(resp.status != 200){
        logger.error(`获取漏洞列表失败`, resp.statusText)
        return
    }

    const body = await resp.json()
    for(const bean of body.data.records){
        let cnnvdId = bean['cnnvdCode']
        const isExist = existCheck(cnnvdId, true)
        if(!forceUpdate && isExist){
            logger.debug(`${cnnvdId} 已存在,跳过...`)
            continue
        }

        /**@type {import("../beans").VulnerabilityType} */
        const vul = { cnnvdId }
        vul.cveId = bean['cveCode']
        vul.name = bean['vulName']
        vul.published = bean['publishTime']
        vul.severity = LEVELS[bean['hazardLevel']]
        vul.updated = today

        //额外获取的数据
        const detailResp = await fetch({
            url:`https://www.cnnvd.org.cn/web/cnnvdVul/getCnnnvdDetailOnDatasource`,
            body: JSON.stringify({
                "id": bean.id,
                "vulType": bean.vulType,
                "cnnvdCode": bean['cnnvdCode']
            }),
            headers,
            method
        })
        if(detailResp.status == 200){
            const detailBody = await detailResp.json()
            let { cnnvdDetail } = detailBody.data
            vul.desc = cnnvdDetail.vulDesc
            vul.type = cnnvdDetail.vulType
            //厂商
            vul.vendor = cnnvdDetail.affectedVendor
            vul.source = cnnvdDetail.referUrl
            vul.solution = cnnvdDetail.patch
        }

        logger.debug(`${!isExist?"新增":"更新"} ${vul.cveId}\t${vul.cnnvdId}\t${vul.published}\t${vul.name}`)

        if(isExist){
            //更新重要字段即可
            exec(
                `UPDATE ${VULN} SET vendor=?,source=?,solution=?,${SEVERITY}=? WHERE ${CNNVD_ID}=?`,
                vul.vendor,
                vul.source,
                vul.solution,
                vul.severity,
                vul.cnnvdId
            )
        }
        else
            insertNew(VULN, vul)
    }

    if(body.data.total > pageIndex * pageSize){
        logger.debug(`即将开始获取第${pageIndex+1}页(总数据量 ${body.data.total})`)
        //继续下一页
        await Bun.sleep(5000)
        await fetchVulnList(conditions, pageIndex + 1)
    }
}

如何调用?

js 复制代码
/**
 * 从官网获取指定日期发布的漏洞信息并入库
 * @param {String} day
 */
export const fetchSpecialDays = async (day=addDay(-1), endTime)=>{
    logger.debug(`获取 ${day}${endTime?`(至${endTime})`:""} 发布的漏洞信息...`)

    await fetchVulnList({
        beginTime: day,
        dateType: "publishTime",
        endTime: endTime || day,
    })
}

export const fetchPreDays = async (step=3)=>{
    await fetchVulnList({
        beginTime: addDay(-1 * step),
        dateType: "publishTime",
        endTime: date(),
    })
}

/**
 * 刷新指定ID的漏洞数据
 * @param {String} keyword
 */
export const fetchSpecialId = async keyword =>{
    await fetchVulnList({ keyword }, 1, true)
}
相关推荐
汤愈韬1 天前
ACL概述、ACL原理、基本ACL应用及配置
网络·网络协议·网络安全
青岑CTF1 天前
攻防世界-Ics-05-胎教版wp
开发语言·安全·web安全·网络安全·php
Yff_world1 天前
网络通信模型
学习·网络安全
Palpitate_LL1 天前
Mongoose 搜索注入漏洞 CVE-2024-53900 到 CVE-2025-23061
网络安全
vortex51 天前
动态漏洞探测:带参 URL 收集与扫描流程优化
web安全·网络安全·渗透测试
one____dream1 天前
【网安】Reverse-非常规题目
linux·python·安全·网络安全·ctf
Root_Hacker1 天前
sql注入学习笔记
数据库·sql·web安全·网络安全·oracle·网络攻击模型
说私域1 天前
社群招募文案的核心构建要点与工具赋能路径——基于AI智能名片链动2+1模式商城小程序的实践研究
人工智能·小程序·私域运营
青岑CTF1 天前
攻防世界-Web_php_include-胎教版wp
开发语言·安全·web安全·网络安全·php
_ZeroKing1 天前
自制智能门锁:NFC 刷卡 + 小程序远程开锁(完整实战记录)
嵌入式硬件·小程序·notepad++·arduino