0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ASP.NET Core MVC セキュリティ対策まとめ

0
Posted at

セキュリティ対策まとめ(XSS / CSRF / SQLインジェクション)— ASP.NET Core MVC 実務の基本

Webアプリケーションの脆弱性は、多くの場合 「信頼できない入力値」 を適切に処理しないことから生まれます。
ASP.NET Core MVC で強固な基盤を作るには、フレームワークが提供する保護機能を 「なぜ」「どのように」使うか を理解することが不可欠です。

この記事では、実務でまず押さえるべき 3 大対策を コード付きで整理します。

  • XSS(クロスサイトスクリプティング)
  • CSRF(クロスサイトリクエストフォージェリ)
  • SQLインジェクション

1. XSS(クロスサイトスクリプティング)防止

XSS とは

攻撃者が悪意あるスクリプトをページに埋め込み、閲覧者のブラウザ上で実行させる攻撃です。
基本原則は 「入力の検証」「出力のエンコーディング」 です。

ASP.NET Core MVC がデフォルトで守ってくれること

Razor は デフォルトで HTML エンコードします。
たとえば @Model.Comment<script>alert('xss')</script> が入っていても、Razor は &lt;script&gt;... のように変換して出力するため、ブラウザはスクリプトとして実行しません。

やってはいけない(危険): Html.Raw() の乱用

Html.Raw() は Razor の自動エスケープを無効化します。
ユーザー入力に対しては絶対に不用意に使わないでください。

@* 危険:ユーザー入力をそのまま HTML としてレンダリング *@
@Html.Raw(Model.UserInput)

@* 安全:Razor が自動で HTML エンコード *@
<p>@Model.UserInput</p>

実務でのコツ

  • 表示する文字列は **「基本はエスケープされる」**前提で設計する
  • どうしても HTML を許可する場合は、許可タグのホワイトリスト方式を検討する(無制限な Raw はNG)

2. CSRF(クロスサイトリクエストフォージェリ)防止

CSRF とは

ログイン済みユーザーのセッション(Cookie)を悪用し、ユーザーの意図しない操作(例:パスワード変更、決済)を 別サイトから勝手に実行させる攻撃です。

ASP.NET Core MVC の基本対策:Antiforgery トークン

フォーム送信に 一意のトークンを含め、サーバー側で検証します。
これにより「正当な画面(自サイト)から送られたPOSTか?」を確認できます。

View 側(フォーム)

<form asp-controller="Account" asp-action="UpdateProfile" method="post">
    @Html.AntiForgeryToken()
    <input type="text" name="Username" />
    <button type="submit">保存</button>
</form>

Controller 側(検証)

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult UpdateProfile(UserViewModel model)
{
    // トークンが一致しない場合、ここは実行されず 400 などで弾かれる
    return View();
}

実務でのコツ

  • フォームPOSTには基本 @Html.AntiForgeryToken() + [ValidateAntiForgeryToken]
  • API(JSON)でやる場合は構成が変わる(Cookie 認証 + SPA の場合はヘッダー連携など)
    ※MVC + Razor のフォーム中心なら上の組み合わせをまず徹底でOK

3. SQLインジェクション防止

SQLインジェクションとは

SQL のパラメータ部分に悪意ある SQL を注入し、DB を不正操作する攻撃です。

EF Core(LINQ)なら基本安全

EF Core の LINQ クエリは内部的に パラメータ化クエリを生成します。
ユーザー入力がそのまま SQL として解釈されにくいのが大きな利点です。

// 安全:EF Core が自動的にパラメータ化する
var user = _context.Users.FirstOrDefault(u => u.Email == inputEmail);

やってはいけない(危険): 文字列連結で生SQLを作る

// 危険:SQLインジェクションの脆弱性がある
var query = "SELECT * FROM Users WHERE Email = '" + inputEmail + "'";
_context.Users.FromSqlRaw(query);

正しい(安全): パラメータ化する

// 安全:パラメータ化する
var query = "SELECT * FROM Users WHERE Email = {0}";
var users = _context.Users.FromSqlRaw(query, inputEmail).ToList();

生SQLが必要なケースはありますが、文字列連結は禁止と覚えておくと事故が減ります。


4. セキュリティ対策が効く流れ(リクエスト・ライフサイクル)

以下は「フォームPOSTを例にした」ざっくりした流れです。


5. 堅牢なフォーム設計(バリデーションは最後の砦)

脆弱性を防ぐ上で「最後の砦」になるのが 入力バリデーションです。
DataAnnotations を活用して、モデルに制約を持たせます。

public class UserProfileViewModel
{
    [Required]
    [StringLength(50, MinimumLength = 3)]
    public string Username { get; set; } = string.Empty;

    [EmailAddress]
    public string? Email { get; set; }
}

Controller では必ず ModelState.IsValid をチェックします。

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult UpdateProfile(UserProfileViewModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    // 正常系の処理
    return RedirectToAction("Index");
}

まとめ(チェックリスト)

  • XSS
    • Razor の自動エンコードを信頼する
    • Html.Raw() をユーザー入力に使わない
  • CSRF
    • フォームには @Html.AntiForgeryToken()
    • POST には [ValidateAntiForgeryToken]
  • SQLインジェクション
    • 基本は EF Core(LINQ)で安全に
    • 生SQLは 必ずパラメータ化(文字列連結は禁止)
  • バリデーション
    • DataAnnotations + ModelState.IsValid を習慣化

セキュリティ対策は「後付け」ではなく 設計の一部です。
まずはこの基本セットを徹底すると、実務の事故率が大きく下がります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?