# JSON, XML & Yaml Hacking & Issues {{#include ../banners/hacktricks-training.md}} ## Go JSON デコーダ Go JSON で以下の問題が検出されましたが、他の言語にも存在する可能性があります。これらの問題は[**このブログ投稿**](https://blog.trailofbits.com/2025/06/17/unexpected-security-footguns-in-gos-parsers/)で公開されました。 Go の JSON、XML、および YAML パーサーには、一貫性のない長い履歴と、**認証をバイパス**、**権限を昇格**、または**機密データを抽出**するために悪用される可能性のある不安全なデフォルトがあります。 ### (Un)Marshaling 予期しないデータ 目的は、攻撃者が機密フィールド(例:`IsAdmin`、`Password`)を読み書きできる構造体を悪用することです。 - 例の構造体: ```go type User struct { Username string `json:"username,omitempty"` Password string `json:"password,omitempty"` IsAdmin bool `json:"-"` } ``` - 一般的な脆弱性 1. **タグの欠如** (タグなし = フィールドはデフォルトでまだ解析される): ```go type User struct { Username string } ``` ペイロード: ```json {"Username": "admin"} ``` 2. **`-`の不適切な使用**: ```go type User struct { IsAdmin bool `json:"-,omitempty"` // ❌ wrong } ``` ペイロード: ```json {"-": true} ``` ✔️ フィールドを(アン)マーシャルされないようにブロックする正しい方法: ```go type User struct { IsAdmin bool `json:"-"` } ``` ### パーサーの差異 目的は、異なるパーサーが同じペイロードを異なって解釈する方法を利用して認証をバイパスすることです。例えば: - CVE-2017-12635: 重複キーによるApache CouchDBのバイパス - 2022: XMLパーサーの不整合によるZoomの0クリックRCE - GitLab 2025 SAMLのバイパスによるXMLの特異性 **1. 重複フィールド:** Goの`encoding/json`は**最後の**フィールドを取ります。 ```go json.Unmarshal([]byte(`{"action":"UserAction", "action":"AdminAction"}`), &req) fmt.Println(req.Action) // AdminAction ``` 他のパーサー(例:JavaのJackson)は**最初**を取るかもしれません。 **2. 大文字小文字の区別:** Goは大文字小文字を区別しません: ```go json.Unmarshal([]byte(`{"AcTiOn":"AdminAction"}`), &req) // matches `Action` field ``` ユニコードトリックも機能します: ```go json.Unmarshal([]byte(`{"aKtionſ": "bypass"}`), &req) ``` **3. クロスサービスの不一致:** 想像してみてください: - Goで書かれたプロキシ - Pythonで書かれたAuthZサービス 攻撃者が送信します: ```json { "action": "UserAction", "AcTiOn": "AdminAction" } ``` - Pythonは`UserAction`を認識し、それを許可します - Goは`AdminAction`を認識し、それを実行します ### データフォーマットの混乱 (ポリグロット) 目的は、フォーマット(JSON/XML/YAML)を混在させるシステムを悪用すること、またはパーサーエラーでオープンに失敗するシステムを悪用することです。例えば: - **CVE-2020-16250**: HashiCorp Vaultは、STSがXMLの代わりにJSONを返した後、XMLパーサーでJSONを解析しました。 攻撃者が制御するもの: - `Accept: application/json` ヘッダー - JSONボディの部分的な制御 GoのXMLパーサーはそれを**とにかく**解析し、注入されたアイデンティティを信頼しました。 - 作成されたペイロード: ```json { "action": "Action_1", "AcTiOn": "Action_2", "ignored": "Action_3" } ``` 結果: - **Go JSON** パーサー: `Action_2` (大文字小文字を区別しない + 最後が勝つ) - **YAML** パーサー: `Action_1` (大文字小文字を区別する) - **XML** パーサー: 文字列内の `"Action_3"` を解析 ### 🔐 緩和策 | リスク | 修正 | |-----------------------------|---------------------------------------| | 不明なフィールド | `decoder.DisallowUnknownFields()` | | 重複フィールド (JSON) | ❌ stdlib に修正なし | | 大文字小文字を区別しない一致 | ❌ stdlib に修正なし | | XML ゴミデータ | ❌ stdlib に修正なし | | YAML: 不明なキー | `yaml.KnownFields(true)` | {{#include ../banners/hacktricks-training.md}}