Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
trailmark — ソースコードのグラフデータベース表現を構築し、クエリを実行する | Kitploit
ツール/GitHubGitHub/trailofbits/trailmark
静的分析脆弱性分析コード分析ファジングバイナリ解析学習と教育
GitHubtrailofbits/trailmark

trailmark

ソースコードのグラフデータベース表現を構築し、クエリを実行する

リポジトリを見る
46329254日前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
# Trailmark

[![CI](https://github.com/trailofbits/trailmark/actions/workflows/ci.yml/badge.svg)](https://github.com/trailofbits/trailmark/actions/workflows/ci.yml)
[![Mutation Testing](https://github.com/trailofbits/trailmark/actions/workflows/mutation.yml/badge.svg)](https://github.com/trailofbits/trailmark/actions/workflows/mutation.yml)

ソースコードを、関数、クラス、呼び出し、セマンティックアノテーションのクエリ可能なグラフに解析し、セキュリティ分析に活用します。

Trailmarkは、言語に依存しないAST解析に[tree-sitter](https://tree-sitter.github.io/)を、高性能なグラフ探索に[rustworkx](https://www.rustworkx.org/)を使用しています。長期的なビジョンは、このグラフをミューテーションテストやカバレッジガイド付きファジングと組み合わせることで、ユーザー入力から到達可能な、前提とテストカバレッジの間のギャップを特定することです。

## 仕組み

Trailmarkは、**parse**、**index**、**query**の3つのフェーズで動作します。

```mermaid
flowchart TD
    A["Source Files"] --> B["tree-sitter Parser"]
    B --> C["CodeGraph (nodes + edges)"]
    C --> D["rustworkx GraphStore"]
    D --> E["QueryEngine"]
    E --> F["JSON / Summary / Hotspots"]

    classDef src fill:#007bff26,stroke:#007bff,color:#007bff
    classDef parse fill:#28a74526,stroke:#28a745,color:#28a745
    classDef data fill:#6f42c126,stroke:#6f42c1,color:#6f42c1
    classDef query fill:#ffc10726,stroke:#e6a817,color:#e6a817

    class A src
    class B parse
    class C,D data
    class E,F query
```

### 1. パース

言語固有のパーサーがディレクトリを走査し、各ファイルを tree-sitter AST にパースして以下を抽出します:

- **ノード** — 関数、メソッド、クラス、構造体、インターフェース、トレイト、列挙型、モジュール、名前空間
- **エッジ** — 呼び出し、継承、実装、包含、インポート
- **メタデータ** — 型注釈、循環的複雑度、分岐、docstring、例外型

### 対応言語

| 言語 | 拡張子 | 主要な構文要素 |
| --- | --- | --- |
| Python | `.py` | 関数、クラス、メソッド |
| JavaScript | `.js`, `.jsx`, `.mjs`, `.cjs` | 関数、クラス、アロー関数 |
| TypeScript | `.ts`, `.tsx` | 関数、クラス、インターフェース、列挙型 |
| PHP | `.php` | 関数、クラス、インターフェース、トレイト |
| Ruby | `.rb` | メソッド、クラス、モジュール |
| C | `.c`, `.h` | 関数、構造体、列挙型 |
| C++ | `.cpp`, `.hpp`, `.cc`, `.hh`, `.cxx`, `.hxx` | 関数、クラス、構造体、名前空間 |
| C# | `.cs` | メソッド、クラス、インターフェース、構造体、列挙型、名前空間 |
| Java | `.java` | メソッド、クラス、インターフェース、列挙型 |
| Go | `.go` | 関数、メソッド、構造体、インターフェース |
| Rust | `.rs` | 関数、構造体、トレイト、列挙型、impl ブロック、`verus!` ブロック |
| Solidity | `.sol` | コントラクト、インターフェース、ライブラリ、関数、修飾子、構造体、列挙型 |
| Cairo | `.cairo` | 関数、トレイト、構造体、列挙型、impl ブロック、StarkNet コントラクト |
| Circom | `.circom` | テンプレート、関数、シグナル、コンポーネント |
| Haskell | `.hs` | 関数、データ型、型クラス、インスタンス |
| Erlang | `.erl` | 関数、レコード、ビヘイビア、モジュール |
| Miden Assembly | `.masm` | プロシージャ、エントリポイント、定数、呼び出し |
| Swift | `.swift` | 関数、クラス、構造体、列挙型、プロトコル、拡張 |
| Objective-C | `.m`, `.mm`, `.h` | C 関数、クラス、メソッド(セレクタベースの命名) |
| Kotlin | `.kt`, `.kts` | 関数、クラス、インターフェース、データクラス、オブジェクト、メソッド |
| Dart | `.dart` | 関数、クラス、抽象クラス、メソッド、コンストラクタ |
| Move | `.move` | モジュール、関数、インポート、直接呼び出し |
| Tact | `.tact` | コントラクト、構造体、レシーバ、関数 |
| Func | `.fc`, `.func` | 関数、インクルード、直接呼び出し |
| Sway | `.sw` | ABI インターフェース、構造体、impl メソッド、関数 |
| Rego | `.rego` | パッケージ、インポート、ポリシールール、ルール呼び出し |
| Proto | `.proto` | サービス、RPC、メッセージ、フィールド、列挙型 |
| Thrift | `.thrift` | サービス、関数、構造体、フィールド、列挙型 |
| GraphQL | `.graphql`, `.gql` | オブジェクト型、ルート操作、フィールド、列挙型 |
| SQL | `.sql` | スキーマ、テーブル、ビュー、関数、プロシージャ |

Rustパーサーは、`verus! { ... }` ブロックから本体を持つ通常の関数、`spec` 関数、`proof` 関数を抽出します。Verus の文法は現在、波括弧で区切られたブロックのみをサポートしており、`verus!(...)` と `verus![...]` は警告付きでスキップされます。インラインモジュールは修飾 ID(例えば `file.inner:function`)を保持し、メソッドはその impl またはトレイトの所有者を保持します。各ブロックは独立して解析され、構文エラーはファイルとブロックの位置を含む警告を生成します。`vstd::prelude::verus!` のような修飾された呼び出しもサポートされています。ローカルヘルパー関数は、その ID に外側の関数を保持します(例えば `file:outer.inner`)。これらのヘルパーへの呼び出しや、`use super::*` のような相対インポートは、ファイル内に存在する宣言に解決されます。異なるブロック内で繰り返されるローカル名には、ノードを区別するためにバイトオフセットの接尾辞が付与され、呼び出しはブロックスコープを尊重します。ローカルの構造体、列挙型、トレイト、インラインモジュールも外側の関数を保持します。例えば `file:outer.Guard.drop` や `file:outer.local.helper` のようになります。これらの本体は別個の呼び出しと複雑度を持ちます。既知のローカル型やモジュールへの明示的な呼び出しは、ファイル内で解決されます。裸の呼び出しは関数スコープとモジュールスコープを検索し、関連項目は `Type::method` のようなパスを使用します。ドット付き呼び出しは、レシーバが既知の構造体または列挙型を指す場合にのみ解決されます。`self.method()` を含むその他の値レシーバは未解決のままです。暗黙のデストラクタ呼び出しとレシーバの型推論はモデル化されません。これらの規則は通常の Rust にも Verus ブロックにも適用されます。オフセット接尾辞を持つ宣言の前のコードを編集するとその ID が変わるため、`trailmark diff` はその宣言を削除および追加として報告する可能性があります。

Trailmark は任意のマクロを展開しません。不透明なマクロや関数本体の中にあるリテラルの Verus 呼び出しは、警告付きでスキップされます。呼び出されていない `macro_rules!` 定義は展開されません。本体を持たない関数シグネチャや、`requires`/`ensures` 節内の呼び出しは抽出されません。

```mermaid
flowchart TD
    subgraph "Per-File Parsing"
        F["Source file"] --> TS["tree-sitter AST"]
        TS --> EX["Extract nodes"]
        TS --> EC["Extract call edges"]
        TS --> EB["Count branches"]
        TS --> ET["Resolve types"]
    end

    EX --> CG["CodeGraph"]
    EC --> CG
    EB --> CG
    ET --> CG

    classDef src fill:#007bff26,stroke:#007bff,color:#007bff
    classDef parse fill:#28a74526,stroke:#28a745,color:#28a745
    classDef extract fill:#ffc10726,stroke:#e6a817,color:#e6a817
    classDef data fill:#6f42c126,stroke:#6f42c1,color:#6f42c1

    class F src
    class TS parse
    class EX,EC,EB,ET extract
    class CG data
```

ノードIDは、曖昧さのない検索のために `module:function`、`module:Class`、または `module:Class.method` というスキームに従います。ディレクトリ解析では、一意な定義が存在する場合にファイルをまたぐベア呼び出しを解決します。曖昧なファイル横断呼び出しは元のベストエフォートのターゲットのままにされ、`uncertain` とマークされます。エッジの信頼度は、`certain`(直接呼び出し、`self.method()`)、`inferred`(非selfオブジェクトへの属性アクセス)、または `uncertain`(動的ディスパッチまたは曖昧な解決)としてタグ付けされます。

### 2. インデックス

`GraphStore` は `CodeGraph` を rustworkx の `PyDiGraph` にロードし、高速なトラバーサルのために双方向のID/インデックスマッピングを構築します。

### 3. クエリ

`QueryEngine` は、インデックス化されたグラフに対する高レベルのAPIを提供します:

| メソッド | 説明 |
| --- | --- |
| `callers_of(name)` | 指定されたターゲットの直接の呼び出し元 |
| `callees_of(name)` | 指定されたソースの直接の呼び出し先 |
| `ancestors_of(name)` | ターゲットに推移的に到達できるすべての関数(上方向スライス) |
| `reachable_from(name)` | ソースから推移的に到達可能なすべての関数 |
| `paths_between(src, dst)` | 2つのノード間のすべての単純な呼び出しパス |
| `connect_subgraphs(source, target)` | 2つの名前付きサブグラフを接続するパス |
| `entrypoint_paths_to(name)` | 検出された任意のエントリポイントからターゲットへのパス |
| `attack_surface()` | 存在する場合、信頼レベル、資産価値、パーサー属性でタグ付けされたエントリポイント |
| `complexity_hotspots(n)` | 循環的複雑度が ≥ n の関数 |
| `functions_that_raise(exc)` | パーサーが検出した例外リストに `exc` が含まれる関数 |
| `generic_parameters(name)` | ノードによって宣言されたジェネリック型パラメータ |
| `type_references(name)` | パラメータ、戻り値、例外、およびジェネリック境界の型参照 |
| `annotate(name, kind, description, source)` | ノードにセマンティックアノテーションを追加 |
| `annotations_of(name, kind=None)` | ノードのアノテーションを取得(オプションで種類によるフィルタリング) |
| `nodes_with_annotation(kind)` | 指定されたアノテーション種別でタグ付けされたすべてのノード |
| `clear_annotations(name, kind=None)` | ノードからアノテーションを削除 |
| `diff_against(other)` | このエンジンのグラフと別のグラフとの構造的差分 |
| `preanalysis()` | 組み込みの事前解析パスを実行し、アノテーション/サブグラフを保存 |
| `augment_sarif(path)` | SARIFの検出結果をグラフにマージ |
| `augment_weaudit(path)` | weAuditの検出結果をグラフにマージ |
| `augment_binary(path)` | 外部のバイナリ解析グラフJSONファイルをマージ |
| `findings(kind=None)` | 検出結果形式のアノテーションを持つノードを返す |
| `subgraph(name)` | 名前付きサブグラフ内のノードを返す |
| `subgraph_edges(name)` | 名前付きサブグラフ内の誘導エッジを返す |
| `subgraph_names()` | 現在グラフ上にあるすべての名前付きサブグラフをリスト |
| `summary()` | ノード数、エッジ数、依存関係 |
| `to_json()` | グラフ全体のエクスポート |

### データモデル

```mermaid
classDiagram
    class CodeGraph {
        language: str
        root_path: str
        nodes: dict[str, CodeUnit]
        edges: list[CodeEdge]
        annotations: dict[str, list[Annotation]]
        entrypoints: dict[str, EntrypointTag]
        dependencies: list[str]
        add_annotation(node_id, annotation)
        clear_annotations(node_id, kind=None)
        merge(other)
    }

    class CodeUnit {
        id: str
        name: str
        kind: NodeKind
        location: SourceLocation
        parameters: tuple[Parameter]
        return_type: TypeRef
        exception_types: tuple[TypeRef]
        cyclomatic_complexity: int
        branches: tuple[BranchInfo]
        docstring: str
    }

    class CodeEdge {
        source_id: str
        target_id: str
        kind: EdgeKind
        confidence: EdgeConfidence
    }

    class Annotation {
        kind: AnnotationKind
        description: str
        source: str
    }

    class EntrypointTag {
        kind: EntrypointKind
        trust_level: TrustLevel
        description: str
        asset_value: AssetValue
    }

    CodeGraph "1" *-- "*" CodeUnit
    CodeGraph "1" *-- "*" CodeEdge
    CodeGraph "1" *-- "*" Annotation
    CodeGraph "1" *-- "*" EntrypointTag
```

**ノード種別:** `function`、`method`、`class`、`module`、`struct`、`interface`、`trait`、`enum`、`namespace`、`contract`、`library`、`template`、`proxy`

**ノードの由来:** `source`、`proxy`、`binary`、`synthetic`

**エッジ種別:** `calls`、`inherits`、`implements`、`contains`、`imports`、`resolves_to`、`type_uses`、`specializes`、`corresponds_to`

**エッジの信頼度:** `certain`、`inferred`、`uncertain`

未解決の呼び出しは `proxy.unresolved:<raw-symbol>` のようなプロキシノードとして実体化されるため、トラバーサル結果では、ソース解析が解決に失敗した箇所をそのエッジを黙って破棄する代わりに示すことができます。ディレクトリのパース(単一言語のパースを含む)でも、リポジトリリンクが適用され、`TYPE_USES` エッジが実体化されます。バイナリ解析のサポートは外部の JSON コールグラフをインポートします。Trailmark 自体は実行ファイルの逆アセンブルを行いません。

### グラフの例

次の Python コードがあるとします:

```python
class Auth:
    def verify(self, token: str) -> bool:
        return self._check_sig(token)

    def _check_sig(self, token: str) -> bool:
        ...

def handle_request(req: Request) -> Response:
    auth = Auth()
    if auth.verify(req.token):
        return process(req)
    return deny()
```

Trailmark は次のようなグラフを生成します:

```mermaid
graph TD
    HR["handle_request"] -->|calls| AV["Auth.verify"]
    HR -->|calls| P["process"]
    HR -->|calls| D["deny"]
    AV -->|calls| CS["Auth._check_sig"]
    A["Auth"] -->|contains| AV
    A -->|contains| CS

    classDef fn fill:#007bff26,stroke:#007bff,color:#007bff
    classDef cls fill:#6f42c126,stroke:#6f42c1,color:#6f42c1

    class HR,P,D fn
    class A,AV,CS cls
```

## インストール

以下の例は現在の開発ブランチを対象としています。最新の
公開パッケージを利用する場合は PyPI からインストールしてください。ここで説明する
機能セットを正確に利用するには、チェックアウトからインストールし、`uv run` 経由でコマンドを実行してください。

```bash
# Latest published release
uv pip install trailmark

# Current checkout / development branch
uv sync --all-groups
```

Python &ge; 3.12 が必要です。

Trailmark はほとんどの文法で `tree-sitter-language-pack` 1.22.1 以降を必要とします。
root 所有の文法キャッシュは、グループやその他のユーザーによる書き込みが許可されていない場合にサポートされます。
現在のリリースでは、文法のダウンロードにプラットフォームの証明書ストアを使用します。
TLS 検査環境やオフライン環境では、一致するプラットフォーム上で
`python -c "import tree_sitter_language_pack as p; p.download_all()"` を実行してパッケージキャッシュを事前に用意し、
生成された `tree-sitter-language-pack` キャッシュディレクトリを対象マシンにコピーしてください。`HTTPS_PROXY` も尊重されます。SQL 文法は
`tree-sitter-sql` wheel 依存として同梱されており、そのキャッシュは使用しません。

同梱の Circom、Miden Assembly、Verus 文法は初回使用時にコンパイルされます。
これには C コンパイラ (`cc`)、Python 開発ヘッダー、およびインストール済みの文法ディレクトリへの書き込みアクセスが必要です。
Verus ブロックを含まない Rust ファイルはコンパイルをトリガーしません。Verus 文法をビルドまたはロードできない場合、Trailmark は
警告をログに記録し、Verus ブロックをスキップして、通常の Rust の解析を続行します。
Verus バインディングキャッシュには、コンパイル済みソースの内容、Python ABI、
プラットフォーム、およびコンパイラオプションが含まれます。入力が変更されると新しいバインディングが選択され、完了した
ビルドはアトミックに公開されます。コンパイラの失敗には、警告内に終了ステータスと
stderr が含まれます。

Git チェックアウトでは Verus 文法定義が保持され、ビルド時に Tree-sitter CLI 0.27.1 を使用してその C パーサーが生成されます。チェックアウト内で `uv sync` または `uv build` を実行する前に、
npm インストールスクリプトを有効にして `npm ci` を実行してください。生成には Node.js が必要です。
生成されたパーサーとヘッダーは gitignore されます。wheel とソースディストリビューションには
これらの生成済みソースが含まれるため、公開済みパッケージのインストールには Node.js も Tree-sitter CLI も不要です。
編集可能な `uv` インストールでは、ビルドフックが再実行されて不足している生成ファイルが復元されます。
入力が変更されていなければ、既存の出力が再利用されます。

## 使用方法

```bash
# Report the installed version
trailmark --version     # or: trailmark -V
trailmark version       # subcommand form

# Full JSON graph (Python, the default)
trailmark analyze path/to/project

# Analyze a different language
trailmark analyze --language rust path/to/project
trailmark analyze --language javascript path/to/project

# Polyglot: auto-detect and merge every supported language found in the
# tree, or pass an explicit comma-separated list.
trailmark analyze --language auto path/to/project
trailmark analyze --language python,rust,solidity path/to/project

# Summary statistics
trailmark analyze --summary path/to/project

# Complexity hotspots (threshold >= 10)
trailmark analyze --complexity 10 path/to/project

# Augment the graph with external findings (SARIF from static analyzers,
# weAudit findings from the VS Code extension). Each --sarif / --weaudit
# flag is repeatable. Add --json to print the augmented graph.
trailmark augment --sarif results.sarif path/to/project
trailmark augment --weaudit findings.json path/to/project
trailmark augment --sarif a.sarif --sarif b.sarif --json path/to/project

# List detected entrypoints (attack surface). Uses heuristic detection
# (main() functions, pyproject.toml [project.scripts]) plus an optional
# override file at .trailmark/entrypoints.toml (see below).
trailmark entrypoints path/to/project
trailmark entrypoints --json path/to/project

# Structural diff between two code graphs. Accepts directory paths or
# git refs (branches, tags, commits). Surfaces added/removed nodes,
# call-edge changes, and — most usefully — attack-surface changes.
trailmark diff before/ after/
trailmark diff --repo . main HEAD          # compare git refs
trailmark diff --json before/ after/        # machine-readable output

# Generate a Mermaid diagram from the code graph. --type is required; the
# choices are call-graph, class-hierarchy, module-deps, containment,
# complexity, and data-flow. Use --focus to scope large graphs.
trailmark diagram --target path/to/project --type call-graph
trailmark diagram -t path/to/project -T call-graph -f parse_file --depth 3
trailmark diagram -t path/to/project -T complexity --threshold 5 --direction LR
```

### エントリポイント検出

Trailmark は `graph.entrypoints` を自動的に設定するため、`attack_surface()`、テイント伝播、特権境界の越境に利用できるデータが揃います。検出は4つのレイヤーで実行され、それぞれが前のレイヤーを上書きします:

1. **汎用 `main` ヒューリスティック。** 任意の言語で `main` という名前の関数。`user_input` / `trusted_internal` / `low` としてタグ付けされます。
2. **フレームワーク対応スキャン。** 言語ごとのデコレータ、属性、可視性パターン — 以下の表を参照してください。
3. **`pyproject.toml [project.scripts]`。** 明示的な CLI ターゲットは、信頼性/アセットの分類がアップグレードされます。
4. **リポジトリローカルのオーバーライドファイル。** `.trailmark/entrypoints.toml` に手動でキュレーションされたエントリポイントが常に優先されます。

フレームワークのカバレッジ:

| 言語 | 検出されるフレームワーク |
| --- | --- |
| Python | Flask、FastAPI、aiohttp、Click、Typer、Celery |
| JavaScript / TypeScript | NestJS、Next.js(App Router + Pages API)、AWS Lambda |
| Java | Spring MVC / WebFlux、JAX-RS、Kafka リスナー、サーブレット |
| C# | ASP.NET Core、Azure Functions |
| PHP | Symfony の `#[Route]` 属性 + レガシーアノテーション |
| Rust | actix-web、rocket、FFI エクスポート(`#[no_mangle]`、`pub extern "C"`)、async-main 属性 |
| Solidity | `external` / `public` 可視性 |
| Cairo / StarkNet | `#[external]`、`#[view]`、`#[l1_handler]`、`#[constructor]` |
| Circom | `component main` 宣言 |
| Miden Assembly | `export.<name>` ディレクティブ |
| Haskell | トップレベルの `main ::` / `main =` |
| Erlang | `-export([...])` にリストされた関数 |
| Swift | `@main` アプリ属性 |
| Objective-C | `UIApplicationDelegate` ライフサイクルセレクタ(例:`application:openURL:options:`) |
| Kotlin | Spring MVC / WebFlux アノテーション(Java と共有)、Android コンポーネントのライフサイクルメソッド(`onCreate`、`onReceive`、`onBind`、...) |
| Dart | `@pragma('vm:entry-point')` ネイティブ呼び出し可能マーカー |
| Go | `http.HandleFunc` / `http.Handle` 標準ライブラリ登録、gin/chi/echo スタイルの `<router>.GET/POST/...` ハンドラ登録 |
| Ruby | Rails コントローラアクション(`ApplicationController` / `ActionController::*` を継承するクラス)、Sidekiq ワーカーの `perform` メソッド |
| C / C++ | `extern "C"` リンケージ、`__attribute__((visibility("default")))`、`__declspec(dllexport)` |

ヒューリスティックが見逃すものについては、プロジェクトルートの `.trailmark/entrypoints.toml` でエントリポイントを明示的に宣言してください。このファイルは単一ノードエントリとルールベースエントリの両方をサポートします:

```toml
# Single-node entry
[[entrypoint]]
node = "my_module:handle_request"  # node id, or "module.path:function"
kind = "api"                       # user_input | api | database | file_system | third_party
trust = "untrusted_external"       # untrusted_external | semi_trusted_external | trusted_internal
asset_value = "high"               # high | medium | low
description = "HTTP POST /auth"

# Rule: every PHP script under public_html/ is a web-exposed entrypoint.
[[entrypoint]]
file_glob = "public_html/**/*.php"
kind = "user_input"
trust = "untrusted_external"
asset_value = "high"
description = "Web-exposed PHP script"

# Rule: any function that takes a PSR-7 request object.
[[entrypoint]]
param_type = "ServerRequestInterface"
kind = "api"
trust = "untrusted_external"
asset_value = "high"
description = "PSR-7 HTTP handler"

# Rule: functions named `handle_*`.
[[entrypoint]]
name_regex = "^handle_"
kind = "api"
trust = "untrusted_external"

# Rule: conditions compose with AND — web.py files AND name starts with handle_.
[[entrypoint]]
file_glob = "public/*.py"
name_regex = "^handle_"
kind = "api"
trust = "untrusted_external"
```

2つのルールが同じノードにタグを付ける場合、後のエントリが前のエントリを上書きするため、広範なルールを先に、具体的な修正を後に配置してください。

完全なリファレンスについては、[docs/entrypoint-patterns.md](https://github.com/trailofbits/trailmark/blob/main/docs/entrypoint-patterns.md) を参照してください。これにはまだ実装されていないフレームワーク(Express / Koa / Fastify、Laravel、Cobra、axum、warp、clap など)が含まれており、コントリビューターが新しい検出器を追加するために使用できる grep 対応のパターンが記載されています。

Solidity の検出は、シグネチャの正規表現ではなくパーサーのメタデータを使用します。インターフェース宣言は除外され、派生したオーバーライドは、基底のエントリポイントを削除するのではなく、一致する基底実装に `solidity_overridden_by` を付与して注釈を付けます。具象の `public` および `external` 関数は、`view` および `pure` 関数を含めてエントリポイントとして残ります。これらの `solidity_visibility`、`solidity_mutability`、およびオーバーライド属性は `attack_surface()` によって返されるため、呼び出し元は読み取り専用の公開とオーバーライドされた基底実装を区別してフィルタリングできます。`attack_surface()` は、基になるグラフノードに付与されている場合、パーサー固有のエントリポイント属性を含みます。

### 言語間および外部リンク

ポリグロット解析は言語グラフをマージしますが、多くの RPC、FFI、サブプロセス、およびホスト/コントラクトの関係はソース構文では可視化されません。これらは `.trailmark/links.toml` で決定的に宣言してください:

```toml
[[link]]
source = "backend:submit"
target = "contract:Verifier.verify"
kind = "calls"                 # defaults to calls
confidence = "certain"         # defaults to inferred
description = "JSON-RPC eth_call"

[[link]]
source = "backend:notify"
target = "payments-webhook"
target_external = true         # required because target is unresolved
```

参照は正確なノードIDまたは一意な名前/サフィックスで指定できます。曖昧な参照、未知の内部エンドポイント、無効なenum値、不正なTOMLは`ValueError`を発生させます。`source_external = true`または`target_external = true`を設定すると、その未解決のエンドポイントを明示的に許可し、プロキシノードを作成します。このファイルは安定した公開設定インターフェースです。

### 分析の制限事項

- `entrypoint_paths_to()`はコールグラフの到達可能性を報告するものであり、攻撃者が制御するデータフローではありません。事前解析のテイント結果を粗い別個のシグナルとして使用してください。Trailmarkはまだ手続き間テイント分析を実行しません。
- TypeScriptは直接呼び出しと、`new ConcreteClass()`で代入された単純なレシーバを解決します。マニフェストを介したインターフェースディスパッチ、計算されたプロパティ名、依存性注入コンテナ、その他の動的メカニズムはベストエフォートのままです。
- SQLサポートはPostgreSQL指向で、スキーマ、テーブル、ビュー、関数、プロシージャ、およびルーチン/ビューの依存関係を抽出します。完全なSQL方言バリデータやクエリセマンティックアナライザではありません。

### プログラムAPI

```python
from trailmark.parse import parse_directory, parse_file
from trailmark.query.api import QueryEngine

# Parse-only API: get the raw CodeGraph without building GraphStore/QueryEngine.
graph = parse_file("path/to/file.py")
graph = parse_directory("path/to/project", language="auto")

# Single-language (default) or auto-detect + merge across all languages
engine = QueryEngine.from_directory("path/to/project")
engine = QueryEngine.from_directory("path/to/project", language="auto")
engine = QueryEngine.from_directory("path/to/project", language="python,rust")

# Direct neighbors
engine.callers_of("handle_request")
engine.callees_of("handle_request")

# Transitive slicing — who could reach this sink, or what could it reach?
engine.ancestors_of("Auth._check_sig")
engine.reachable_from("handle_request")

# Attack-surface paths from any detected entrypoint
engine.entrypoint_paths_to("Auth._check_sig")

# All call paths between two nodes
engine.paths_between("handle_request", "Auth._check_sig")

# Functions with cyclomatic complexity >= 10
engine.complexity_hotspots(10)

# What functions can raise a given exception? (uses parser-detected
# exception_types; no runtime tracing required)
engine.functions_that_raise("PermissionError")

# Add and query semantic annotations
from trailmark.models.annotations import AnnotationKind

engine.annotate(
    "handle_request",
    AnnotationKind.ASSUMPTION,
    "Caller has already authenticated the session token",
    source="llm",
)
engine.annotations_of("handle_request")
engine.nodes_with_annotation(AnnotationKind.FINDING)

# Diff against an earlier snapshot of the same codebase
before = QueryEngine.from_directory("before/")
diff = engine.diff_against(before)
# diff contains: summary_delta, nodes {added/removed/modified},
# edges {added/removed}, entrypoints {added/removed/modified}

# Run the built-in audit-oriented preanalysis passes
engine.preanalysis()
engine.findings()
engine.subgraph_names()

# Programmatic augmentation hooks for external tooling
engine.augment_sarif("results.sarif")
engine.augment_weaudit("findings.json")
```

`NodeKind.SCHEMA`、`TABLE`、`VIEW`、`PROCEDURE` は v0.5.0 で追加されました。
enum の値を網羅的にマッチするコンシューマは、それらのケースを追加する必要があります。

## 開発

```bash
# Install package and dev dependencies
npm ci
uv sync --all-groups

# Lint and format
uv run ruff check --fix
uv run ruff format

# Type check
uv run --locked ty check

# Tests
uv run pytest -q tests/

# Mutation testing with pytest-gremlins
uv run python -m tests.run_mutations --reviewed --workers=4
uv run python -m tests.mutation_gate

# Full repository mutation campaign
uv run python -m tests.run_mutations --workers=4
```

---

[Read more](https://github.com/trailofbits/trailmark)
ツールをダウンロード