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)
}
相关推荐
QuantumRedGuestk2 小时前
DEDECMS靶场CSRF漏洞分析与安全防护
网络安全·漏洞分析·csrf·dedecms
luffy54592 小时前
微信小程序实现图片横向滑动的示例
微信小程序·小程序
万岳软件开发小城2 小时前
直播电商系统源码搭建直播带货APP/小程序的完整流程
小程序·php·软件开发·直播带货系统源码·直播电商app开发
棒棒的唐3 小时前
使用微信小程序版Vant的upload组件上传身份证的样式自定义方案(Css魔改版)
css·微信小程序·小程序
jaqi.l3 小时前
uni-app 小程序全局挂载分享功能,并动态配置页面是否可以分享
vue.js·小程序·uni-app
上海云盾-高防顾问4 小时前
API接口成攻击重灾区?高防CDN限流策略让恶意调用无所遁形
web安全·网络安全
2501_915106324 小时前
HBuilderX 项目上架 iOS app上架 App Store 的关键流程
android·ios·小程序·https·uni-app·iphone·webview
2501_915106324 小时前
iOS 文件管理,在不越狱的前提下管理 iPhone / iPad 文件
android·ios·小程序·uni-app·iphone·webview·ipad
南行*4 小时前
逆向中的Hash类算法
算法·网络安全·哈希算法