Skip to content

Instantly share code, notes, and snippets.

@podhmo
Created June 1, 2025 16:16
Show Gist options
  • Save podhmo/b7e8c703eb8d3c647e769cbaa1a03644 to your computer and use it in GitHub Desktop.
Save podhmo/b7e8c703eb8d3c647e769cbaa1a03644 to your computer and use it in GitHub Desktop.
安全なuiの描画

対話履歴

ユーザー: 根源的な話をしてください。

完全にRCEやコードインジェクションに対して安全なGUIについて考えてくれませんか? 必須の条件とそれの満たし方について回答してください。

自作のuiレンダラーでui言語を解釈するという形で考えてください。また信頼しているホスト同士のe2eのコネクションが確立してるとします。


AI: 根源的な話をしましょう。完全にRCE(リモートコード実行)やコードインジェクションに対して安全なGUIシステムを自作UIレンダラーとUI言語で構築するための必須条件と、それを満たす方法について考察します。信頼しているホスト同士のE2Eコネクションが確立しているという前提も考慮に入れます。

「完全に安全」の目標設定

まず、「完全に安全」とは、GUIの定義や操作を通じて、意図しないコードが実行されたり、システムが不正に操作されたりする可能性を限りなくゼロに近づけることを意味します。具体的には、以下の脅威を防ぐことを目指します。

  • RCE: GUIシステムを介して、OSコマンドや任意のスクリプトが実行されること。
  • コードインジェクション: UI定義言語やイベントハンドリングの仕組みに悪意のあるコードを注入され、それが解釈・実行されること。

根源的な原則

これらの脅威を防ぐためには、以下の根源的な原則に基づいた設計が不可欠です。

  1. UI記述言語の非チューリング完全性と宣言的特性:

    • 説明: UI言語自体に、任意の計算や複雑なロジックを実行できる能力(チューリング完全性)を持たせないことが最も重要です。UI言語は、画面の構造、見た目、静的なデータを「宣言的」に記述するものであり、手続き的なプログラムコードを記述するものであってはなりません。
    • 理由: これにより、言語仕様レベルで任意のコード実行の可能性を排除できます。
  2. データとコードの厳格な分離:

    • 説明: UI定義は純粋な「データ」として扱われるべきであり、そのデータが直接的に「コード」として解釈・実行されるような仕組み(例: eval() 関数やスクリプトタグの直接実行)を完全に排除します。
    • 理由: データとコードの境界が曖昧だと、巧妙なデータによって意図しないコード実行が引き起こされる可能性があります。
  3. 最小権限の原則とサンドボックス化:

    • 説明: UIレンダラーおよびUI言語の実行環境は、その機能を実現するために必要最小限の権限のみを持つべきです。ファイルシステムへのアクセス、ネットワーク通信、OSコマンドの実行などは原則として禁止し、必要な場合はホストアプリケーションを介して厳格な管理のもとで行われるべきです。
    • 理由: たとえ何らかの脆弱性が存在したとしても、権限が制限されていれば被害を最小限に抑えられます。

必須の条件とそれを満たす方法

上記の原則を踏まえ、具体的な必須条件とそれを満たす方法を以下に示します。

I. UI言語の設計レベル

  1. 条件: 静的な構造定義と限定された動的要素。

    • 満たし方:
      • UI言語は、JSON、XML、あるいは専用の構文を持つ静的な形式とし、UIの構造(どの要素がどこに配置されるか)、スタイル、表示するテキストなどを定義します。
      • if文やforループのような制御構造が必要な場合でも、汎用的なものではなく、UI構築に特化した限定的なもの(例: リスト要素の繰り返し描画、特定の条件下での要素の表示/非表示)に留めます。これらはレンダラー側で安全に解釈・処理されます。
      • 実行時に動的にコードを生成したり、外部からスクリプトを読み込んで実行するような機能は一切設けないでください。
  2. 条件: イベント処理の厳格な制約。

    • 満たし方:
      • ボタンクリックなどのイベントハンドリングは、UI言語内で直接コードを記述するのではなく、事前に定義された「アクションID」や「メッセージ」をホストアプリケーションに送信する形を取ります。
      • 例: <Button onClick="SEND_MESSAGE:UserClickedButton" />{"type": "Button", "onClick": {"action": "user_action_1", "payload": {"itemId": 123}}} のような形式。
      • UI言語側では、このメッセージの送信以上のことはできません。実際の処理ロジックは、信頼されたホストアプリケーション側で、受信したアクションIDやメッセージに基づいて安全に実行されます。
  3. 条件: 外部リソース参照の管理。

    • 満たし方:
      • 画像などの外部リソースを参照する場合、URLを直接指定するのではなく、抽象的なリソースIDを使用し、ホストアプリケーションがそのIDに対応する安全なリソースを提供するか、信頼できるソースからのURLのみを許可するホワイトリスト方式を採用します。
      • レンダラーが直接任意のURLにアクセスできないようにします。

II. UIレンダラーの実装レベル

  1. 条件: パーサーとインタープリターの安全性。

    • 満たし方:
      • UI言語のパーサー(構文解析器)は、バッファオーバーフローやその他のパース時の脆弱性がないように、メモリ安全なプログラミング言語(例: Rust, Go)を使用するか、慎重に実装します。
      • UI言語を解釈し、レンダリングするインタープリター部分は、定義された仕様外の動作をしないように厳格に作ります。未知の要素や属性は無視するか、エラーとして処理します。
  2. 条件: 実行環境の隔離 (サンドボックス化)。

    • 満たし方:
      • レンダラーは、OSの機能(ファイルアクセス、ネットワーク、プロセス起動など)に直接アクセスできないようにサンドボックス環境で動作させることが理想です。
      • これは、レンダラープロセスにOSレベルのサンドボックス(例: Linuxのseccomp-bpf, AppArmor、WindowsのAppContainer)を適用するか、WebAssembly (WASM) のようなサンドボックス化された実行環境をUIレンダリングの一部に利用することで実現できます。ただし、WASMからホスト機能を呼び出す場合は、そのインターフェースの安全性が重要です。
  3. 条件: 入力の厳格な検証とサニタイズ。

    • 満たし方:
      • UI言語で記述された全てのデータ(テキスト、数値、IDなど)は、レンダラー側で期待される型やフォーマットであるか厳格に検証します。
      • ユーザーが表示するテキストデータは、他のUI要素の構造を破壊したり、レンダラーの解釈を誤らせたりしないように、適切にエスケープ処理(例: HTMLエスケープに類似した処理)を行います。これを「出力エンコーディング」とも呼びます。
  4. 条件: 状態管理の分離とカプセル化。

    • 満たし方:
      • 各UIコンポーネントの状態は独立して管理され、他のコンポーネントに意図せず影響を与えないようにします。
      • 状態の変更は、明確に定義されたインターフェースを通じてのみ行われるようにします。

III. ホストアプリケーションとの連携レベル

  1. 条件: 明確に定義されたAPIとデータ形式。

    • 満たし方:
      • UIレンダラーとホストアプリケーション間の通信(イベント通知、データ要求など)は、事前に厳密に定義されたAPIを通じて行います。
      • やり取りされるデータは、JSONのような安全にシリアライズ/デシリアライズ可能な形式に限定し、実行可能なコードを含まないようにします。
  2. 条件: ホスト側の責任: 検証と権限管理。

    • 満し方:
      • UI側から送られてくるアクションIDやメッセージペイロードは、ホストアプリケーション側で再度検証し、そのアクションが現在のコンテキストで許可されているか、ペイロードの内容が妥当かを確認します。
      • UI側からの要求に基づいてホストアプリケーションが何らかの処理(例: ファイル保存、データ送信)を行う場合、その処理はホストアプリケーションの権限管理下で安全に実行されます。UI側に直接的な権限を与えません。

E2Eコネクションの影響と残存リスク

  • 信頼しているホスト同士のE2Eコネクション: これは、UI定義データやイベントデータが通信経路において盗聴されたり改ざんされたりするリスクを大幅に低減します。送信元が確かに信頼するホストであることも保証されます。
  • 残存リスク:
    • コンテンツの無害性の非保証: E2Eコネクションは通信路の安全性を保証しますが、送信されるUI定義データそのものが「無害」であることまでは保証しません。信頼するホストがマルウェアに感染したり、バグによって意図せずリソースを過剰に消費するUI定義(例: 極端に深いネスト構造、大量の要素)を生成・送信する可能性は残ります。
    • レンダラーの脆弱性: 上記の対策を施しても、レンダラーの実装自体に未知の脆弱性が存在する可能性はゼロではありません。
    • ホストアプリケーションの脆弱性: ホストアプリケーションがUIからのメッセージを処理する際に脆弱性があれば、そこが攻撃経路となる可能性があります。

したがって、UIレンダラーは、たとえ信頼できるソースからのUI定義であっても、原理的には「信頼できない入力」として扱う設計思想が重要です。

まとめと展望

完全にRCEやコードインジェクションに対して安全なGUIシステムを構築するには、UI言語の設計段階から実行環境、ホストアプリケーションとの連携に至るまで、セキュリティを最優先に考慮した多層的なアプローチが必要です。

  • UI言語: 宣言的で非チューリング完全、スクリプト実行能力なし。
  • レンダラー: 堅牢なパーサー、厳格な入力検証、サンドボックス化、最小権限。
  • ホスト連携: 明確なAPI、ホスト側での最終検証と権限管理。

E2Eコネクションは重要な基盤ですが、それだけでは不十分です。自作のUIレンダラーとUI言語を持つことは、これらの原則を徹底的に適用できる大きなアドバンテージとなります。

「完全な安全」は極めて高い目標であり、100%の達成は現実的には困難かもしれませんが、これらの原則に忠実に従うことで、RCEやコードインジェクションのリスクを限りなく低減し、実用上非常に安全なGUIシステムを構築することは可能です。継続的な設計レビュー、コード監査、脆弱性テストも安全性を維持するためには不可欠です。

(返答終了理由: STOP)


ユーザー: チューリング完全を持たせてはいけない理由は何ですか?極論を言うとサイドチャネル攻撃的な類推ができてしまうせいですか?それとも振る舞いが壊れてしまう可能性があるからですか?正直なところ途中でパニックしたり描画が止まらないとかは許容可能なものだと捉えてます。なぜならRCEやコマンドインジェクションのような外部に影響を与えうるものではないので。


AI: UI言語にチューリング完全性を持たせてはいけない理由について、より深く掘り下げてご説明します。ご指摘の通り、UIの描画が停止したりパニックしたりすること自体は、RCEやコマンドインジェクションのような直接的な外部システムへの侵害とは異なります。しかし、チューリング完全性を持つことは、これらの深刻なセキュリティ問題を引き起こす「土壌」や「踏み台」を提供してしまう可能性が格段に高まるため、避けるべきとされています。

主な理由を以下に詳述します。

  1. 攻撃対象領域 (Attack Surface) の増大と未知の脆弱性の誘発:

    • チューリング完全な言語の複雑性: チューリング完全な言語を安全に実装し、実行環境を構築することは非常に複雑です。言語仕様、パーサー、インタープリター、メモリ管理など、あらゆる部分にバグや脆弱性が潜む可能性が増大します。
    • 意図しないコード実行経路の創出: たとえ開発者がOSコマンド実行のような直接的な危険な機能を公開していなくても、言語の計算能力そのものを悪用して、レンダラーやホストアプリケーションの内部の脆弱性(例えば、巧妙なデータ構造や計算順序によるバッファオーバーフロー、use-after-freeなど)を誘発し、結果的に任意のコード実行に繋がる可能性があります。
    • 例: 非常に複雑なUIロジックを記述できるということは、そのロジックの実行過程でレンダラー内部の状態を予期せぬものにし、メモリ破壊などを引き起こす巧妙な「プログラム」をUI定義として注入されるリスクがあるということです。
  2. 「外部への影響」の定義と間接的な攻撃:

    • 情報漏洩: チューリング完全な言語は、たとえファイルシステムへの直接アクセスがなくても、レンダラーが保持している情報(他のUIコンポーネントの状態、キャッシュされたデータ、場合によってはホストアプリから限定的に渡された情報など)を計算によって収集し、それを巧妙な方法で外部に送信するロジックを組むことが可能です。
      • 例: UIの描画パターンを微細に変化させて情報をエンコードし、外部の監視プロセス(例えば画面キャプチャ)で読み取る(これは極端な例ですが、原理的には可能です)。あるいは、ホストアプリのAPIを悪用して、許可されていないネットワークリクエストを生成するなど。
    • リソース枯渇 (DoS): 無限ループ、指数関数的なメモリ消費、計算量の多い処理などをUI言語で記述できてしまうと、レンダラーやホストアプリケーション、最悪の場合はシステム全体のリソースを枯渇させ、サービス停止を引き起こすことができます。これは「外部への影響」と言えます。ユーザーが許容する「描画停止」のレベルを超える深刻な影響があり得ます。
    • 暗号学的攻撃の補助: ホストアプリケーションが何らかの暗号処理を行っている場合、UI側で大量の計算を実行させることで、タイミング攻撃や電力解析攻撃(これはハードウェアに近いですが)のようなサイドチャネル攻撃を補助する計算を行わせる可能性があります。これはご指摘の「サイドチャネル攻撃的な類推」に近いですが、より能動的な関与です。
  3. サンドボックス化の限界とバイパスの可能性:

    • サンドボックスは重要な防御策ですが、万能ではありません。チューリング完全な言語の実行環境自体に脆弱性があれば、サンドボックスをバイパスしてホストシステムに影響を与える試みが可能になります。
    • 言語レベルで能力を制限することは、サンドボックスのさらに内側にある、より根源的な安全策です。
  4. 予測不可能性と検証の困難性:

    • チューリング完全な言語で書かれたUIの振る舞いは、静的に解析したり、その安全性を完全に検証したりすることが極めて困難になります。「何でもできてしまう」ため、あらゆる可能性を考慮して安全性を担保する必要があり、これは現実的ではありません。
    • 宣言的なUI言語は、その構造と振る舞いが限定されているため、安全性の検証が比較的容易です。
  5. 「描画が止まらない」という許容範囲について:

    • ユーザーが個人の利用で一時的なフリーズを許容するとしても、それが第三者によって意図的に引き起こされるDoS攻撃であれば問題です。また、UIのフリーズが、実際にはバックグラウンドで悪意のある計算(例: 暗号通貨マイニング、ボットネットの一部としての活動)が行われている兆候である可能性も否定できません。

なぜ「計算能力」そのものが問題なのか?

RCEやコマンドインジェクションは、「特定の危険な関数を実行する」という直接的な行為です。しかし、チューリング完全な言語は、「任意のアルゴリズムを実行できる能力」を提供します。この能力は、それ自体が直接的にOSコマンドを実行しなくても、

  • レンダラーやホストアプリの既存の機能を予期せぬ形で組み合わせたり、悪用したりするための「接着剤」や「制御ロジック」として機能する。
  • システムの内部状態を探索し、脆弱な箇所を見つけ出すための「プローブ」として機能する。
  • 脆弱性をトリガーするための複雑な前提条件を作り出すための「ステージング」として機能する。

このように、チューリング完全性は、攻撃者にとって非常に強力な「道具」を提供してしまうことになります。たとえその道具箱に「OSコマンド実行ハンマー」が最初から入っていなくても、他の道具を組み合わせて同様の結果を生み出したり、システムを破壊したりすることが可能になるのです。

結論として、

UI言語にチューリング完全性を持たせないのは、単に「振る舞いが壊れる」のを防ぐためだけではありません。それ以上に、意図しない計算能力が悪用され、間接的にRCEやコードインジェクション、あるいはそれと同等の深刻なセキュリティ侵害(情報漏洩、DoSなど)に繋がるリスクを根源的に断ち切るためです。 「できることを制限する」というのは、セキュリティにおける非常に基本的な原則であり、特にUIのように外部からの入力を解釈するコンポーネントにおいては、その原則を厳格に適用することが求められます。

(返答終了理由: STOP)


ユーザー: 良いですね。つまりすごく効率の悪いデータ構造としてui自体が機能する可能性があるのでそれを防ぐという話と何らかの漏れを発生する可能性を埋め込む余地が生まれるので避けたいということですね。


AI: はい、その通りです。ご指摘の2点は、チューリング完全性をUI言語から排除するべき重要な理由を的確に捉えています。

もう少し詳しく、ご指摘の点を深掘りすると以下のようになります。

  1. 「すごく効率の悪いデータ構造としてUI自体が機能する可能性があるのでそれを防ぐ」

    • これは、UIの構造や状態変化を巧妙に利用して、意図しない計算や情報処理を行わせる可能性を指しています。
    • 例えば、UI要素の表示/非表示、位置、色などを大量に組み合わせることで、それ自体をビット列やメモリセルに見立て、チューリング完全な言語によってそれらを操作し、一種の「計算機」をUI内部に構築してしまうようなイメージです。
    • このような使われ方は、UIレンダラーの設計者が想定していない負荷をかけ、パフォーマンスの著しい低下(実質的なDoS)を引き起こしたり、前述のようにレンダラーの脆弱性を誘発する可能性があります。
    • UIは本来「情報を表示し、ユーザーインタラクションを受け付ける」ためのものであり、汎用的な計算基盤として機能することは目的外であり、リスクを伴います。
  2. 「何らかの漏れ(情報漏洩や意図しない振る舞い)を発生する可能性を埋め込む余地が生まれるので避けたい」

    • これは、チューリング完全な言語の表現力と計算能力が、攻撃者にとって悪意のあるロジックをUI定義に潜ませるための「余地」や「自由度」を与えてしまうことを意味します。
    • 情報漏洩の例:
      • ユーザーが入力した機微な情報を、UIの計算ロジックを使って加工・エンコードし、一見無害に見える別のUI要素(例えば、画像のピクセルパターンや、エラーメッセージの特定の文字列など)に埋め込み、間接的に外部に送信する。
      • レンダラーやホストアプリが内部的に保持している(本来UIからはアクセスできないはずの)情報を、タイミング攻撃のような手法で推測し、漏洩させる。
    • 意図しない振る舞いの例:
      • ホストアプリケーションのAPIを、設計者の意図とは異なる順序や頻度で呼び出し、予期せぬ状態変化やリソース消費を引き起こす。
      • 他のUIコンポーネントの動作を妨害したり、誤った情報を表示させたりする。

補足:なぜ「非チューリング完全」でも十分なのか

UIに必要な動的な振る舞い(例:条件付きレンダリング、リストの繰り返し、簡単な状態変化)の多くは、チューリング完全でなくても実現可能です。

  • 宣言的なアプローチ: 「もしこのデータが真ならこの要素を表示する」「このリストの各アイテムに対してこのテンプレートを適用する」といった記述は、チューリング完全な計算能力を必要としません。
  • ホストアプリケーションとの連携: より複雑なロジックや副作用を伴う処理(例:データの永続化、ネットワーク通信)は、UI言語ではなく、信頼されたホストアプリケーション側が担当することで、UI言語のシンプルさと安全性を保つことができます。

UI言語をシンプルで宣言的なものに保つことは、セキュリティ上のメリットだけでなく、開発の容易さ、テストのしやすさ、パフォーマンスの予測可能性といった面でも利点があります。

ご認識の通り、チューリング完全性を避けることは、これらの潜在的なリスクを設計レベルで排除するための非常に効果的なアプローチです。

(返答終了理由: STOP)


ユーザー: 一番単純な仕組みとしてある種のテンプレート(ここでは静的なhtmlのサブセットのようなものを考えてください)に返ってきたデータ(ここではJSONをイメージしてください)を特定のオペレーターで走査し値を特定のフォーマッターで文字列に変換する(どちらも制限された関数のみを提供)することはこのuiレンダラーの最も単純な形式として機能しますか?


AI: はい、そのアプローチは、RCEやコードインジェクションに対して安全なUIレンダラーの非常に良い出発点であり、最も単純な形式として十分に機能します。 それは、これまで議論してきたセキュリティ原則の多くを自然に満たすことができるからです。

具体的に、ご提案の仕組みがどのように安全性を担保するのか、そしてなぜそれが良い出発点なのかを分解してみましょう。

提案された仕組みの構成要素と安全性

  1. テンプレート(静的なHTMLのサブセットのようなもの):

    • 役割: UIの構造とレイアウトを定義します。
    • 安全性:
      • 宣言的: 「どこに何を表示するか」を記述するものであり、手続き的なロジックを含みません。
      • 静的: 実行時に構造が動的に生成・変更されるのではなく、あらかじめ定義されています。(データバインディングによる表示内容の変更はありますが、構造そのものの変更は限定的)
      • サブセット: HTML全体ではなく、安全な要素と属性に限定することで、<iframe><script> のような潜在的に危険な要素を排除できます。
  2. データ(JSON):

    • 役割: UIに表示される動的な情報を提供します。
    • 安全性:
      • 純粋なデータ: JSONはデータ記述言語であり、実行可能なコードを含みません。
      • 構造化: データが明確な構造を持つため、パースやアクセスが比較的安全に行えます。
  3. 特定のオペレーター(制限された関数群)によるデータの走査:

    • 役割: JSONデータから必要な値を抽出し、テンプレートの特定の部分に結びつけます。
    • 安全性:
      • 非チューリング完全: 複雑な計算や無限ループ、再帰呼び出しのようなものは許可せず、データのフィールドアクセス、配列のイテレーション(限定的な回数や深さ)、単純な条件分岐(例: if value exists)などに限定します。
      • ホワイトリスト方式: 許可されたオペレーターのみが使用可能であり、それ以外の操作はできません。これにより、意図しないデータ操作や情報漏洩を防ぎます。
      • 例: Mustache.js や Handlebars.js (の安全なサブセット) のようなテンプレートエンジンのロジックに近いですが、それらよりもさらに機能を絞り込むイメージです。
  4. 特定のフォーマッター(制限された関数群)による文字列への変換:

    • 役割: 抽出された値を、表示に適した文字列に変換します(例: 日付フォーマット、数値の桁区切り、HTMLエスケープ)。
    • 安全性:
      • 出力エンコーディングの強制: 最も重要なのは、表示される全ての文字列に対して、HTMLエンティティエスケープ(例: <&lt; に変換)のようなサニタイズ処理をデフォルトで、あるいは強制的に適用することです。これにより、データとして渡された文字列がHTML構造を破壊したり、XSS(クロスサイトスクリプティング)のようなインジェクションを引き起こすのを防ぎます。
      • 限定的な機能: フォーマッターは文字列操作に特化し、ファイルアクセスやネットワークアクセスのような危険な機能は持ちません。

この仕組みが機能する理由とメリット

  • データとコードの厳格な分離: テンプレート(構造)とJSON(データ)が明確に分離されており、データがコードとして解釈される余地がありません。
  • 最小権限の原則: オペレーターとフォーマッターは、UI表示に必要な最小限の機能しか持ちません。
  • 予測可能性と検証の容易さ: UIの振る舞いがテンプレートとデータの組み合わせによって決まるため、比較的予測しやすく、安全性の検証も容易です。
  • 実装の容易さ: 複雑な言語処理系を実装する必要がないため、レンダラー自体の開発コストを抑えつつ、バグの混入リスクも低減できます。
  • 拡張性: 将来的にUIの表現力を高めたい場合でも、新しい安全なオペレーターやフォーマッターを慎重に追加していく形で拡張できます。

考慮すべき点

  • オペレーターとフォーマッターの設計: どのようなオペレーターやフォーマッターを許可するかの選定と設計は非常に重要です。少しでも汎用的な計算能力を持たせてしまうと、そこが抜け穴になる可能性があります。常に「本当にこの機能が必要か?」「悪用される可能性はないか?」を問い続ける必要があります。
  • エラーハンドリング: 不正なデータ形式や予期せぬ値が来た場合の安全なエラーハンドリングも重要です(例: エラーメッセージを表示する、デフォルト値を表示する、要素を非表示にするなど。クラッシュは避ける)。

結論

ご提案いただいた「静的なテンプレート + JSONデータ + 制限されたオペレーターとフォーマッター」というモデルは、RCEやコードインジェクションに対して非常に堅牢なUIレンダラーの基本形として極めて有効です。 これは、Web開発における安全なテンプレートエンジンのベストプラクティスを、より根源的なレベルで適用するアプローチと言えるでしょう。

このシンプルなモデルからスタートし、必要に応じて慎重に機能を追加していくことで、安全性を維持しながら表現力豊かなUIシステムを構築していくことが可能です。

(返答終了理由: STOP)

メタデータ

{
  "runSettings": {
    "temperature": 1,
    "model": "models/gemini-2.5-pro-preview-05-06",
    "topP": 0.95,
    "topK": 64,
    "maxOutputTokens": 65536,
    "safetySettings": [
      {
        "category": "HARM_CATEGORY_HARASSMENT",
        "threshold": "OFF"
      },
      {
        "category": "HARM_CATEGORY_HATE_SPEECH",
        "threshold": "OFF"
      },
      {
        "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
        "threshold": "OFF"
      },
      {
        "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
        "threshold": "OFF"
      }
    ],
    "responseMimeType": "text/plain",
    "enableCodeExecution": false,
    "enableSearchAsATool": false,
    "enableBrowseAsATool": false,
    "enableAutoFunctionResponse": false
  },
  "systemInstruction": {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment