我们可以通过github的open api 来拉取一些信息。这里主要是拉取 github 开源漏洞中的漏洞信息
Github Explorer
github Explorer 是一个在线工具,登录之后,我们可以在左侧输入GraphQL 查询语句,之后就可以查询相关的信息。例如:
查询第一页
这里我们想要查询在github 开源的npm漏洞可以这么输入
{
securityVulnerabilities(first: 100, ecosystem: NPM) {
totalCount
pageInfo {
endCursor
startCursor
}
nodes {
advisory {
identifiers {
value
type
}
}
firstPatchedVersion {
identifier
}
package {
name
ecosystem
}
severity
updatedAt
vulnerableVersionRange
}
}
}
这里是一个GraphQL语句,解释一下
- first:100表查询前100个数据,用于分页
- ecosystem:npm, 表查询的是npm生态的数据,这里也可以换成其他的生态比如maven
- totalCount:用于获取数据的总条数,便于后续分页获取下一页数据
- pageInfo:分页的信息,这里分页主要是使用该对象里面的startCursor,endCursor两个游标,类似SQL 查询是的从那一条开始查询。当我们确定开始游标时,再加上查询数量就可以查询下一页的数据了
- nodes:这个就是返回的节点信息了
查询的结果如下:
查询下一页数据
上面是查询第一页的前100条数据,这里总计有3000+的数据,那我们就需要分页查询到所有的数据。分页的话,我们就需要获取前一页数据的最后的游标,将其作为下一页的起始游标查询。从pageInfo中的endcCursor就可以获取上一页数据的最后的游标值。
我们讲GraphQL的语句修改成下面的
{
securityVulnerabilities(first: 100, ecosystem: NPM, after: "Y3Vyc29yOnYyOpK5MjAyMi0xMi0yMlQwMjo1Mzo1NCswODowMM2STQ==") {
totalCount
pageInfo {
endCursor
startCursor
}
nodes {
advisory {
identifiers {
value
type
}
}
firstPatchedVersion {
identifier
}
package {
name
ecosystem
}
severity
updatedAt
vulnerableVersionRange
}
}
}
查询之后我们就查到了第二页的100条数据。
接口拉取
我们在实际应用中期望是在一个程序中获取数据,而不是每次手动的在这个工具网站中查询。
github 提供了一些open api,我么可以通过这些接口来获取想要的数据。
获取github token
需要先获取一个github的token,可以查看github的文档,按照上面的步骤一步步来就可以了github 获取token
http 拉取数据
不啰嗦直接附上代码
const axios = require('axios');
const fs = require('fs');
// 按照上述步骤从github 上获取的token
const accessToken = 'your token';
// 这部分内容就是GraphQL,其中的$page是为了查询分页加的占位符
const query = `
{
securityVulnerabilities(
first: 100
ecosystem: NPM
$page
) {
totalCount
pageInfo {
endCursor
startCursor
}
nodes {
advisory {
identifiers {
value
type
}
}
firstPatchedVersion {
identifier
}
package {
name
ecosystem
}
severity
updatedAt
vulnerableVersionRange
}
}
}`;
const getNpmSecurityVulnerabilitiesPaging = async (afterCursor) => {
// github graphql 的api
const url = 'graphql';
const method = 'POST';
const baseURL = 'https://api.github.com/';
const headers = {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
};
let queryStr = query;
if (afterCursor) {
// 非第一页查询,标记查询起始游标
queryStr = queryStr.replace('$page', `after: "${afterCursor}"`);
} else {
// 第一页查询无需游标
queryStr = queryStr.replace('$page', '');
}
const config = {
url,
method,
baseURL,
headers,
data: JSON.stringify({query: queryStr}),
};
try {
const rst = await axios(config);
return rst.data.data.securityVulnerabilities;
} catch (error) {
console.log(error.message);
}
}
const getSecurityVulnerabilitiesNpmList = async () => {
const list = [];
let afterCursor = null;
let total = null;
do {
const securityVulnerabilities = await getNpmSecurityVulnerabilitiesPaging(afterCursor);
const { totalCount, pageInfo, nodes} = securityVulnerabilities;
if (!total) total = securityVulnerabilities.totalCount;
afterCursor = pageInfo.endCursor;
list.push(...nodes);
console.log(`length: ${list.length} / ${total}; afterCursor: ${afterCursor}`);
}while(list.length < total)
console.log(list);
// 将所有的数据输入到同目录下的data.json文件中
fs.writeFileSync('./data.json', JSON.stringify(list))
}
// 获取开源漏洞列表
getSecurityVulnerabilitiesNpmList()
漏洞详情信息
一般可以通过https://github.com/advisories/GHSA编号 来查看漏洞的详情。
每一个开源的漏洞也都有一个统一的编号简称是CVE(Common Vulnerabilities and Exposures) 这两个数据也是可以获取到的。如下:
参考资料
github open api
github 开源漏洞
github Explorer
github 文档
github 获取token