certinia/asist
GitHub: certinia/asist
一款基于Go语言的极速Salesforce应用静态安全扫描工具,通过内置和自定义正则规则在开发阶段快速检测XSS、硬编码机密等安全风险。
Stars: 6 | Forks: 4
# ASIST (Automated Security Issue Scanning Tool)
[](https://pkg.go.dev/github.com/certinia/asist)
[](https://opensource.org/license/bsd-3-clause)
ASIST 是一个基于正则表达式的极速静态应用安全测试 (SAST) 工具,专为以开发者速度保护 Salesforce 应用安全而设计。
它最初是为 Certinia 内部使用以支持安全审查而构建的,我们现在决定将其发布给社区 🌍
## ⭐ 功能特性
- ⚡ 极速!可在几十毫秒内扫描单个文件,在不到一分钟的时间内扫描包含 250 万行 Apex 代码的项目
- 👾 包含 32 条规则,涵盖 XSS、Sharing 子句、硬编码机密以及一些更隐蔽的陷阱,所有规则均符合 Salesforce 安全最佳实践
- 🖋️ 支持在配置文件中自定义正则表达式规则以及标准规则覆盖
- ✅ 通过注释或注解进行误报管理
- ⚙️ 支持边写代码边扫描的 VSCode 扩展!详情请参见[扩展 README](extension/README.md)
- 💻 跨平台、多架构支持(已在 Mac Intel、Mac Silicon、Windows 和 Linux 上测试)
- 🚫 默认遵循 .gitignore 和 .forceignore 规则
- 🧩 支持 YAML 或 JSON 配置,以及用于程序化处理的 JSON 输出 😎
- 🏗️ 可直接集成到 CI/CD 流水线且不会造成干扰
- 📈 提供用于生成指标的基线扫描模式
## ▶️ VSCode 扩展演示

## ▶️ CLI 演示

## 📥 安装说明
### 预编译版本
1. 从 [releases](https://github.com/certinia/asist/releases) 下载您选择的二进制文件。
2. 将该二进制文件放置在您的 PATH 环境变量所包含的目录中
### 作为 Go 包安装
1. 运行 `go install github.com/certinia/asist@latest`
### 安装 VSCode 扩展
在 VSCode 商店中搜索 ASIST。
有关用法请参见 [extensions](extension)
### 从源码构建
1. 安装 `go` 和 `make`
2. 克隆此仓库
3. 安装到您的 GOPATH 中:`make install`
或者:
- 仅针对您的操作系统和架构构建二进制文件:`make`
- 交叉编译:`GOOS=windows GOARCH=amd64 go build -o asist.exe .`
- 为最常用的平台构建二进制文件,请运行:`make build-binaries`
## 🕹️ 用法
要查看帮助信息,请运行:
`asist -h`
```
Usage:
asist [OPTIONS] [Path]
Application Options:
-u, --repo-url= URL of the repo. Used for baseline scan output
-c, --config= JSON or YAML config file to read from
-r, --rules= Rules comma separated to run (ignore rules enabled/disabled in config)
-l, --list-rules List rules which would be run
-b, --baseline-scan For getting output of ASIST baseline scan as count of occurrences and false positive occurrences, number of custom rules occurrences, type of record and this data is used for creating
metrics.
-j, --cicd-rules For use in CI/CD pipelines. Tells ASIST to only run the CICD rules defined in config file. If there are no CI/CD rules defined, no rules will be executed. If there are any occurrences, returns
a non-zero exit code which will make the pipeline step fail
-v, --verbose Print out debug messages with time elapsed since last message
-V, --version Display the current version of ASIST binary
Help Options:
-h, --help Show this help message
Arguments:
Path: Path to the file or folder to scan
```
### 🧩 示例
使用默认设置(所有规则)递归扫描当前工作目录:
```
asist .
```
此扫描将产生以下输出,指示识别出的总问题数、开始和结束时间戳以及详细的发现结果:
```
{
"Count": 161,
"Started": "2025-07-23 13:12:08.231779 +0200 CEST m=+0.000501126",
"Ended": "2025-07-23 13:12:08.307712 +0200 CEST m=+0.076432459",
"Result": [
{
"ID": "ApexClassNoSharing",
"Name": "Apex Class No Sharing",
"Description": "Use of Apex classes where the sharing clause is not specified may cause confusion for other developers. Always set the most restrictive sharing clause for each class.",
"Severity": "Medium",
"RuleCategory": "Security",
"Occurrence": {
"File": "/Users/shaundoyle/sandbox/product/asist/files/testData/testFile.cls",
"Line": "Class TestFile {",
"LineNumber": 1,
"ColumnRange": [
0,
14
]
}
},
{
"ID": "XSSFormAction",
"Name": "Potential XSS with formaction in JS context",
"Description": "Use of the formaction attribute in JavaScript context may introduce an XSS issue. Consider removing it, otherwise ensure that no user input is rendered unescaped.",
"Severity": "High",
"RuleCategory": "Security",
"Occurrence": {
"File": "/Users/shaundoyle/sandbox/product/asist/integrationtests/src/aura/aura.cmp",
"Line": " \u003cform id=\"test\"\u003e\u003c/form\u003e\u003cbutton form=\"test\" formaction=\"javascript:alert(1)\"\u003eX\u003c/button\u003e",
"LineNumber": 3,
"ColumnRange": [
47,
70
]
}
},
[...]
```
使用默认设置扫描单个文件:
```
asist force-app/main/default/classes/MyClass.cls
```
打印 ASIST 版本
```
asist -V
```
使用您的配置文件进行扫描:
```
asist -c ./.asist.json force-app/main/default/classes/MyClass.cls
```
使用单条规则进行扫描:
```
/asist -r ApexClassNoSharing .
```
仅列出已启用的规则,不进行扫描:
```
asist -l
asist -c .asist.yaml -l # Does not list rules disabled in your config
```
以详细模式运行(用于调试):
```
asist -v .
```
以 CI/CD 模式运行(如果定义了 `cicdrules` 属性,则仅运行添加到 `cicdrules` 中的规则):
```
asist -j .
```
以基线模式运行:
```
asist -b -u "https://github.com/certinia/asist.git" .
```
## ⚙️ 配置
您的项目所需的大部分配置都将定义在配置文件中。
ASIST 支持 YAML 或 JSON 配置文件。
扫描文件夹时,ASIST 会自动从被扫描的顶级文件夹中检测 `.asist.yaml` 或 `.asist.json`。
也可以使用 `-c` 参数显式指定配置文件(注意:扫描单个文件时此参数为必填项)。
在配置文件中,您可以:
- 启用/禁用所有标准规则
- 覆盖标准规则的某些属性
- 排除适用于所有规则的文件或目录
- 排除适用于特定规则的文件或目录
- 添加自定义正则表达式规则
- 定义在 CI/CD 模式下运行的规则
请参阅我们的[示例配置文件](.asist.example.yaml)以了解所有配置选项的详细说明。
### 🔧 自定义标准规则
用户可以根据需要覆盖标准规则的某些属性,从而允许他们通过以下方式自定义特定规则的行为:
- 完全禁用规则:`enabled`
- 限制允许的规则违规数量:[`cicdmaxissues`](#rule-max-issues)
- 调整规则严重级别:`severity`
- 调整应扫描的文件:`includepattern`
- 调整不应扫描的文件:`excludepattern`
### ✍🏼 创建自定义规则
除了自定义标准规则外,用户还可以创建自定义规则以定义自己的正则表达式模式:
```
customregexrules:
NoDebugStatements:
name: doNotDebug
description: "Debug statements anticipate bugs; avoid bugs instead"
enabled: false
severity: Critical
rulecategory: Security
pattern: "System\\.debug\\("
includepattern: "\\.cls$"
excludepattern: "Test\\.cls$"
cicdmaxissues: 10 # Allow up to 10 occurrences in CI/CD mode
```
您可以像这样测试此特定规则:
```
asist -c .asist.yaml -r doNotDebug
```
## ❌ 误报管理
ASIST 提供了使用注解、注释或任何其他可以指定任意文本的地方来标记误报的功能。
在下面的示例中,`SessionIDApex` 规则对该语句被忽略:
```
// asist-ignore-begin:[SessionIDApex]
ID sid = UserInfo.getSessionID();
// asist-ignore-end
```
多个规则 ID 可以用逗号分隔,以忽略特定代码块的多个规则,并可以在 `asist-ignore-begin` 语句之后设置带有理由的注释:
```
// asist-ignore-begin:[SessionIDApex,InsecureCryptoAlgorithm] This code is for testing, and not part of the package
ID sid = UserInfo.getSessionID();
Blob sidBlob = Blob.valueOf(sid);
Blob hash = Crypto.generateDigest('MD5', sidBlob);
[...]
// asist-ignore-end
```
在标记语言中,应尽可能在 `` 中设置注释。
在任何其他文件类型中,用户必须自行寻找最合适的方式插入 `asist-ignore-begin` 和 `asist-ignore-end` 语句。从技术上讲,将它们放在哪里并不重要!
_**注意**:不支持嵌套的误报标签。_
### 🔌 使用扩展标记误报
在使用 ASIST 扩展时,将鼠标悬停在出现问题的地方并点击 `Quick fix...` 选项,然后选择 `Mark False positive`:

# 🔁 CI/CD 模式
使用 `-j` 标志即可启用 CI/CD 模式:
```
asist -j .
```
在此模式下,如果未定义 `cicdrules` 属性,默认情况下将运行所有已启用的规则;但如果 `cicdrules` 配置属性包含任何规则 ID,则只会运行这些规则。此外,如果定义了 `cicdrules` 但留空(该属性下未提及任何规则),则不会执行任何规则。
```
cicdrules:
- "XSSDomHtml"
- "XSSLabel"
- "XSSMergeField"
```
这允许开发人员将总体规则集中的一个子集添加到 ASIST 中并引入其 CI/CD 流水线,并随着他们开始清理其他规则的发现结果而逐步向 CI/CD 添加更多规则。这可以防止 `cicdrules` 中定义的规则的问题再次悄然混入代码库中。
## 规则最大问题数
在将 ASIST 引入现有代码库时,您可能已有一些安全历史遗留问题,并希望在着手修复它们的同时防止问题数量增加。`cicdmaxissues` 属性允许您为特定规则设置 CI/CD 模式(仅在使用 -j 选项扫描时)所允许的最大问题数量。
**默认情况下,规则的问题数限制为 0。** 当某个规则超过其 `cicdrules` 阈值时,ASIST 将以错误代码退出(参见[退出代码](#-exit-codes))。只有当您希望允许现有问题存在并防止其继续增加时,才需要设置 `cicdmaxissues`。
对于**标准规则**,请在 `ruleoverrides` 下设置 `cicdmaxissues`:
```
ruleoverrides:
XSSLabel:
cicdmaxissues: 150 # Allow up to 150 XSSLabel issues (grandfather existing issues)
XSSMergeField:
cicdmaxissues: 0 # Explicitly set to 0 (same as default - no issues allowed)
# XSSDomHtml has no cicdmaxissues set, defaults to 0 (no issues allowed)
```
对于**自定义规则**,请直接在规则定义中设置 `cicdmaxissues`:
```
customregexrules:
NoDebugStatements:
name: doNotDebug
severity: Critical
pattern: "System\\.debug\\("
includepattern: "\\.cls$"
cicdmaxissues: 20 # Allow up to 20 existing debug statements while you clean them up
```
此功能允许您:
- 通过随着时间推移逐步降低 cicdmaxissues 来逐渐引入更严格的安全要求
- 在解决现有问题的同时防止技术债务增长
- 开始在一个包含 150 个现有问题的代码库上强制执行安全要求,然后逐步减少到 100 个、50 个,并最终降至 0
## 📊 基线扫描
此模式旨在供 SecOps 团队用于创建跨多个项目的基准并衡量 ASIST 的采用率。
配置中的某些覆盖项(例如 severity)将被忽略,以便规范化数据,从而在不同代码库之间进行同口径对比,并且误报发现也将包含在输出中。
基线模式通过 `-b` 标志启用。
还建议使用 `-u` 标志指定仓库 URL:
```
asist -b -u "git@github.com:certinia/asist.git" .
```
此命令将输出如下的 JSON(格式化后):
```
[
{
"RepositoryName": "certinia/asist",
"RepositoryURL": "git@github.com:certinia/asist.git",
"RecordType": "Finding",
"Content": {
"FindingID": "b17fe249915712219aca7e",
"IsCustom": false,
"IsFalsePositive": true,
"RuleID": "LwcNonStandardPositioning",
"Severity": "Medium",
"RuleCategory": "Security"
}
},
{
"RepositoryName": "certinia/asist",
"RepositoryURL": "git@github.com:certinia/asist.git",
"RecordType": "Finding",
"Content": {
"FindingID": "3a2861bee641864816b86d",
"IsCustom": false,
"IsFalsePositive": true,
"RuleID": "LwcNonStandardPositioning",
"Severity": "Medium",
"RuleCategory": "Security"
}
}
]
```
与常规扫描相比,可以观察到一些差异:
- 缺少大部分“人类友好”的信息(例如,发现结果的代码位置、发现结果的描述等)
- 将包含仓库名称和 URL,以便指标系统可以将其用作过滤维度。
- 每个问题都会被分配一个 `FindingID`,这实际上是一个散列值,可根据规则、发现位置以及是否为误报来唯一标识该发现。
- 添加了一些附加属性,例如该规则是否为自定义规则,或者该发现是否被标记为误报。
## 🫣 .gitignore 和 .forceignore 文件
默认情况下,ASIST 将忽略定义在 .gitignore 和 .forceignore 中的文件和文件夹。如果您不希望 ASIST 遵循 .gitignore 和 .forceignore,可以在配置文件中使用以下属性:
- **dontgitignore**
- **dontforceignore**
### ⍈ 退出代码
| 退出代码 | 退出原因 |
| --------- | -------------------------------------------------------- |
| 0 | ASIST 执行成功且未发现任何问题 |
| 1 | ASIST 执行成功并发现了问题 |
| 3 | ASIST 因内部错误而失败(请提交错误报告!) |
| 4 | ASIST 因用户错误而失败(请检查输入和配置) |
## 🏗️ [贡献](CONTRIBUTING.md)
## 🎫 [许可证](LICENSE.txt)
## ❤️ 贡献者
衷心感谢所有为 ASIST 做出贡献的开发者!
标签:Apex代码扫描, API安全, EVTX分析, Go语言, Homebrew安装, JSON输出, Salesforce, SAST, VSCode扩展, XSS检测, YAML配置, 代码安全, 安全基线, 安全扫描, 教学环境, 日志审计, 时序注入, 漏洞枚举, 盲注攻击, 硬编码密钥检测, 程序破解, 自动化安全审查, 自定义规则, 误报管理, 错误基检测, 静态代码分析, 静态应用安全测试