cogniumhq/circle-ir
GitHub: cogniumhq/circle-ir
一个高性能、零依赖、可同时运行在 Node.js 和浏览器端的 SAST 库,通过污点分析和 36 遍分析管道检测安全漏洞与代码质量问题,支持六种主流语言。
Stars: 3 | Forks: 0
# circle-ir


一个高性能的静态应用安全测试 (SAST) 库,用于通过污点分析检测安全漏洞,并通过可扩展的 36 遍分析管道检测代码质量问题。支持在 Node.js 和浏览器中运行。
## 功能特性
- **污点分析**:跟踪从数据源(用户输入)到汇聚点(危险操作)的数据流
- **多语言支持**:Java、JavaScript/TypeScript、Python、Rust、Bash/Shell、HTML
- **高准确率**:OWASP Benchmark 100%,Juliet Test Suite 100%,SecuriBench Micro 97.7% TPR
- **36 遍分析管道**:19 个安全污点分析遍 + 17 个可靠性/性能/可维护性/架构质量分析遍
- **指标引擎**:24 项软件质量指标(圈复杂度、Halstead、CBO、RFC、LCOM、DIT 和 4 项综合评分)
- **跨文件分析**:`analyzeProject()` 呈现跨越多个文件的污点流
- **通用性**:核心代码与环境无关,支持在 Node.js 和浏览器中运行
- **零外部依赖**:核心分析过程无需网络调用或外部服务
- **浏览器兼容**:使用 Tree-sitter WASM 进行通用解析
- **配置驱动**:使用 YAML/JSON 模式配置数据源、汇聚点和过滤器
## 安装
```
npm install circle-ir
```
## 快速开始
### Node.js
```
import { initAnalyzer, analyze } from 'circle-ir';
// Initialize the analyzer
await initAnalyzer();
// Analyze Java code
const result = await analyze(code, 'MyClass.java', 'java');
// Security taint flows
for (const flow of result.taint.flows || []) {
console.log(`Found ${flow.sink_type} vulnerability`);
console.log(` Source: line ${flow.source_line}`);
console.log(` Sink: line ${flow.sink_line}`);
}
// Quality findings from all 36 analysis passes
for (const finding of result.findings || []) {
console.log(`[${finding.severity}] ${finding.rule_id} at line ${finding.line}`);
console.log(` ${finding.message}`);
if (finding.fix) console.log(` Fix: ${finding.fix}`);
}
// Software quality metrics
const m = result.metrics;
if (m) {
console.log(`Cyclomatic complexity: ${m.cyclomatic_complexity}`);
console.log(`Maintainability index: ${m.maintainability_index}`);
console.log(`CBO (coupling): ${m.CBO}`);
}
```
### 浏览器
```
```
## API 参考
### `initAnalyzer(options?)`
初始化分析器。必须在调用 `analyze()` 之前调用。
```
interface AnalyzerOptions {
wasmPath?: string; // Path to web-tree-sitter.wasm
languagePaths?: { // Paths to language WASM files
java?: string;
javascript?: string;
python?: string;
rust?: string;
};
taintConfig?: TaintConfig; // Custom taint configuration
passOptions?: PassOptions; // Per-pass configuration (thresholds, patterns)
disabledPasses?: string[]; // Passes to skip (e.g., ['naming-convention'])
}
interface PassOptions {
dependencyFanOut?: {
threshold?: number; // Max imports before flagging (default: 20)
};
unboundedCollection?: {
skipPatterns?: string[]; // Variable names to ignore
};
namingConvention?: {
classPattern?: string; // Regex for class names
methodPattern?: string; // Regex for method names
};
}
```
**示例:在运行时配置分析遍**
```
await initAnalyzer({
passOptions: {
dependencyFanOut: { threshold: 50 },
unboundedCollection: { skipPatterns: ['results', 'items', 'cache'] },
},
disabledPasses: ['naming-convention', 'missing-public-doc'],
});
```
### `analyze(code, filePath, language, options?)`
分析单个文件并返回 Circle-IR 输出。
```
const result = await analyze(code, 'File.java', 'java');
// Result contains:
result.meta // File metadata
result.types // Classes, methods, fields
result.calls // Method invocations
result.cfg // Control flow graph
result.dfg // Data flow graph
result.taint // Taint sources, sinks, flows
result.imports // Import statements
result.exports // Exported symbols
result.findings // SastFinding[] from all 36 analysis passes
result.metrics // FileMetrics — 24 software quality metrics (always populated)
```
### `analyzeProject(files, options?)`
同时分析多个文件,以检测跨文件的污点流。
```
import { analyzeProject } from 'circle-ir';
const result = await analyzeProject([
{ code: controllerCode, filePath: 'UserController.java', language: 'java' },
{ code: serviceCode, filePath: 'UserService.java', language: 'java' },
{ code: daoCode, filePath: 'UserDao.java', language: 'java' },
]);
// Per-file analysis (same as analyze() per file)
for (const { file, analysis } of result.files) {
console.log(`${file}: ${analysis.taint.flows?.length ?? 0} intra-file flows`);
}
// Cross-file taint paths (the key deliverable)
for (const path of result.taint_paths) {
console.log(`Cross-file ${path.sink.type}: ${path.source.file} → ${path.sink.file}`);
console.log(` Confidence: ${path.confidence.toFixed(2)}, CWE: ${path.sink.cwe}`);
}
// Resolved inter-file method calls
console.log(`${result.cross_file_calls.length} cross-file calls resolved`);
// Project metadata
console.log(`${result.meta.total_files} files, ${result.meta.total_loc} LOC`);
```
### `analyzeForAPI(code, filePath, language, options?)`
适用于 REST API 的简化响应格式。
```
const response = await analyzeForAPI(code, 'File.java', 'java');
// Response format:
{
success: true,
analysis: {
sources: [...],
sinks: [...],
vulnerabilities: [...]
},
meta: {
parseTimeMs: 15,
analysisTimeMs: 42,
totalTimeMs: 57
}
}
```
## 支持的语言
| 语言 | 解析器 | 框架 |
|----------|--------|------------|
| **Java** | tree-sitter-java | Spring, JAX-RS, Servlet API |
| **JavaScript/TypeScript** | tree-sitter-javascript | Express, Fastify, Koa, Node.js |
| **Python** | tree-sitter-python | Flask, Django, FastAPI |
| **Rust** | tree-sitter-rust | Actix-web, Rocket, Axum |
| **Bash/Shell** | tree-sitter-bash | Shell 脚本 |
| **HTML** | tree-sitter-html | Web 提取预处理器 |
HTML 作为预处理器处理:`