Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions docs/labs/ja_sql-injection.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://best.openssf.org/assets/css/style.css">
<link rel="stylesheet" href="checker.css">
<script src="checker.js"></script>
<script src="sql-injection.js"></script>
<link rel="license" href="https://creativecommons.org/licenses/by/4.0/">

<!-- See create_labs.md for how to create your own lab! -->

</head>
<body>
<!-- For GitHub Pages formatting: -->
<div class="container-lg px-3 my-5 markdown-body">
<h1>ラボ演習 sql-injection</h1>
<p>
これはセキュアなソフトウェア開発に関するラボ演習です。
ラボの詳細については、<a href="ja_introduction.html" target="_blank">概要</a>をご覧ください。

<p>
<h2>ゴール</h2>
<p>
<b>SQL インジェクション攻撃を防ぐために、パラメータ化されたステートメントの構築方法を学びます
</b>

<p>
<h2>背景</h2>
<p>
パラメータ化されたステートメントは、SQLコードとデータ入力を分離することで SQL インジェクション攻撃を防ぐために使用されます。パラメータ化されたステートメントとは、ユーザー入力をクエリに直接埋め込むのではなく、プレースホルダを利用する SQL クエリです。これにより、クエリに悪意のあるコードが挿入されるのを防ぎます。
<p>
<h2>タスクの詳細</h2>
<p>

<p>
このラボでは、SQL インジェクション攻撃に関連するコードを学び、それを修正します。プリペアドステートメント / パラメータ化されたステートメントについて、いくつかの問いに答えてください。

<p>
必要に応じて、「ヒント」ボタンと「諦める」ボタンを使用してください。

<p>
<h2>演習 (<span id="grade"></span>)</h2>
<p>
Java で書かれた以下のサンプルコードを見ると、脆弱性を含むコードの一例であることが分かります。
(この例は
<a href="https://github.com/ossf/secure-sw-dev-fundamentals/blob/main/secure_software_development_fundamentals.md">Secure
Software Development Fundamentals</a> コースの内容を直接引用しました)
(訳注:リンクはコースの GitHub レポジトリを指しているため英語です)
これをプリペアドステートメント(パラメータ化されたステートメントの一種)を使用するシーケンスとなるように書き換えます。
最初の部分では、<tt>pstmt</tt> という名前で <tt>PreparedStatement</tt> 型の変数を作ります。
二つ目の部分では、<tt>setString</tt> を使って検索対象を設定し、<tt>ResultSet</tt> 型の <tt>results</tt> 変数に結果を格納します。
ここでは結果のコレクションを得たいので、クエリの実行には <tt>executeQuery</tt> を使用してください。

<form id="lab">
<pre><code
> // クエリの準備
<textarea id="attempt0" rows="4" cols="60" spellcheck="false"
> String QueryString =
"select * from authors where lastname = ' " +
search_lastname + " '; ";
</textarea>
// クエリの実行
<textarea id="attempt1" rows="3" cols="60" spellcheck="false"
> rs = statement.executeQuery(QueryString);
</textarea>
</code></pre>
<button type="button" class="hintButton">ヒント</button>
<button type="button" class="resetButton">リセット</button>
<button type="button" class="giveUpButton">諦める</button>
</form>
<br><br>
<p>
<i>このラボは Elijah Everett, Jeremiah Howard, および Emily Lovell により
<a href="https://github.com/emmet0r/contributor-catalyst"
>Contributor Catalyst Program</a> の一部として、また David A. Wheeler により開発されました。</i>
<br><br>
<p id="correctStamp" class="small">
<textarea id="debugData" class="displayNone" rows="20" cols="65" readonly>
</textarea>
</div>
</body>
</html>
8 changes: 8 additions & 0 deletions docs/labs/sql-injection.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ info =
{
present: "search_lastname",
text: "You should replace \"search_lastname\" with a placeholder (?).",
text_ja: "\"search_lastname\" をプレースホルダの (?) に置き換える必要があります。",
index: 0,
examples: [
[
Expand All @@ -17,12 +18,14 @@ info =
{
absent: String.raw`\?`,
text: "Write an parameterized statement with the Special character \"?\" added.",
text_ja: "特殊文字である \"?\" を使ってパラメータ化されたステートメントを書いてください。",
index: 0
},
{
present: String.raw`\+`,
index: 0,
text: "There is no need for string concatenation. Use a simple constant string using the form \"...\".",
text_ja: "文字列連結は必要ありません。\"...\" の形で定数文字列を使ってください。",
examples: [
[
"String QueryString =\n \"select * from authors where lastname = \" + \"?\" + \" ; \";\n",
Expand All @@ -34,28 +37,33 @@ info =
absent: String.raw`\s* PreparedStatement\s+pstmt = connection \.
prepareStatement \( QueryString \) \; \s*`,
text: "After defining the query string you should create a prepared statement, using the form `PreparedStatement pstmt = connection.prepareStatement(QueryString);`",
text_ja: "クエリ文字列を定義したあとに、`PreparedStatement pstmt = connection.prepareStatement(QueryString);` の形でプリペアドステートメントを作成する必要があります。",
},
{
absent: "search_lastname",
present: "lastname",
index: 1,
text: "The term `lastname` is the name of the database field to be searched, However, you want to search for a specific value in that field. That value is held in the variable `search_lastname`, not in `lastname`.",
text_ja: "`lastname` は検索するデータベースのフィールド名です。このフィールドからある特定の値を検索したいはずです。その値は `lastname` ではなく `search_lastname` に格納されています。",
},
{
absent: String.raw`pstmt \. setString \( 1 , search_lastname \) \;`,
index: 1,
text: "Start the second section with a statement like `pstmt.setString(1, search_lastname);`",
text_ja: "2つ目のセクションは `pstmt.setString(1, search_lastname);` で始めてください。",
},
{
absent: "executeQuery",
present: "execute",
index: 1,
text: "Use `executeQuery` not `execute` so we can receive and use a potential series of results (a `ResultSet`).",
text_ja: "`execute` ではなく `executeQuery` を使用してください。これで一連の結果(ResultSet)を得ることができます。",
},
{
absent: String.raw`\s* ResultSet\s+results = pstmt \. executeQuery \( \) \; \s*`,
index: 1,
text: "After using `setString` execute the query and place the results in `results`, something like `ResultSet results = pstmt.executeQuery();`",
text_ja: "`setString` のあとでクエリを実行し、結果を `result` に格納してください。`ResultSet results = pstmt.executeQuery();` のような形になるはずです。",
},
],
expected: [
Expand Down