HeaderLogo
← Works一覧に戻る

Java講師

Java講師

概要

今案件は、大手IT企業の新人研修でJavaのサブ講師を担当しました。 研修の内容としては、Javaの基礎構文の学習、SpringBootフレームワークの学習、SQLの基礎構文、PostgreSQLの学習、Gitを使用したECサイトのチーム開発を行いました。 授業形式でつまづいた箇所の補修や、都度都度の質問に対しての応答、生徒の理解力の分析評価、セキュアコーディングの範囲を主に担当しました。

使用技術

javaGithubeclipcePostgreSQLSpringBootFramework

詳細

研修の背景とサブ講師の役割

今案件はただのプログラミングスクールではなく「大手IT企業の新人研修」という、求められる基準や密度が高い環境でした。

受講生の数は約40名でかなりの大人数を相手にプログラミングやITの基礎知識を浸透させる必要があるため、各生徒が足並みを揃えるのを目的とし業務に当たりました。

全貌としては、知識の詰め込みだけでなくクイズ形式、記述形式を混ぜたオリジナルのWeb教材を活用と市販の参考書を併用しての学習で進めました。

約2ヶ月間でJavaの基礎からSpring Boot、SQL、Gitを使ったチーム開発(ECサイト構築)まで、実戦レベルへ引き上げるハイペースなカリキュラムで迅速な状況の把握が必要となりました。

在籍する受講生は8割が未経験文系であり、コンピューターの基礎概念やアルゴリズムに対しての知見を有していないため、理解度のグラデーションが存在してしまうことが問題点でした。

特にチーム開発やフレームワーク(Spring Boot)に入ると、エラーやGitのコンフリクトで「手が止まる受講生」が多発し、全体の進行がブレてしまうことも想定されます。

そこで、個々のつまずきをその場で解消し、全員の理解度を底上げしてチーム開発を完遂させるための “伴走者”として私がアサインされた、というのが役割の背景です。

私も受講生と同じように文系卒で、新卒研修をした経験があるため、受講生と同じ立場にたって伴走できると考えました。

講義の上での問題点と工夫

全体をとおしての問題点は、メイン講師のコードを模写している際、少しでも変数名を間違えてしまうと(大文字と小文字などのタイポ)それを修正するのに必死で複雑な概念を聞き逃してしまうことにありました。一度そうなってしまうと、次の行からはただの呪文のようになってしまうため、その場、あるいはその後でリカバリーする必要がありました。

人間である以上打ち間違えは必ずあるものだし、タイピングに慣れていない受講生もいるのでそうなってしまった場合は講義の間の「実装時間」で私がリカバリーするように努めました。

今回の研修全てを通して、工夫したポイントや意識したことは以下の通りです。

言葉だけで伝えない

私が初学者だった時、意外と大切なのがデータの動きや概念がイメージできるかということでした。

例えば、「コンストラクタでメンバ変数に初期値を入力・・・」のように言葉で話してもなかなか頭に入らないと考え、私はIpadを持参、図や矢印を用いながら視覚的にやっていることを説明するようにしました。

エラーの読み方の説明

配列の要素の数とIndexの説明

このように基礎的なIndexなどのわかりにくい点は絵を用いながら解説しました。

調べ方を教える

答えを教えることは簡単なので、私は努めて「わからない問題をどうやって解決するか」の方法を教えることも意識しました。

現場にでると自分が知っていることばかりではなく、知らないフレームワークやツール、独自のルールなどをしらべてキャッチアップする必要があります。

昨今では生成AIも発展しているので、いつもどのようにプロンプトを入力しているのか、どうやって調べているのかという技術を伝えることを考えていました。

いくらAIが発達していると言っても、「ページ遷移したらエラーが起きた」と入力しても解決につながるヒントを得るのは難しいです。

解決までの道のりを提示させるには「レンジを絞って質問する」という方針でお伝えしました。

例えば、エラーが出た際エラー文と共にディレクトリの構造を一緒に送ったり、コードの詳細をおくったりと言った具合にAIに解決のための材料をこちらも提供しなければなりません。またデバッグだけでなく、生成させる際にも「FormSectionのHTMLをBootStrapを使用して青を基調としたカラーで作って」など使用しているライブラリーや箇所を指定することを意識しました。

実際には研修ではMybatisを使用して、MapperでのSQLはxmlで指定しているので以下のようなプロンプトで期待したヒントを得ることができました。

伴走する

複雑な概念や特定の挙動について質問された時わからないときは無理に知ったかぶりをするのではなく、「わからない」と言うスタンスで臨みました。講師が絶対的な存在であると認識してほしくなかったからです。もちろん、わからないまま放置するようなことはせず、むしろわからないところはわからないと伝えて一緒になってコーディングしたり、調べたりするほうが受講者との距離が近くなると思いました。

その結果、調べるまでの過程や、答えまでたどり着くプロセスを体験することができるし、最も大切なのは受講者が臆せずに「講師のこの説明、実は全然わからなかったです」という言葉を引き出して、よりわかりやすく伝えるためのコミュニケーションになると考えました。

セキュリティ研修

メイン講師と相談の上、私のセキュリティスキルを活かし、攻撃者の視点を体験できる実践的なセキュリティ研修を実装しました。

よくある「怪しいメールは開かない」「パスワードは定期的に変更する」といった、ユーザー向けの一般的なセキュリティ啓修ではありません。今回対象としたのは「開発者(または IT 従事者)」です。

受講生に必要なのは、「なぜ脆弱なコードを書いてはいけないのか」を、身をもって理解することだと考えました。そのため、ただの座学ではなく、攻撃者が実際にシステムを侵食していく一連の流れ(サイバーキルチェーン)を目の前で実演し、体験してもらう形にこだわりました。

今回は、Webアプリケーションのバックエンド・フロントエンド両面に潜む代表的な脅威と、認証の要となるパスワード管理をピックアップしました。

XSS(クロスサイトスクリプティング)

XSSでよくある教科書の例では掲示板や入力フォームに

<script>alert("XSS")</script>

を入力してポップアップを出して終わりです。しかしこれでは本当の脅威がよくわかりません。

なのでローカルネットワークで以下のような掲示板を用意して実演しました。

実装パートでは、Python(Flask)で作成したあえて脆弱性(XSS)を残したアプリケーションを使用しました。

実際にクッキーを盗む


デモでは私が攻撃者役となり、その脆弱性を突いて巧妙な「フィッシング用の偽フォーム」を動的に生成。受講生のメールアドレスやパスワードといった機密情報が、いとも簡単に攻撃者の元へと奪取されていくプロセスを実演しました。


重要なのは、知識の暗記ではなく「攻撃者の目的(インセンティブ)と具体的な手法(エクスプロイト)」の構造を体感することです。守るべき対象(システム)を裏側から見つめ直すこのアプローチにより、日々の設計・開発業務において「どこに、なぜバリデーションやサニタイズが必要なのか」を自発的に考え、警戒できるエンジニアマインドを醸成できたと考えています。

SQLI

SQLインジェクションのセクションでは、受講生自身が攻撃者側の思考をトレースする「ハンズオン形式」を採用しました。検証環境として、Java(Spring Boot)で構築したローカル用のログインフォームおよび社員検索システムを用意し、以下のステップで進行しました。

  1. 構造の推測
    ログインフォームの挙動から、バックエンドでどのようなSQL文(認証クエリ)が組み立てられているかを推測。
  2. 攻撃コードの組み立て
    推測したSQL構造を破綻させ、認証をバイパスするためのコード(' OR '1'='1 など)を受講生自身に思考・検証させる。
  3. 認証バイパスの成功体験
    実際にフォームへ入力し、ID・パスワードを知らなくてもログインが成立することを確認。
  4. データの不正窃取(エクスプロイトの拡張)
    ログイン後の「社員検索機能」を対象に、UNION句などを用いたSQLIを実行させ、本来閲覧権限のないデータベースの内部情報を引き出す(情報漏洩)までの一連の流れを体験。

【教育的効果と狙い】
単に「脆弱性の対策方法」を座学で学ぶだけでは、実装時の危機感に繋がりづらいという課題があります。
受講生自身が攻撃者となって文字列を注入し、DBの中身が露出するリスクを直接体験することで、データ入力値に対するサニタイズ処理の重要性や、プレースホルダ(バインド変数)を用いたセキュアコーディングの必要性を深く認識させる狙いがありました。また、万が一脆弱性があった場合のリスクを最小限に抑えるため、DBの接続権限管理に対する意識向上も促しました。

パスワードクラック

前段のSQLインジェクションによって「ユーザー名」と「ハッシュ化されたパスワード」が漏洩した、というタイムラインを引き継ぎ、ハッカーがそのデータをどのように解析・悪用するのかを実演・検証しました。パスワードの強固性と、バックエンド側での安全な暗号化実装のあり方を理解させることを目的としました。

【実習・実演の流れ】

  1. ハッシュ解析ツールの実演(Hashcatの利用)
    オープンソースのパスワード解析ツールである「Hashcat」を使用し、漏洩したハッシュ値の解読プロセスを実演。

  2. 辞書攻撃・レインボーテーブル攻撃の疑似体験
    事前に用意した「氏名+誕生日」などの単純なパターンを含む辞書データや、ハッシュ値の逆引きテーブル(レインボーテーブル)を想定した手法を用いて、受講生がローカル環境に登録したパスワードの解析を試行。

  3. 脆弱なパスワードの即時突破を体感
    予測しやすい文字列や短いパスワードを設定していた受講生のハッシュ値が、数秒足らずで元の平文(プレーンテキスト)に解読されてしまう現実を体験。

【教育的効果と狙い】
この演習には、大きく分けて2つの狙いがあります。

  • エンドユーザー(開発者自身)の意識改革
    システムがハッシュ化して保管していても、パスワード自体が脆弱であれば現代の計算機能力の前には数秒で突破されてしまうため、適切な複雑性や長さ(パスワードポリシー)の強制が不可欠であることを実感させる。

  • 独自実装(車輪の再発明)の危険性とフレームワークの信頼性向上
    セキュリティの専門知識がない状態で、独自にソルト(Salt)の付与やストレッチングのロジックをJavaで実装することは、実装ミスのリスク(脆弱性の作り込み)が非常に高いことを解説。自作するのではなく、Spring Boot(Spring Security)などが提供する、業界標準で検証済みの暗号化ライブラリ(BCryptなど)を正しく組み込んで利用する重要性を担保させる。

Bcryptを使用したコード

WebShell

【概要とアプローチ】
一連の攻撃プロセスの最終段階(目的の実行)として、Webアプリケーションの脆弱性を突き、サーバー上に「WebShell」を設置・実行するデモを行いました。これにより、ネットワーク外部の攻撃者がサーバーマシンのOSコマンドを直接操作し、内部情報を完全に掌握・窃取する脅威の全容を実演しました。
【実演の流れ】

  1. 不正ファイルのアップロード(足がかりの構築)
    アプリケーションに存在するファイルアップロード機能(バリデーションの不備)を悪用し、画像ファイルなどを装った悪意のあるスクリプトファイル(PHPやJava/JSP等で記述されたWebShell)をサーバーにアップロード。
  2. WebShellの起動とコマンド実行
    ブラウザ経由でアップロードしたファイルにアクセスし、サーバーのバックエンドで任意のOSコマンド(whoamilscat など)を実行できる環境(バックドア)を確立。
  3. サーバー内操作と情報の抜き取り
    確立したWebShellを通じてサーバー内部のディレクトリを探索し、機密ファイルや環境変数、設定ファイル(DBの接続クレデンシャル等)を特定。最終的に、それらのデータを外部へ不正にエクスポート(情報窃取)する一連のプロセスを実演。

MacからRDPを使用して会社のWindowsに侵入したデモ。

【教育的効果と狙い】
この実演の狙いは、Webアプリケーションの単純なバグ(入力値やファイル検証の不備)が、最終的に「サーバーマシンそのものの権限を奪われる」という致命的なセキュリティインシデントに直結することを受講生に深く認識させることにあります。
単にデータの改ざんや閲覧に留まらず、インフラ層まで巻き込んだシステム全体の崩壊を目の当たりにすることで、以下の実務的な防衛意識を向上させる効果を狙いました。

  • アップロードされるファイルの拡張子、MIMEタイプ、ファイル名の厳格なバリデーションとサニタイズ。
  • アップロードディレクトリに対する実行権限(エグゼキューション権限)の剥奪。
  • 万が一ファイルが配置された場合でも、最小権限原則(Least Privilege)に基づき、Webアプリケーションプロセスの実行ユーザー権限を最小限に絞っておくことの重要性。

チーム演習

研修の総仕上げとして、受講生約40名を複数の班に分けた「ECサイト構築のチーム演習」を実施し、その成果を総合評価の対象としました。このフェーズでは、単に答えを教えるのではなく、受講生が自発的に課題を解決できるよう「ヒントの出し方」をコントロールする伴走型のサポートを徹底しました。

フロントエンド知見を活かしたオリジナル機能の提案・実装支援

各チームが独自性を出すために「オリジナル機能の実装」を課しました。受講生のアイデア出しを支援するだけでなく、具体的に以下の実装を提案・サポートしました。

  • AIチャットボット機能の組み込み
  • ガチャシステムなどのゲーミフィケーション要素の導入

実装の過程で、受講生が未学習のフロントエンド(JavaScriptやHTML5の各種プロパティ等)の知識が必要になった際、私のWebクリエイターとしての知使を活かし、具体的な実装アプローチを積極的に提案・指導しました。

堅牢性を意識させるGitHubコードレビュー

最終成果物に対しては、GitHub上で実務さながらのコードレビューを実施しました。単に「動けば良い」というコードではなく、将来的なバグや脆弱性の原因となり得る箇所の指摘に注力しました。

以下の画像のコードを例にします。

こちらのコードは「10連ガチャ」の要素の一部を再現したものです。

ユーザーが入力する`betPoint`に対して betPoint 10 の計算を行っているため、ベット数が 214,748,365 以上の場合、Javaの`int`型の最大値を超えて数値オーバーフローが発生します。結果として正しい「ポイント不足チェック」が機能しなくなるリスクを指摘しました。

このような境界値のバグを防ぐため、金額やポイントの計算には`long`型を使用する、あるいは計算前に上限チェックを行うといった、システムの堅牢性を担保するための具体的な修正方法を指導しました。

講師経験を通じて得た「2つの学びと成長」

2ヶ月間の研修に伴走する中で、教育の難しさと向き合い、エンジニアとしてもメンターとしても大きな気付きを得ることができました。

「プロフェッショナルな壁」を取り払い、本音の課題を引き出す距離感

過去にマンツーマンでプログラミング(PHP)を指導した際、丁寧さを意識するあまり業務的な距離感が生まれ、受講生が「実はここが分からない」という本音を言いにくくなってしまった反省がありました。

その経験を活かし、今回の集団研修では、単に上から教える「先生」ではなく、「一緒にエラーの謎を解き明かす一歩先行くチームメンバー」のようなスタンスで接することを意識しました。

受講生と同じ目線でドキュメントを調べたり、対等な立場でコードの設計について建設的な議論を交わしたりした結果、受講生の心理的ハードルが下がり、潜在的なつまずきを早期にキャッチアップして解決へ導くことができました。

「人に教えること」が生み出した、技術概念の高度な抽象化

「1を教えるためには、10の理解が必要である」という言葉の通り、受講生にフレームワークの仕組みやSQLの挙動を噛み砕いて説明するためには、私自身の知識の「曖昧さ」を完全に削ぎ落とす必要がありました。

特に、未経験の受講生に対してオブジェクト指向やMVCモデルなどの概念を説明する際、「いかに分かりやすい比喩表現に落とし込めるか」を徹底的に突き詰めました。このプロセスを経たことで、プログラムの構造をより客観的・抽象的に捉えられるようになり、私自身のバックエンドエンジニアとしての設計・開発視点も一段上のレベルへ引き上げられたと感じています。