cogniumhq/circle-ir

GitHub: cogniumhq/circle-ir

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

Stars: 3 | Forks: 0

# circle-ir ![信任分数](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/cf65807a36074959.svg) ![质量分数](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/4b21529bad074959.svg) 一个高性能的静态应用安全测试 (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 作为预处理器处理:`