# 自定义扫描工具

  • 自定义扫描工具属于系统高级功能,需要后台管理员在功能菜单中开启该功能
  • 自定义扫描工具是针对系统内部集成工具而言的(例如系统已经集成的三方工具CppCheck、平台自研的Scanner-xxx系列工具等)
  • 先看看系统内部集成一款新工具,平台需要完成哪些工作,以及与自定义集成方式的对比,见下方的表格
工 作 项 平台集成方式 自定义集成方式
工具环境集成 工具(包括运行时环境)集成到扫描镜像 扫描运行时通过自定义命令的方式实时安装工具以及环境,见【工具环境安装命令
工具调度执行 添加工具、语言-工具映射关系sql,由扫描器实现各个工具调度逻辑 统一工具调度逻辑(类似流水线构建插件,用户填写shell命令),扫描器仅负责执行用户的命令调用工具执行扫描,见【工具执行扫描命令
扫描规则录入 平台整理sql批量录入规则 平台提供模板约定规则字段以及类型,用户根据模板示例自己整理上传,见【工具扫描规则录入
扫描结果解析 解析服务实现各个工具扫描结果解析逻辑 平台定义扫描结果文件格式json,约束字段Schema,
解析服务统一结果解析逻辑,见【工具扫描结果约束

# 自定义命令

扫描镜像环境说明:

  • 扫描镜像是基于debian 12系统构建。
  • 镜像中安装了常用的环境,如:python3.11java 17go 1.18nodejs 18.Net 6.0/8.0等。
  • 扫描镜像中自带常用的工具,如:pipnpmmvngitcurlwget等。

需要执行的自定义命令包括两部分: 工具环境安装命令以及工具执行扫描命令

# 工具环境安装命令

用户通过执行命令安装自定义的扫描工具及工具依赖的运行时环境。建议将工具安装文件托管至平台制品库中或者其他可下载的地方,然后在命令中进行下载安装。

以下为示例命令,用户需根据实际情况替换名称以及路径:

# 下载并解压工具文件
curl -o tool.tar.gz https://example.com/tool.tar.gz
tar -zxvf tool.tar.gz
# 修改执行权限,避免容器中无法正常执行
chmod +x tool_cli
# 移动到系统环境变量路径下,方便执行扫描时直接调用
mv tool_cli /usr/bin/tool_cli

# 根据工具需要,完成其他环境准备工作...

提示

1、扫描程序会按原样执行自定义命令,保留原生 stdout / stderr 行为,执行命令的工作目录为下载的代码库根目录$SCAN_REPO_DIR 2、支持直接执行代码库中的脚本文件,例如可以将工具安装命令封装在install_tool.sh文件中,然后直接执行 sh $SCAN_REPO_DIR/install_tool.sh

# 工具执行扫描命令

工具启动扫描时要执行的命令,包括参数、结果输出格式、结果文件存放地址(约定为/tmp/scan_result.json)、扫描路径等。

提示:命令中也可以使用系统的环境变量,通过 $变量名 进行引用, 支持的环境变量包括:

1、构建任务通用的系统变量 前往查看

2、扫描任务相关的环境变量,见下方:

环境变量 说明 示例
SCAN_REPO_DIR 本次扫描任务克隆代码库的本地路径 "/home/app/scan/11_200/repo_name"
SCAN_DIFF_FILES 增量扫描模式,diff文件列表,相对路径 "src/file1.java,src/dir/file2.java"
SCAN_INCLUDE_FILES 扫描过滤设置中只扫描的文件、目录,相对路径 "src/dir1,src/dir2/file1.java"
SCAN_EXCLUDE_FILES 扫描过滤设置中排除的文件、目录,相对路径 "src/test,src/sample/file1.java"

以下为示例命令,用户需根据实际使用情况填写:

tool_cli scan -debug -f json -o /tmp/scan_result.json --exclude=test/**,src/**/*_test.java $SCAN_REPO_DIR

# 其他后续命令,如:预处理原始结果文件转换为满足平台要求的json格式、拷贝结果文件到约定路径等(参考【工具扫描结果约束】)

提示:类似工具安装命令,支持直接执行代码库中的脚本文件,例如可以将工具执行扫描命令封装在start_tool.sh文件中,然后直接执行 sh $SCAN_REPO_DIR/start_tool.sh

# 工具扫描规则录入

可以在后台批量导入页面这里下载规则模板,按照说明填写规则信息,上传平台即可自动导入。

注意:规则的key作为唯一标识不能重复,也不能与系统内部已集成的工具的规则key重复,导入时接口会进行校验

# 工具扫描结果约束

自定义工具最终产出的扫描结果,需要满足约束条件:

1,扫描结果文件格式目前支持json,文件路径约定为:/tmp/scan_result.json 扫描结束后会解析该文件

2,若工具原始扫描结果不满足约束条件,可以在扫描命令中通过脚本进行预处理,将原始结果转换为满足平台要求的json格式。

3,每个代码问题包含的字段Schema:

字段名 数据类型 JSON标签 必填 取值范围 描述说明 示例值
File string "file" 必填 非空字符串 检测到问题的源代码文件路径(相对根目录) "src/main/java/com/example/sample.java"
Line int "line" 必填 正整数(≥0) 问题在文件中的具体行号(部分问题没有具体行号,默认0) 42
Column int "column" 必填 正整数(≥1) 问题在行中的列位置(从1开始计数) 15
Rule string "rule" 必填 非空字符串 规则唯一标识符(要与录入平台的规则key保持一致,否则问题将被忽略 "key_prefix:sql-injection"
Msg string "msg" 必填 非空字符串 问题的详细描述信息 "发现潜在的SQL注入漏洞"
Suggest string "suggest" 可选 可为空字符串 针对问题的修复建议或解决方案 "建议使用参数化查询"
FixCode string "fixCode" 可选 可为空字符串 修复问题的示例代码片段 "PreparedStatement stmt = conn.prepareStatement(sql);"

扫描结果文件/tmp/scan_result.json示例内容:

[
  {
      "file": "src/main/java/com/example/sample1.java",
      "line": 42,
      "column": 15,
      "rule": "key_prefix:sql-injection",
      "msg": "发现使用字符串拼接构造SQL查询,存在SQL注入风险",
      "suggest": "建议使用PreparedStatement进行参数化查询",
      "fixCode": "PreparedStatement stmt = conn.prepareStatement(sql);"
  },
  {
    "file": "src/main/java/com/example/sample2.java",
    "line": 20,
    "column": 11,
    "rule": "key_prefix:xxx",
    "msg": "xxx",
    "suggest": "建议xxx",
    "fixCode": "xxx"
  }
]