安全な開発の流れ

レッスン 5-1

設計で決まる部分は、実装では取り返せません。

目安 60 分 トラック 5 設計と制度の 1 本目

読み終えたら脅威モデルを開発の流れのどこに入れるかを説明できる

この頁の流れ

  1. 1なぜ通るのか
  2. 2脆いコードと直したコード
  3. 3ログでの見え方と検知
  4. 4直し方と確かめ方
  5. 5関わる事例
  6. 6確認クイズ
  7. 7説明課題
  8. 8一次資料
  9. 9次へ

セキュリティ・バイ・デザイン (企画と設計の段から守りを組み込む考え方) を、開発の流れのどこに何を置くかとして扱います。要件、設計の見直し、出す前の判定に脅威モデルを入れる場所を決め、既定で公開になる作りと既定で閉じる作り、試験だけを見る出す前の判定と境目の変更を見る判定を、手元で比べます。

出典を確かめた日 2026年10月27日

なぜ通るのか

ある会社が、注文の書類を顧客に渡す機能を作ります。設計の打ち合わせでは「リンクを送るだけ」と決まり、認証の話は出ませんでした。実装は速く進み、試験もすべて通ります。出したあとで、リンクの中の番号を 1 つ変えると、別の人の書類が見えると分かります。直すには、リンクの作りから変え、出してしまったリンクを全部止めることになります。

この穴は、コードの書き間違いではなく、設計の段で「だれが見てよいか」を決めなかったことから来ています。試験は、決めた通りに動くかを確かめるので、決めていないことは確かめません。このレッスンでは、守りを決める場所を、開発の流れの前の方へ動かします。

セキュリティ・バイ・デザインとは

セキュリティ・バイ・デザインは、製品やシステムを作り終えてから守りを足すのではなく、企画と設計の段から守りを組み込む考え方です。IPA の「セキュリティ・バイ・デザイン導入指南書」は、脅威分析、セキュリティ要件、セキュリティアーキテクチャ、下流の工程のセキュア開発の順に章を立てています。

米国の CISA は、Secure by Design の 3 つの原則として、顧客のセキュリティの結果に作り手が責任を持つこと、徹底した透明性と説明責任、経営の上から率いることを挙げています。顧客が設定で守りを足すのではなく、出荷した時から安全な既定値にすることも求めています。

シフトレフトとの違い

シフトレフトは、試験や確かめを、開発の流れの左 (前の方) へ動かすことです。セキュリティ・バイ・デザインは、その中でも、守りの判断そのものを設計の段で行うことに重きを置きます。左へ動かした試験は「決めた通りか」を早く見つけ、設計の段の判断は「何を決めるか」を早く決めます。両方が要ります。

流れのどこに何を置くか

NIST の SSDF (SP 800-218) は、安全な開発の実践を、組織の準備 (PO)、ソフトウェアの保護 (PS)、よく守られたソフトウェアの生産 (PW)、脆弱性への対応 (RV) の 4 つに分けています。PW.1.1 は、脅威モデリングなどのリスクのモデル化でセキュリティのリスクを見積もること、PW.2.1 は、設計に関わらなかった人か、道具の中の自動の手順で、設計が要件とリスクに応えているかを見直すことを求めています。

段置く物脅威モデルとの関わり
要件守る物、だれが何をしてよいか、法令と契約の決まり守る物の一覧を作る
設計データの流れ図、信頼の境目、既定値脅威モデルを作り、対策を設計に書く
設計の見直し設計に関わらなかった人の目境目ごとに、6 つの型で漏れを探す
実装安全な既定値の部品、秘密の扱い対策が部品の形になっているか
試験権限の試験、入力の試験、依存の検査脅威ごとに 1 つ以上の試験
出す前の判定決めた基準での可否境目を変えた変更は、脅威モデルの更新を確かめる
運用と対応記録、検知、穴の届けの窓口起きたことを脅威モデルに戻す

脅威モデルは、設計の段で 1 回作って終わりではありません。信頼の境目をまたぐ変更 (認証、権限、外とのつなぎ、データの置き場) が入るたびに、更新が要ります。出す前の判定は、その更新を確かめる場所です。

脆いコードと直したコード

開発の流れの決まりを、小さなコードで比べます。Python に付いている物だけで動きます。

既定で公開か、既定で閉じるか

脆いコード 書き忘れると、だれでも見られる

Python

ROUTES = {}

def route(path, login=False):
    def deco(fn):
        ROUTES[path] = (fn, login)
        return fn
    return deco
直したコード 理由を書かない限り、ログインが要る

Python

ROUTES = {}

def route(path, public=None):
    if public is not None and not str(public).strip():
        raise ValueError("公開するなら理由を書く")
    def deco(fn):
        ROUTES[path] = (fn, public is None)
        return fn
    return deco

脆い方では、新しい道を足す人が login=True を書き忘れると、その道はだれでも見られます。忘れた時の結果が「開いている」なのが問題です。直した方は、何も書かなければログインが要り、公開したい時は public="理由" を書きます。公開の道は、理由ごと一覧にでき、見直しの対象になります。CISA の言う、出荷した時から安全な既定値の、最小の形です。

試験だけを見るか、境目の変更も見るか

脆いコード 試験が通れば出せる

Python

def can_release(pr):
    return pr["tests_passed"]
直したコード 出せない理由を並べる

Python

def blockers(pr):
    reasons = []
    if not pr["tests_passed"]:
        reasons.append("試験が通っていない")
    if pr["touches_boundary"] and not pr["threat_model_updated"]:
        reasons.append("境目を変えたのに脅威モデルが古い")
    if any(f["severity"] == "high" for f in pr["open_findings"]):
        reasons.append("重大な指摘が残っている")
    return reasons

脆い方は、決めた通りに動くかしか見ません。直した方は、認証や権限や外とのつなぎのように信頼の境目に当たるファイルを変えた変更 (touches_boundary) では、脅威モデルの更新を求め、重大な指摘が残っていれば止めます。空の一覧が返れば出せます。SSDF の PO.4.1 は、ソフトウェアのセキュリティの確かめの基準を決め、開発の流れの全体で追うことを求めています。

判定は、入力が正しい時だけ効きます。指摘の深刻度を誤って低く記録すれば、この判定は通ってしまいます。深刻度の記録は、記録した人とは別の人が確かめます。

ログでの見え方と検知

開発の流れの記録 (プルリクエスト、判定の結果、指摘の台帳) に、設計の段の抜けが映ります。次は、出す前の判定の記録の例です。

出す前の判定の記録

記録

PR 412 tests ok boundary yes threat_model no 止める 境目を変えたのに脅威モデルが古い
PR 413 tests ok boundary no 出せる
PR 414 tests ok boundary yes threat_model yes 出せる
PR 415 tests ok open high 1 (期限 05-08 超過) 止める 重大な指摘が残っている

守る側は、1 件ずつの可否だけでなく、流れ全体の偏りを見ます。

見る物何の抜けか
境目を変えた変更のうち、脅威モデルを更新した割合設計の段の判断が、変更に追いついていない
公開の道の数と、理由の書かれていない物既定で閉じる作りの例外が増えている
期限を過ぎた重大な指摘指摘が直す仕事に変わっていない
判定を手で飛ばした回数判定が、急ぐ理由で形だけになっている

直し方と、直ったことの確かめ方

自分のリポジトリの中だけで行います。

  1. 信頼の境目に当たるファイル (認証、権限、道の定義、外とのつなぎ、データの置き場) を一覧にする
  2. プルリクエストのひな形に「境目を変えたか」「脅威モデルを更新したか」の欄を足す
  3. 道を足す部品を、直した route の形にし、公開の道には理由を書かせる
  4. 出す前の判定に blockers を置き、境目の一覧に当たるファイルが変わったら touches_boundary が立つようにする
  5. 下の試験を足し、直す前のコードに戻すと試験が落ちることを確かめる
  6. 月に 1 回、公開の道の一覧と、期限を過ぎた指摘の一覧を見直す
既定で閉じることと、境目の判定を固める試験

Python

import pytest

def test_routes_require_login_by_default():
    ROUTES.clear()

    @route("/orders")
    def orders():
        return "注文"

    @route("/health", public="監視のため、中身を返さない")
    def health():
        return "ok"

    assert ROUTES["/orders"][1] is True
    assert ROUTES["/health"][1] is False

def test_public_needs_a_reason():
    with pytest.raises(ValueError):
        route("/export", public="")

def test_boundary_change_needs_threat_model():
    pr = {"tests_passed": True, "touches_boundary": True,
          "threat_model_updated": False, "open_findings": []}
    assert blockers(pr) == ["境目を変えたのに脅威モデルが古い"]

1 つ目の試験は、何も書かない道がログインを求めることを、2 つ目の試験は、空の理由での公開が断られることを確かめます。3 つ目の試験は、試験が通っていても、境目の変更に脅威モデルの更新が無ければ止まることを確かめます。

設計の見直しを 1 枚にまとめる

設計の見直しでは、設計に関わらなかった人が、次の欄を埋めます。

設計の見直しの例

記録

機能    注文の書類を顧客に渡す
守る物   書類 (氏名、住所、金額)
境目    顧客のブラウザと書類の置き場の間
だれが   書類の持ち主の顧客と、担当の社員だけ
既定値   リンクはログインが要る、期限は 7 日
脅威    番号の差し替えで他人の書類 (情報の漏えい)
対策と試験 持ち主の確かめを置き場の手前で行い、他人の番号で 403 の試験
見直した人 設計に関わらなかった 1 人

関わる事例

設計の段や、出す前の判定で止められたはずの例が並びます。First American では、文書を渡すアプリで、認証の無いリンクを送れる機能を足し、URL の中の連番を替えると無関係な取引の文書が見える欠陥が生まれました。自社の侵入テストで見つかったものの、社内のシステムに深刻度を低く誤って記録し、直す期限が延びて、期限までに直りませんでした。

CrowdStrike では、新しい検知の型で、センサーのコードが用意する入力の数 (20) と、型の定義が期待する数 (21) が食い違っていました。開発の時の試験でも、配る前に内容を確かめる仕組みでも見つからず、問題のある設定のファイルがそのまま配られて、Windows の端末が一斉に止まりました。設計の前提の食い違いを、試験も確かめも同じ前提で見ていた例です。

SolarWinds では、ソースコードの置き場ではなく、自動のビルドの環境の中で不正なコードが混ぜられ、正規の署名つきの更新として顧客に配られました。Log4Shell では、広く組み込まれた部品の穴が、どの製品に入っているかを誰も把握していなかったため、探すこと自体に時間がかかりました。開発の流れそのものと、使う部品の一覧も、守る物に入ります。

確認クイズ

1 問目

脅威モデルを、開発の流れのどこで扱うのが合っていますか。

答えだと思う選択肢を押すと、その場で正誤と理由が開きます。

2 問目

新しい道を足す時、ログインを求める印を付け忘れると、だれでも見られる作りになっています。何を直しますか。

答えだと思う選択肢を押すと、その場で正誤と理由が開きます。

説明課題

次のことを、自分の言葉で 3 行にまとめてください。書けたら、このレッスンは修了です。

  • 脅威モデルを、開発の流れのどこに入れ、どうやって古くならないようにするか
模範解答を見る

設計の段で、データの流れ図と信頼の境目から脅威モデルを作り、対策を設計に書き、設計に関わらなかった人に見直してもらう。認証、権限、外とのつなぎのように境目に当たるファイルを一覧にし、それが変わったプルリクエストでは脅威モデルの更新を求める。出す前の判定で、更新が無ければ止める。

一次資料

どれも 2026年10月27日に開いて、題と中身を確かめました。

次へ

次のレッスンは「供給網のリスク」です。自分のコードの外、頼っている部品とその作り手の側の守りを扱います。

次のレッスン 5-2 供給網のリスク

トラック 5 設計と制度の中で

学んだことを次につなげる

ゆめさくセキュリティは、攻撃の仕組みを知り、自分の PC の中で壊して直し、守る側の判断を身につけるための学びの場です。

ラボはすべて自分の PC の中 (127.0.0.1) で閉じます。自分が管理していない相手に試すことは扱いません。