137 lines
4.7 KiB
TypeScript
137 lines
4.7 KiB
TypeScript
/** 模块:SVE 数据归一化与 CVSS 工具(后端 JSON 字段为原样存储,前端做防御性归一化) */
|
|
|
|
export interface ProductItem {
|
|
name: string
|
|
version: string
|
|
fixedVersion?: string
|
|
}
|
|
|
|
export interface ReferenceItem {
|
|
type: string
|
|
title?: string
|
|
url: string
|
|
}
|
|
|
|
export interface RelatedItem {
|
|
id: string
|
|
relation?: string
|
|
}
|
|
|
|
const asRecord = (raw: unknown): Record<string, unknown> => {
|
|
return raw && typeof raw === 'object' ? (raw as Record<string, unknown>) : {}
|
|
}
|
|
|
|
/** SveProducts:兼容 {name,version,fixedVersion} 与 {productName,productVersion,productFixedVersion} 两种形态 */
|
|
export function normalizeProducts(raw: unknown): ProductItem[] {
|
|
if (!Array.isArray(raw)) return []
|
|
return raw
|
|
.map((entry) => {
|
|
const r = asRecord(entry)
|
|
return {
|
|
name: String(r.name ?? r.productName ?? r.Name ?? r.product_name ?? ''),
|
|
version: String(r.version ?? r.productVersion ?? r.Version ?? r.product_version ?? ''),
|
|
fixedVersion: r.fixedVersion != null ? String(r.fixedVersion) : undefined,
|
|
}
|
|
})
|
|
.filter((p) => p.name || p.version)
|
|
}
|
|
|
|
/** SveReferences:兼容 {type,title,url} 与 {referenceType,referenceTitle,referenceUrl} 两种形态 */
|
|
export function normalizeReferences(raw: unknown): ReferenceItem[] {
|
|
if (!Array.isArray(raw)) return []
|
|
return raw
|
|
.map((entry) => {
|
|
const r = asRecord(entry)
|
|
return {
|
|
type: String(r.type ?? r.referenceType ?? r.Type ?? 'other'),
|
|
title: r.title != null ? String(r.title) : undefined,
|
|
url: String(r.url ?? r.referenceUrl ?? r.Url ?? r.link ?? ''),
|
|
}
|
|
})
|
|
.filter((ref) => ref.url)
|
|
}
|
|
|
|
/** SveRelatedSves:兼容 [{id,relation}] 与 [{SveID,relation}] 与 [字符串] 三种形态 */
|
|
export function normalizeRelated(raw: unknown): RelatedItem[] {
|
|
if (!Array.isArray(raw)) return []
|
|
return raw
|
|
.map((entry) => {
|
|
if (typeof entry === 'string') return { id: entry }
|
|
const r = asRecord(entry)
|
|
return {
|
|
id: String(r.id ?? r.SveID ?? r.sveId ?? ''),
|
|
relation: r.relation != null ? String(r.relation) : undefined,
|
|
}
|
|
})
|
|
.filter((rel) => rel.id)
|
|
}
|
|
|
|
/** 解析 CVSS 向量字符串为指标字典,如 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N */
|
|
export function parseCvssVector(vector: string): Record<string, string> {
|
|
const result: Record<string, string> = {}
|
|
for (const part of vector.split('/')) {
|
|
const m = /^([A-Z]{1,2}):(.+)$/.exec(part.trim())
|
|
if (m) result[m[1]] = m[2]
|
|
}
|
|
return result
|
|
}
|
|
|
|
/** 指标缩写 → 完整名(用于详情页展示) */
|
|
export const CVSS_METRIC_LABELS: Record<string, { en: string; zh: string }> = {
|
|
AV: { en: 'Attack Vector', zh: '攻击向量' },
|
|
AC: { en: 'Attack Complexity', zh: '攻击复杂度' },
|
|
PR: { en: 'Privileges Required', zh: '所需权限' },
|
|
UI: { en: 'User Interaction', zh: '用户交互' },
|
|
S: { en: 'Scope', zh: '影响范围' },
|
|
C: { en: 'Confidentiality', zh: '机密性' },
|
|
I: { en: 'Integrity', zh: '完整性' },
|
|
A: { en: 'Availability', zh: '可用性' },
|
|
}
|
|
|
|
/** 指标值 → 显示文本 */
|
|
export const CVSS_METRIC_VALUE_LABELS: Record<string, Record<string, { en: string; zh: string }>> = {
|
|
AV: {
|
|
N: { en: 'Network', zh: '网络' },
|
|
A: { en: 'Adjacent', zh: '相邻网络' },
|
|
L: { en: 'Local', zh: '本地' },
|
|
P: { en: 'Physical', zh: '物理' },
|
|
},
|
|
AC: {
|
|
L: { en: 'Low', zh: '低' },
|
|
H: { en: 'High', zh: '高' },
|
|
},
|
|
PR: {
|
|
N: { en: 'None', zh: '无' },
|
|
L: { en: 'Low', zh: '低' },
|
|
H: { en: 'High', zh: '高' },
|
|
},
|
|
UI: {
|
|
N: { en: 'None', zh: '无' },
|
|
R: { en: 'Required', zh: '需要' },
|
|
},
|
|
S: {
|
|
U: { en: 'Unchanged', zh: '未变更' },
|
|
C: { en: 'Changed', zh: '已变更' },
|
|
},
|
|
C: { N: { en: 'None', zh: '无' }, L: { en: 'Low', zh: '低' }, H: { en: 'High', zh: '高' } },
|
|
I: { N: { en: 'None', zh: '无' }, L: { en: 'Low', zh: '低' }, H: { en: 'High', zh: '高' } },
|
|
A: { N: { en: 'None', zh: '无' }, L: { en: 'Low', zh: '低' }, H: { en: 'High', zh: '高' } },
|
|
}
|
|
|
|
/** 参考类型标签 */
|
|
export const REFERENCE_TYPE_LABELS: Record<string, { en: string; zh: string }> = {
|
|
vendor: { en: 'Vendor Advisory', zh: '厂商公告' },
|
|
tech_doc: { en: 'Technical Documentation', zh: '技术文档' },
|
|
sve_guide: { en: 'SVE Guidance', zh: 'SVE 指导文档' },
|
|
research: { en: 'Research Paper', zh: '研究论文' },
|
|
other: { en: 'Other', zh: '其他' },
|
|
}
|
|
|
|
/** 相关关系标签 */
|
|
export const RELATED_RELATION_LABELS: Record<string, { en: string; zh: string }> = {
|
|
same_product: { en: 'Same Product', zh: '同一产品' },
|
|
similar_vuln: { en: 'Similar Vulnerability', zh: '类似漏洞' },
|
|
same_vendor: { en: 'Same Vendor', zh: '同一厂商' },
|
|
other: { en: 'Other Relationship', zh: '其他关系' },
|
|
}
|