手把手教你用Python解析SARIF报告:5分钟提取关键漏洞信息并生成Excel

SARIF静态分析Python网络安全
于 2026-05-31 12:03:12 修改
·本内容遵循CC 4.0 BY-SA版权协议

手把手教你用Python解析SARIF报告:5分钟提取关键漏洞信息并生成Excel

每次收到静态分析工具生成的SARIF报告,面对密密麻麻的JSON结构,你是否感到无从下手?作为开发者,我们真正需要的是快速定位高危漏洞、清晰了解问题所在,而不是在复杂的数据结构中迷失方向。本文将带你用Python轻松解析SARIF报告,提取关键漏洞信息,并自动生成结构化的Excel报告,让安全分析变得简单高效。

1. 准备工作:理解SARIF报告结构

SARIF报告本质上是一个结构化的JSON文件,包含了静态分析工具发现的所有问题。在开始编写解析脚本前,我们需要先了解它的核心结构:

JSON
{
"version": "2.1.0",
"runs": [
{
"tool": {
"driver": {
"name": "分析工具名称",
"version": "工具版本"
}
},
"results": [
{
"ruleId": "规则ID",
"message": {
"text": "问题描述"
},
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "文件路径"
},
"region": {
"startLine": 行号,
"startColumn": 列号,
"snippet": {
"text": "问题代码片段"
}
}
}
}
],
"level": "问题严重程度"
}
]
}
]
}

提示:不同工具生成的SARIF报告可能在细节上略有差异,但核心结构基本一致。重点关注results数组,它包含了所有检测到的问题。

2. 基础解析:用Python提取关键信息

我们先从最简单的解析开始,使用Python内置的json库读取SARIF文件,并提取基本信息:

PYTHON
import json
 
def parse_sarif_basic(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
sarif_data = json.load(f)
# 提取工具信息
tool_name = sarif_data['runs'][0]['tool']['driver']['name']
tool_version = sarif_data['runs'][0]['tool']['driver']['version']
# 提取所有结果
results = sarif_data['runs'][0]['results']
print(f"工具: {tool_name} {tool_version}")
print(f"发现的问题总数: {len(results)}")
# 打印前5个问题
for i, result in enumerate(results[:5], 1):
print(f"\n问题 #{i}:")
print(f"规则ID: {result.get('ruleId', 'N/A')}")
print(f"严重程度: {result.get('level', 'warning')}")
print(f"描述: {result['message']['text']}")
if result.get('locations'):
location = result['locations'][0]['physicalLocation']
print(f"文件: {location['artifactLocation']['uri']}")
print(f"行号: {location['region']['startLine']}")
if 'snippet' in location['region']:
print(f"代码片段: {location['region']['snippet']['text']}")
 
# 使用示例
parse_sarif_basic('report.sarif')

这个基础版本已经能提取出每个问题的关键信息,包括:

  • 规则ID
  • 问题描述
  • 文件路径
  • 行号
  • 代码片段
  • 严重程度

3. 进阶处理:使用pandas进行数据分析

为了更高效地处理和分析大量问题,我们可以使用pandas库将数据转换为DataFrame:

PYTHON
import pandas as pd
 
def sarif_to_dataframe(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
sarif_data = json.load(f)
results = sarif_data['runs'][0]['results']
data = []
for result in results:
entry = {
'rule_id': result.get('ruleId'),
'level': result.get('level', 'warning'),
'message': result['message']['text']
}
if result.get('locations'):
location = result['locations'][0]['physicalLocation']
entry['file'] = location['artifactLocation']['uri']
entry['line'] = location['region']['startLine']
if 'snippet' in location['region']:
entry['snippet'] = location['region']['snippet']['text']
data.append(entry)
return pd.DataFrame(data)
 
# 使用示例
df = sarif_to_dataframe('report.sarif')
print(df.head())

有了DataFrame,我们可以轻松进行各种分析:

PYTHON
# 按严重程度统计问题数量
severity_counts = df['level'].value_counts()
print("问题严重程度分布:")
print(severity_counts)
 
# 找出最常见的规则ID
top_rules = df['rule_id'].value_counts().head(10)
print("\n最常见的10个规则:")
print(top_rules)
 
# 筛选高危问题
critical_issues = df[df['level'] == 'error']
print(f"\n发现的高危问题数量: {len(critical_issues)}")

4. 生成Excel报告:自动化输出

最后,我们将分析结果输出为结构化的Excel报告,方便团队共享和跟踪:

PYTHON
def generate_excel_report(df, output_file):
# 创建Excel writer
writer = pd.ExcelWriter(output_file, engine='xlsxwriter')
# 写入所有问题
df.to_excel(writer, sheet_name='所有问题', index=False)
# 按严重程度分组
for level in df['level'].unique():
level_df = df[df['level'] == level]
level_df.to_excel(writer, sheet_name=f'{level}级别问题', index=False)
# 获取workbook和worksheet对象
workbook = writer.book
worksheet = writer.sheets['所有问题']
# 设置自动列宽
for i, col in enumerate(df.columns):
max_len = max(df[col].astype(str).map(len).max(), len(col)) + 2
worksheet.set_column(i, i, max_len)
# 添加严重程度统计图表
severity_counts = df['level'].value_counts()
chart_sheet = workbook.add_worksheet('统计图表')
chart = workbook.add_chart({'type': 'pie'})
chart.add_series({
'name': '问题严重程度分布',
'categories': ['所有问题', 1, 1, len(severity_counts), 1],
'values': ['所有问题', 1, 2, len(severity_counts), 2],
'data_labels': {'percentage': True}
})
chart_sheet.insert_chart('A1', chart)
writer.close()
 
# 使用示例
generate_excel_report(df, 'security_report.xlsx')

生成的Excel报告将包含:

  • 所有问题的详细列表
  • 按严重程度分组的问题列表
  • 问题严重程度分布的饼图
  • 自动调整的列宽,确保数据可读性

5. 实用技巧与常见问题

在实际使用中,有几个实用技巧可以提升效率:

1. 处理大型SARIF文件

当处理非常大的SARIF文件时,可以使用流式处理来减少内存消耗:

PYTHON
import ijson
 
def process_large_sarif(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
# 使用ijson逐项解析results数组
results = ijson.items(f, 'runs.item.results.item')
for result in results:
# 处理每个result项
process_result(result)

2. 自定义过滤规则

可以根据项目需求添加自定义过滤规则:

PYTHON
def filter_results(df, config):
"""根据配置文件过滤结果"""
# 排除特定规则ID
if 'exclude_rules' in config:
df = df[~df['rule_id'].isin(config['exclude_rules'])]
# 只包含特定严重程度
if 'include_levels' in config:
df = df[df['level'].isin(config['include_levels'])]
# 排除特定文件路径
if 'exclude_paths' in config:
for path in config['exclude_paths']:
df = df[~df['file'].str.contains(path, na=False)]
return df
 
# 示例配置
config = {
'exclude_rules': ['TUT1001', 'TUT1002'],
'include_levels': ['error', 'warning'],
'exclude_paths': ['test/', 'mock/']
}
 
filtered_df = filter_results(df, config)

3. 与CI/CD集成

可以将这个脚本集成到CI/CD流程中,自动分析每次构建的SARIF报告:

BASH
# !/bin/bash
# 在CI中运行的示例脚本
 
# 运行静态分析工具
./static_analyzer --output=report.sarif
 
# 解析SARIF报告并生成Excel
python parse_sarif.py report.sarif -o security_report.xlsx
 
# 如果有高危问题,使构建失败
critical_count=$(python parse_sarif.py report.sarif --count-critical)
if [ "$critical_count" -gt 0 ]; then
echo "发现 $critical_count 个高危问题,构建失败!"
exit 1
fi

注意:不同静态分析工具生成的SARIF报告可能有细微差异,建议先检查报告结构,必要时调整解析逻辑。