$30 off During Our Annual Pro Sale. View Details »

Go をセキュアに書き進めるための
「ガードレール」を整備しよう / Let's Build Security Guardrails For Your Go Programs!

Go をセキュアに書き進めるための
「ガードレール」を整備しよう / Let's Build Security Guardrails For Your Go Programs!

Go Conference 2021 Spring (B7-S) で使用した資料です。
- セッションの詳細: https://gocon.jp/sessions/session-b7-s/
- 発表者: https://twitter.com/lmt_swallow
- 資料に誤りがあれば是非こちらにご連絡ください

Takashi Yoneuchi

April 24, 2021
Tweet

More Decks by Takashi Yoneuchi

Other Decks in Programming

Transcript

  1. (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷ
    ʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    (P$POGFSFODF4QSJOH#4
    ถ಺وࢤ:0/&6$)* 5BLBTIJ
    גࣜձࣾ'MBUU4FDVSJUZ

    View Slide

  2. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    XIPBNJ
    4FFIUUQTTIJGUKTJOGP
    ถ಺وࢤ !MNU@TXBMMPX
    גࣜձࣾ'MBUU4FDVSJUZ
    ࠷ۙʰ8FCϒϥ΢βηΩϡϦςΟʱͱ͍͏ॻ੶Λग़͠·ͨ͠

    View Slide

  3. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ͋Εɺ͜Εͬͯ҆શ͚ͩͬʜʜ
    /* ... */
    x := 0
    blah(unsafe.Pointer(x))
    /* ... */

    View Slide

  4. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ͋Εɺ͜Εͬͯ҆શ͚ͩͬʜʜ
    /* ... */
    x := 0
    blah(unsafe.Pointer(x))
    /* ... */
    /* .... */
    config = &tls.Config{
    InsecureSkipVerify: true,
    };
    /* .... */

    View Slide

  5. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ͋Εɺ͜Εͬͯ҆શ͚ͩͬʜʜ
    /* ... */
    x := 0
    blah(unsafe.Pointer(x))
    /* ... */
    /* .... */
    config = &tls.Config{
    InsecureSkipVerify: true,
    };
    /* .... */
    https://golang.org/pkg/math/rand

    View Slide

  6. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ͋͋ɺ҆શͳίʔυΛॻ͘ͷ͸ർΕΔ
    ʜʜͦΕ͕ͨͱ͑(PͰ͋ͬͯ΋ʂ
    /* ... */
    x := 0
    blah(unsafe.Pointer(x))
    /* ... */
    /* .... */
    config = &tls.Config{
    InsecureSkipVerify: true,
    };
    /* .... */
    https://golang.org/pkg/math/rand

    View Slide

  7. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ૊৫ͷίʔυΛηΩϡΞʹอ্ͭͰͷ՝୊
    ஌͍ͬͯͯ΋஫ҙෆ଍Ͱ
    ੬ऑͳίʔυΛॻ͍ͯ͠·͏
    ՝୊
    ࣗ෼͸෼͔͍ͬͯΔ͕ɺ
    νʔϜʹ஌ݟ͕ਁಁ͠ͳ͍
    ՝୊
    ͦ΋ͦ΋ԿʹؾΛ͚ͭΔ΂͖
    ͔Λ୭΋஌Βͳ͍··
    ՝୊
    c := &http.Client{
    Transport: &http.Transport{
    TLSClientConfig: &tls.Config{
    InsecureSkipVerify: true,
    },
    },
    }

    View Slide

  8. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ૊৫ͷίʔυΛηΩϡΞʹอ্ͭͰͷ՝୊
    ஌͍ͬͯͯ΋஫ҙෆ଍Ͱ
    ੬ऑͳίʔυΛॻ͍ͯ͠·͏
    ՝୊
    ࣗ෼͸෼͔͍ͬͯΔ͕ɺ
    νʔϜʹ஌ݟ͕ਁಁ͠ͳ͍
    ՝୊
    ͦ΋ͦ΋ԿʹؾΛ͚ͭΔ΂͖
    ͔Λ୭΋஌Βͳ͍··
    ՝୊
    c := &http.Client{
    Transport: &http.Transport{
    TLSClientConfig: &tls.Config{
    InsecureSkipVerify: true,
    },
    },
    }

    View Slide

  9. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ૊৫ͷίʔυΛηΩϡΞʹอ্ͭͰͷ՝୊
    ஌͍ͬͯͯ΋஫ҙෆ଍Ͱ
    ੬ऑͳίʔυΛॻ͍ͯ͠·͏
    ՝୊
    ࣗ෼͸෼͔͍ͬͯΔ͕ɺ
    νʔϜʹ஌ݟ͕ਁಁ͠ͳ͍
    ՝୊
    ͦ΋ͦ΋ԿʹؾΛ͚ͭΔ΂͖
    ͔Λ୭΋஌Βͳ͍··
    ՝୊
    c := &http.Client{
    Transport: &http.Transport{
    TLSClientConfig: &tls.Config{
    InsecureSkipVerify: true,
    },
    },
    }

    View Slide

  10. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ͦ΋ͦ΋ԿʹؾΛ͚ͭΔ΂͖͔Λ୭΋஌Βͳ͍··
    ࣗ෼͸෼͔͍ͬͯΔ͕ɺνʔϜʹ஌ݟ͕ਁಁ͠ͳ͍
    ஌͍ͬͯͯ΋஫ҙෆ଍Ͱ੬ऑͳίʔυΛॻ͍ͯ͠·͏
    ΄͍͠ͷ͸ʜ
    ՝୊
    ஌͍ͬͯͯ΋஫ҙෆ଍Ͱ
    ੬ऑͳίʔυΛॻ͍ͯ͠·͏
    ՝୊
    ࣗ෼͸෼͔͍ͬͯΔ͕ɺ
    νʔϜʹ஌ݟ͕ਁಁ͠ͳ͍
    ՝୊
    ͦ΋ͦ΋ԿʹؾΛ͚ͭΔ΂͖͔Λ୭΋஌Βͳ͍··
    ՝୊
    c := &http.Client{
    Transport:
    &http.Transport{
    TLSClientConfig:
    &tls.Config{
    InsecureSkipVerify:
    true,
    },
    },
    }

    View Slide

  11. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ͦ΋ͦ΋ԿʹؾΛ͚ͭΔ΂͖͔Λ୭΋஌Βͳ͍··
    ࣗ෼͸෼͔͍ͬͯΔ͕ɺνʔϜʹ஌ݟ͕ਁಁ͠ͳ͍
    ஌͍ͬͯͯ΋஫ҙෆ଍Ͱ੬ऑͳίʔυΛॻ͍ͯ͠·͏
    ΄͍͠ͷ͸ʜΨʔυϨʔϧ🚧
    ՝୊
    ҎԼΛຬͨ͢Α͏ͳʮΨʔυϨʔϧʯ͕΄͍͠ʂ
    ✔ Α͋͘ΔϛεΛେ·͔ʹरͬͯ͘ΕΔ
    ✔ Ұਓͷ஌ݟΛνʔϜʹεέʔϧͤ͞ΒΕΔ
    ✔ ؾΛ͚ͭଓ͚ͳͯ͘΋ɺ໰୊Λػց͕ڭ͑ͯ͘ΕΔ
    ཧ૝
    ஌͍ͬͯͯ΋஫ҙෆ଍Ͱ
    ੬ऑͳίʔυΛॻ͍ͯ͠·͏
    ՝୊
    ࣗ෼͸෼͔͍ͬͯΔ͕ɺ
    νʔϜʹ஌ݟ͕ਁಁ͠ͳ͍
    ՝୊
    ͦ΋ͦ΋ԿʹؾΛ͚ͭΔ΂͖͔Λ୭΋஌Βͳ͍··
    ՝୊
    c := &http.Client{
    Transport:
    &http.Transport{
    TLSClientConfig:
    &tls.Config{
    InsecureSkipVerify:
    true,
    },
    },
    }

    View Slide

  12. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ΨʔυϨʔϧΛߏ੒͢ΔͨΊͷ
    ͭͷΞΫγϣϯ
    ஌͍ͬͯͯ΋஫ҙෆ଍Ͱ
    ੬ऑͳίʔυΛॻ͍ͯ͠·͏
    ࣗ෼͸෼͔͍ͬͯΔ͕ɺ
    νʔϜʹ஌ݟ͕ਁಁ͠ͳ͍
    ͦ΋ͦ΋ԿʹؾΛ͚ͭΔ΂͖
    ͔Λ୭΋஌Βͳ͍··
    ՝୊
    ·ͣ͸HPTFDͰΑ͋͘Δ
    ϛεΛݕग़Ͱ͖ΔΑ͏ʹ͢Δ
    HPSVMFHVBSE౳Λ׆༻ͯ͠
    ஌ݟΛίʔυͱͯ͠஝ੵ͍ͯ͘͠
    $*ʹHPTFD౳Λ഑ஔ͢Δ
    ॳظ͸SFWJFXEPHͷซ༻΋(PPE
    ΞΫγϣϯ

    View Slide

  13. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ‣ యܕతͳ҆શͰͳ͍(PίʔυύλʔϯΛݕग़ͯ͘͠ΕΔπʔϧ
    ‣ HPMBOHDJMJOUܦ༝Ͱར༻Մೳ
    ‣ ,VCFSOFUFT΍$BEEZ౳ͷஶ໊ͳ(PϓϩδΣΫτͰ΋ར༻͞Ε͍ͯΔ
    HPTFD
    IUUQTHJUIVCDPNTFDVSFHPHPTFD
    $ gosec ./main.go
    [/app/main.go:6] - G404 (CWE-338): Use of weak random number generator
    (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH)
    5: func main() {
    > 6: sample := rand.Int()
    7:

    View Slide

  14. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ҆શͰͳ͍(PίʔυͷయܕྫΛݕग़Մೳ
    /* ... */
    x := 0
    blah(unsafe.Pointer(x))
    /* ... */
    /* .... */
    config = &tls.Config{
    InsecureSkipVerify: true,
    };
    /* .... */
    (
    (
    HPTFD
    https://golang.org/pkg/math/rand
    (

    View Slide

  15. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ‣ HPܥύοέʔδ੡
    ‣ HP͸(Pඪ४ͷ੩తղੳ༻ͷύοέʔδ܈
    ‣ HPTFDͰ͸ओʹHPBTUʢߏจ໦पΓʣͱHPUZQFTʢܕपΓʣ͕ར༻͞Ε͍ͯΔ
    ‣ ֤ݕग़ϧʔϧ͸HPͱHPTFDʹΑΔHPͷUIJOXSBQQFSͰॻ͔ΕΔ
    HPTFDͷ͘͠Έ
    if ident, ok := n.Key.(*ast.Ident); ok {
    switch ident.Name {
    case "InsecureSkipVerify":
    if node, ok := n.Value.(*ast.Ident); ok {
    if node.Name != "false" {
    return gosec.NewIssue(c, n, t.ID(),
    "TLS InsecureSkipVerify set true.",
    gosec.High, gosec.High)
    }
    } // ....
    https://github.com/securego/gosec/blob/27a5ffb5c8f6dd3b6dea3b8e6019a2b3d43bf0f9/rules/tls.go#L64-L72

    View Slide

  16. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ՝୊૊৫ݻ༗ͷϧʔϧ࡞੒ͰࠔΔ
    func applyUnsafeOpToDir(path string) error {
    /* ... */
    }
    /* ... */
    s := scanner.Text()
    applyUnsafeOpToDir("/etc")
    applyUnsafeOpToDir("/etc"+ "/gogogo")
    applyUnsafeOpToDir(s)
    ͦͦ͜͜ةͳ͍ؔ਺
    ‣ QSJWBUFͳύοέʔδʹؔ͢ΔηΩϡϦςΟϧʔϧΛHPTFDʹ௥Ճ͢Δͷ͸ࠔ೉
    ‣ 044ͳͷͰ૊৫ʹݻ༗ͷϧʔϧΛ࡞ͬͯ΋DPOUSJCVUFͰ͖ͳ͍
    ‣ ҰԠHPTFDΛGPSLͯ͠ϝϯςφϯε͢Δͱ͍͏ख͸͋Δ͕ɺͭΒ͍
    ‣ ࿑ྗ͸࠷খԽͭͭࣗ͠࡞-JOUFSΛ༻ҙͰ͖ͨΒخ͍͕͠ʜʜ
    ྫҾ਺͕ίϯύΠϧ
    ࣌ఆ਺Ͱͳ͍Մೳੑ͕
    ͋Δ৔߹ʹܯࠂ͍ͨ͠

    View Slide

  17. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ‣ (Pίʔυ޲͚ͷಠࣗ੩తղੳϧʔϧͷ࡞੒Λิॿ͢Δ-JOUFS
    ‣ ૊৫ಠࣗͷϧʔϧΛڧྗͳύλʔϯϚονϟʢETMύοέʔδʣΛ༻͍ͯهड़Ͱ͖Δ
    ‣ HPBOBMZTJT HPHSFQϕʔεͰ࡞੒͞Ε͍ͯΔ
    HPSVMFHVBSE
    IUUQTHJUIVCDPNRVBTJMZUFHPSVMFHVBSE
    m.Match(`copy($b, []byte($s))`).
    Where(m["s"].Type.Is(`string`)).
    Suggest(`copy($b, $s)`)
    sample := "test"
    copy(buf, []byte(sample))
    ղੳϧʔϧͷྫ
    ݕग़͍ͨ͠அยͷྫ

    View Slide

  18. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    m.Match(`applyUnsafeOpToDir($x)`).
    Where(!m["x"].Const).
    Report(`$x should be a compile-time constant value`)
    func applyUnsafeOpToDir(path string) error { /* ... */ }
    /* ... */
    s := scanner.Text()
    applyUnsafeOpToDir("/etc")
    applyUnsafeOpToDir("/etc"+ "/gogogo")
    applyUnsafeOpToDir(s)
    /app/main.go:39:2: permitOnlyConstant: s should be a compile-time constant
    value (rules.go:14)
    ղੳର৅ͷίʔυྫ
    ղੳϧʔϧͷྫ
    ղੳ݁Ռͷྫ
    ࠷ऴߦͷΑ͏ͳ
    ݺͼग़͠Λݕग़͍ͨ͠ʂ

    View Slide

  19. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    m.Match(`applyUnsafeOpToDir($x)`).
    Where(!m["x"].Const).
    Report(`$x should be a compile-time constant value`)
    func applyUnsafeOpToDir(path string) error { /* ... */ }
    /* ... */
    s := scanner.Text()
    applyUnsafeOpToDir("/etc")
    applyUnsafeOpToDir("/etc"+ "/gogogo")
    applyUnsafeOpToDir(s)
    /app/main.go:39:2: permitOnlyConstant: s should be a compile-time constant
    value (rules.go:14)
    ղੳର৅ͷίʔυྫ
    ղੳϧʔϧͷྫ
    ղੳ݁Ռͷྫ

    View Slide

  20. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    m.Match(`applyUnsafeOpToDir($x)`).
    Where(!m["x"].Const).
    Report(`$x should be a compile-time constant value`)
    func applyUnsafeOpToDir(path string) error { /* ... */ }
    /* ... */
    s := scanner.Text()
    applyUnsafeOpToDir("/etc")
    applyUnsafeOpToDir("/etc"+ "/gogogo")
    applyUnsafeOpToDir(s)
    /app/main.go:39:2: permitOnlyConstant: s should be a compile-time constant
    value (rules.go:14)
    ղੳର৅ͷίʔυྫ
    ղੳϧʔϧͷྫ
    ղੳ݁Ռͷྫ
    ^
    \

    View Slide

  21. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    (PʹಛԽ͍ͯ͠Δ͔Βͦ͜ͷڧΈ΋
    https://go-ruleguard.github.io/by-example/
    m.Match(`fmt.Sprint($x)`).
    Where(m["x"].Type.
    Implements(`fmt.Stringer`)).
    Suggest(`$x.String()`)
    m.Match(`$x<$a && $x>$b`).
    Where(m["a"].Value.Int()
    <= m["b"].Value.Int()).
    Report("always false")
    ‣ HPSVMFHVBSE͸(PʹಛԽͯ͠࡞ΒΕ͍ͯΔ
    ‣ ͦͷͨΊྨࣅπʔϧͱൺ΂Δͱศརɾߴػೳ
    ‣ ίϯύΠϧ࣌ఆ਺ͷऔΓѻ͍ɺܕपΓͷऔΓѻ͍ɺʜ
    ܕ৘ใΛ༻͍ͨ
    ϧʔϧ
    ίϯύΠϧ࣌ఆ਺Λ
    ༻͍ͨϧʔϧ

    View Slide

  22. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ܧଓతʹվળ͍ͯͨ͘͠Ίʹ
    ͜ͷखͷπʔϧͷಋೖ͸ॳظোน͕ߴ͍͕ʜʜ
    $ curl -sfL https://raw.githubusercontent.com/securego/gosec/
    master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.7.0
    $ gosec ./...
    ʮࢼ͠ʹ࢖ͬͯΈΑ͏ʂʯ

    View Slide

  23. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ܧଓతʹվળ͍ͯͨ͘͠Ίʹ
    ͜ͷखͷπʔϧͷಋೖ͸ॳظোน͕ߴ͍͕ʜʜ
    $ curl -sfL https://raw.githubusercontent.com/securego/gosec/
    master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.7.0
    $ gosec ./...
    /* ... */
    Summary:
    Files: 77
    Lines: 4034
    Nosec: 0
    Issues: 543
    $
    ʮ΋ͷౖ͍͢͝ΒΕͯΔͳɺಋೖ͸·ͨࠓ౓ߟ͑Δ͔ʜʯ

    View Slide

  24. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ܧଓతʹվળ͍ͯͨ͘͠Ίʹ
    ͜ͷखͷπʔϧͷಋೖ͸ॳظোน͕ߴ͍͕ʜʜ
    $ curl -sfL https://raw.githubusercontent.com/securego/gosec/
    master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.7.0
    $ gosec ./main.go
    /* ... */
    Summary:
    Files: 77
    Lines: 4034
    Nosec: 0
    Issues: 543
    $
    ʮ΋ͷౖ͍͢͝ΒΕͯΔͳɺಋೖ͸·ͨࠓ౓ߟ͑Δ͔ʜʯ

    View Slide

  25. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ‣ ֤छ-JOUFSπʔϧͷग़ྗΛίϝϯτͱͯ͠౤ߘͯ͘͠ΕΔ(P੡πʔϧ
    ‣ (JU)VC౳Ͱͷࠩ෼ϨϏϡʔ࣌ʹɺࠩ෼෦෼ͷΈͷ-JOU݁ՌΛڭ͑ͯ͘ΕΔ
    ‣ πʔϧͷ'BMTF1PTJUJWF͕໨ཱͭ৔߹Ͱ΋ɺద౓ʹ໨ʹͭ͘ͱ͜ΖͰ஫ҙשىͰ͖Δ
    ‣ ίʔυશମʹରͯ͠େྔͷΞϥʔτ͕ग़Δ؀ڥͰ΋ɺஈ֊తʹվળΛ࢝ΊΒΕΔ
    SFWJFXEPH🐾
    IUUQTHJUIVCDPNSFWJFXEPHSFWJFXEPH
    ͜ͷ෦෼ͷݕࠪ݁ՌΛ
    ίϝϯτͱͯ͠౤ߘ
    ͜ͷ෦෼ͷݕࠪ݁Ռ͸
    Ұ୴ࣺͯΔ

    View Slide

  26. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    &YBNQMFHPTFDSFWJFXEPH🐾
    https://github.com/security-aware-repo-examples/gosec/pull/1
    ࠩ෼ʹର͢Δࢦఠ͕ίϝϯτͰ

    View Slide

  27. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ,FZ5BLFBXBZT
    ஌͍ͬͯͯ΋஫ҙෆ଍Ͱ
    ੬ऑͳίʔυΛॻ͍ͯ͠·͏
    ՝୊
    ࣗ෼͸෼͔͍ͬͯΔ͕ɺ
    νʔϜʹ஌ݟ͕ਁಁ͠ͳ͍
    ՝୊
    ͦ΋ͦ΋ԿʹؾΛ͚ͭΔ΂͖
    ͔Λ୭΋஌Βͳ͍··
    ՝୊ ·ͣ͸HPTFD͔Β࢝ΊΑ͏
    HPSVMFHVBSE౳Λ׆༻Ͱ͖Δ
    $*ʹHPTFD౳Λ഑ஔͰ͖Δ
    ॳظ͸SFWJFXEPHͷซ༻΋(PPE
    &YBNQMFTBSFBWBJMBCMFBU
    IUUQTHJUIVCDPNTFDVSJUZBXBSFSFQPFYBNQMFT

    View Slide

  28. ΨʔυϨʔϧΛ੔උͯ͠ɺ
    ҆৺ɾ҆શͳ(PϥΠϑΛૹΓ·͠ΐ͏ʂ

    View Slide

  29. ˜TIJGUKTJOGP
    (PΛηΩϡΞʹॻ͖ਐΊΔͨΊͷʮΨʔυϨʔϧʯΛ੔උ͠Α͏
    ‣ େྔͷ(PQIFS͘Μͨͪ
    ‣ .BSJB-FUUBGSFFHPQIFSTQBDL
    ‣ IUUQTHJUIVCDPN.BSJB-FUUBGSFFHPQIFSTQBDL
    ‣ ΨʔυϨʔϧͷΠϥετ
    ‣ ͍Β͢ͱ΍
    ‣ IUUQTXXXJSBTVUPZBDPNCMPHQPTU@IUNM
    "QQFOEJYը૾ͷग़ࣗ

    View Slide