<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CSRF | Seek Rise</title>
	<atom:link href="https://seek-rise.com/tag/csrf/feed/" rel="self" type="application/rss+xml" />
	<link>https://seek-rise.com</link>
	<description></description>
	<lastBuildDate>Sat, 03 Jan 2026 14:29:57 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://seek-rise.com/wp-content/uploads/2019/10/cropped-favicon-32x32.png</url>
	<title>CSRF | Seek Rise</title>
	<link>https://seek-rise.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="https://pubsubhubbub.superfeedr.com"/><atom:link rel="hub" href="https://websubhub.com/hub"/><site xmlns="com-wordpress:feed-additions:1">167377966</site>	<item>
		<title>6-11 CSRFとは？仕組みと対策</title>
		<link>https://seek-rise.com/web-development/php-basic/post-441/</link>
					<comments>https://seek-rise.com/web-development/php-basic/post-441/#respond</comments>
		
		<dc:creator><![CDATA[NOA（ノア）]]></dc:creator>
		<pubDate>Mon, 22 Dec 2025 14:19:24 +0000</pubDate>
				<category><![CDATA[Web開発学習ロードマップ]]></category>
		<category><![CDATA[6.PHP基礎]]></category>
		<category><![CDATA[Web開発]]></category>
		<category><![CDATA[初心者]]></category>
		<category><![CDATA[PHP基礎]]></category>
		<category><![CDATA[セキュリティ]]></category>
		<category><![CDATA[CSRF]]></category>
		<guid isPermaLink="false">https://seek-rise.com/?p=441</guid>

					<description><![CDATA[前の記事では、XSS（クロスサイトスクリプティング） という「表示時の危険性」について学びました。 今回扱う CSRF は、それとは別の方向から攻撃が行われます。 CSRFは、ユーザーが意図していない操作を、正規ユーザー [&#8230;]]]></description>
										<content:encoded><![CDATA[<p data-start="236" data-end="295">前の記事では、<br data-start="243" data-end="246" /><strong data-start="246" data-end="269">XSS（クロスサイトスクリプティング）</strong> という<br data-start="273" data-end="276" />「表示時の危険性」について学びました。</p>
<p data-start="297" data-end="335">今回扱う <strong data-start="302" data-end="310">CSRF</strong> は、<br data-start="313" data-end="316" />それとは別の方向から攻撃が行われます。</p>
<p data-start="337" data-end="395">CSRFは、<br data-start="343" data-end="346" /><strong data-start="346" data-end="391">ユーザーが意図していない操作を、<br data-start="364" data-end="367" />正規ユーザーとして実行させられてしまう脆弱性</strong> です。</p>
<p data-start="397" data-end="435">フォーム処理を行うPHPでは、<br data-start="412" data-end="415" /><strong data-start="415" data-end="428">CSRF対策は必須</strong> になります。</p>
<p data-start="437" data-end="501">この記事では、<br data-start="444" data-end="447" /><strong data-start="447" data-end="484">CSRFとは何か、なぜ危険なのか、<br data-start="466" data-end="469" />PHPでの基本的な対策方法</strong> を<br data-start="486" data-end="489" />コード付きで解説します。</p>
<hr data-start="503" data-end="506" />

  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2" checked><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">この記事で学べること</a></li><li><a href="#toc2" tabindex="0">CSRFとは何か</a></li><li><a href="#toc3" tabindex="0">CSRF攻撃の典型的な流れ</a></li><li><a href="#toc4" tabindex="0">CSRFで何が起こるのか</a></li><li><a href="#toc5" tabindex="0">なぜCSRFが起きるのか</a></li><li><a href="#toc6" tabindex="0">XSSとCSRFの違い</a></li><li><a href="#toc7" tabindex="0">CSRF対策の基本は「トークン」</a></li><li><a href="#toc8" tabindex="0">PHPでCSRFトークンを生成する</a><ol><li><a href="#toc9" tabindex="0">サンプルコード①：トークン生成</a></li><li><a href="#toc10" tabindex="0">コードの読み解き</a></li></ol></li><li><a href="#toc11" tabindex="0">フォームにトークンを埋め込む</a><ol><li><a href="#toc12" tabindex="0">サンプルコード②：フォーム側</a></li><li><a href="#toc13" tabindex="0">ポイント</a></li></ol></li><li><a href="#toc14" tabindex="0">送信時にトークンを検証する</a><ol><li><a href="#toc15" tabindex="0">サンプルコード③：トークン検証</a></li><li><a href="#toc16" tabindex="0">コードの読み解き</a></li></ol></li><li><a href="#toc17" tabindex="0">CSRF対策が必要な処理</a></li><li><a href="#toc18" tabindex="0">初心者がよくやるミス</a></li><li><a href="#toc19" tabindex="0">フレームワークがCSRF対策を自動化する理由</a></li><li><a href="#toc20" tabindex="0">まとめ</a></li><li><a href="#toc21" tabindex="0">次に読むべき記事</a></li></ol>
    </div>
  </div>

<h2 data-start="508" data-end="521"><span id="toc1">この記事で学べること</span></h2>
<p data-start="523" data-end="594">・CSRFとは何か<br data-start="532" data-end="535" />・CSRF攻撃の仕組み<br data-start="546" data-end="549" />・なぜCSRFが危険なのか<br data-start="562" data-end="565" />・PHPでの基本的なCSRF対策<br data-start="581" data-end="584" />・XSSとの違い</p>
<hr data-start="596" data-end="599" />
<h2 data-start="601" data-end="612"><span id="toc2">CSRFとは何か</span></h2>
<p data-start="614" data-end="699">CSRF（Cross Site Request Forgery）とは、<br data-start="649" data-end="652" /><strong data-start="652" data-end="695">ログイン中のユーザーの権限を悪用し、<br data-start="672" data-end="675" />意図しないリクエストを送信させる攻撃</strong> です。</p>
<p data-start="701" data-end="754">攻撃者自身がログインするわけではなく、<br data-start="720" data-end="723" /><strong data-start="723" data-end="741">被害者がログインしている状態</strong> を利用する点が特徴です。</p>
<hr data-start="756" data-end="759" />
<h2 data-start="761" data-end="777"><span id="toc3">CSRF攻撃の典型的な流れ</span></h2>
<p data-start="779" data-end="802">CSRFは、<br data-start="785" data-end="788" />次のような流れで行われます。</p>
<ol data-start="804" data-end="918">
<li data-start="804" data-end="826">
<p data-start="807" data-end="826">ユーザーがWebサービスにログイン</p>
</li>
<li data-start="827" data-end="850">
<p data-start="830" data-end="850">ログイン状態のまま、別のサイトを閲覧</p>
</li>
<li data-start="851" data-end="877">
<p data-start="854" data-end="877">そのサイトから勝手にリクエストが送信される</p>
</li>
<li data-start="878" data-end="901">
<p data-start="881" data-end="901">サーバーは正規ユーザーの操作だと判断</p>
</li>
<li data-start="902" data-end="918">
<p data-start="905" data-end="918">処理が実行されてしまう</p>
</li>
</ol>
<p data-start="920" data-end="969">ユーザーは、<br data-start="926" data-end="929" /><strong data-start="929" data-end="956">自分が操作したつもりがなくても処理が実行される</strong><br data-start="956" data-end="959" />という点が問題です。</p>
<hr data-start="971" data-end="974" />
<h2 data-start="976" data-end="991"><span id="toc4">CSRFで何が起こるのか</span></h2>
<p data-start="993" data-end="1021">CSRFが成立すると、<br data-start="1004" data-end="1007" />次のような被害が起こります。</p>
<p data-start="1023" data-end="1065">・パスワード変更<br data-start="1031" data-end="1034" />・メールアドレス変更<br data-start="1044" data-end="1047" />・投稿や削除処理<br data-start="1055" data-end="1058" />・退会処理</p>
<p data-start="1067" data-end="1105">どれも<br data-start="1070" data-end="1073" /><strong data-start="1073" data-end="1093">本人の意思とは無関係に実行される</strong><br data-start="1093" data-end="1096" />可能性があります。</p>
<hr data-start="1107" data-end="1110" />
<h2 data-start="1112" data-end="1127"><span id="toc5">なぜCSRFが起きるのか</span></h2>
<p data-start="1129" data-end="1139">原因はシンプルです。</p>
<p data-start="1141" data-end="1176"><strong data-start="1141" data-end="1176">「そのリクエストが、本当に本人の操作かどうかを確認していない」</strong></p>
<p data-start="1178" data-end="1185">サーバー側が、</p>
<p data-start="1187" data-end="1222">・ログインしている<br data-start="1196" data-end="1199" />という理由だけで<br data-start="1207" data-end="1210" />・正当な操作だと判断</p>
<p data-start="1224" data-end="1237">してしまうことが問題です。</p>
<hr data-start="1239" data-end="1242" />
<h2 data-start="1244" data-end="1258"><span id="toc6">XSSとCSRFの違い</span></h2>
<p data-start="1260" data-end="1274">ここで整理しておきましょう。</p>
<p data-start="1276" data-end="1301">・XSS<br data-start="1280" data-end="1283" />　→ スクリプトを実行させる攻撃</p>
<p data-start="1303" data-end="1329">・CSRF<br data-start="1308" data-end="1311" />　→ リクエストを実行させる攻撃</p>
<p data-start="1331" data-end="1363">どちらも危険ですが、<br data-start="1341" data-end="1344" /><strong data-start="1344" data-end="1362">攻撃の方法と対策が異なります</strong>。</p>
<hr data-start="1365" data-end="1368" />
<h2 data-start="1370" data-end="1389"><span id="toc7">CSRF対策の基本は「トークン」</span></h2>
<p data-start="1391" data-end="1426">CSRF対策の基本は、<br data-start="1402" data-end="1405" /><strong data-start="1405" data-end="1417">CSRFトークン</strong> を使う方法です。</p>
<p data-start="1428" data-end="1435">トークンとは、</p>
<p data-start="1437" data-end="1475">・推測できない文字列<br data-start="1447" data-end="1450" />・フォームごとに発行<br data-start="1460" data-end="1463" />・送信時に一緒に送る</p>
<p data-start="1477" data-end="1486">という仕組みです。</p>
<hr data-start="1488" data-end="1491" />
<h2 data-start="1493" data-end="1513"><span id="toc8">PHPでCSRFトークンを生成する</span></h2>
<p data-start="1515" data-end="1546">まずは、<br data-start="1519" data-end="1522" />トークンを生成して<br data-start="1531" data-end="1534" />セッションに保存します。</p>
<h3 data-start="1548" data-end="1567"><span id="toc9">サンプルコード①：トークン生成</span></h3>
<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary">
<pre class="overflow-y-auto p-4" dir="ltr"><code class="whitespace-pre! language-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-title function_ invoke__">session_start</span>();

<span class="hljs-keyword">if</span> (<span class="hljs-keyword">empty</span>(<span class="hljs-variable">$_SESSION</span>[<span class="hljs-string">'csrf_token'</span>])) {
  <span class="hljs-variable">$_SESSION</span>[<span class="hljs-string">'csrf_token'</span>] = <span class="hljs-title function_ invoke__">bin2hex</span>(<span class="hljs-title function_ invoke__">random_bytes</span>(<span class="hljs-number">32</span>));
}
</code></pre>
</div>
<hr data-start="1700" data-end="1703" />
<h3 data-start="1705" data-end="1717"><span id="toc10">コードの読み解き</span></h3>
<p data-start="1719" data-end="1800">・session_start<br data-start="1733" data-end="1736" />　→ セッションを開始<br data-start="1747" data-end="1750" />・random_bytes<br data-start="1763" data-end="1766" />　→ 安全なランダム文字列生成<br data-start="1781" data-end="1784" />・$_SESSION に保存</p>
<p data-start="1802" data-end="1830">トークンは、<br data-start="1808" data-end="1811" /><strong data-start="1811" data-end="1824">ユーザーごとに保持</strong> されます。</p>
<hr data-start="1832" data-end="1835" />
<h2 data-start="1837" data-end="1854"><span id="toc11">フォームにトークンを埋め込む</span></h2>
<p data-start="1856" data-end="1877">次に、<br data-start="1859" data-end="1862" />フォームにトークンを含めます。</p>
<h3 data-start="1879" data-end="1897"><span id="toc12">サンプルコード②：フォーム側</span></h3>
<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary">
<pre class="overflow-y-auto p-4" dir="ltr"><code class="whitespace-pre! language-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span></span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"result.php"</span>&gt;
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span></span> <span class="hljs-attr">type</span>=<span class="hljs-string">"hidden"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"csrf_token"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"&lt;?php echo $_SESSION['csrf_token']; ?&gt;"</span>&gt;
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span></span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;送信<span class="hljs-tag">&lt;/<span class="hljs-name">button</span></span>&gt;
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span></span>&gt;
</code></pre>
</div>
<hr data-start="2086" data-end="2089" />
<h3 data-start="2091" data-end="2099"><span id="toc13">ポイント</span></h3>
<p data-start="2101" data-end="2153">・hidden フィールドで送信<br data-start="2117" data-end="2120" />・ユーザーには見えない<br data-start="2131" data-end="2134" />・正規フォームからしか送信できない</p>
<hr data-start="2155" data-end="2158" />
<h2 data-start="2160" data-end="2176"><span id="toc14">送信時にトークンを検証する</span></h2>
<p data-start="2178" data-end="2205">フォーム送信後、<br data-start="2186" data-end="2189" />PHP側でトークンを確認します。</p>
<h3 data-start="2207" data-end="2226"><span id="toc15">サンプルコード③：トークン検証</span></h3>
<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary">
<pre class="overflow-y-auto p-4" dir="ltr"><code class="whitespace-pre! language-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-title function_ invoke__">session_start</span>();

<span class="hljs-keyword">if</span> (
  <span class="hljs-keyword">empty</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'csrf_token'</span>]) ||
  <span class="hljs-variable">$_POST</span>[<span class="hljs-string">'csrf_token'</span>] !== <span class="hljs-variable">$_SESSION</span>[<span class="hljs-string">'csrf_token'</span>]
) {
  <span class="hljs-keyword">echo</span> <span class="hljs-string">'不正なリクエストです'</span>;
  <span class="hljs-keyword">exit</span>;
}

<span class="hljs-keyword">echo</span> <span class="hljs-string">'正規のリクエストです'</span>;
</code></pre>
</div>
<hr data-start="2408" data-end="2411" />
<h3 data-start="2413" data-end="2425"><span id="toc16">コードの読み解き</span></h3>
<p data-start="2427" data-end="2457">・トークンが存在するか<br data-start="2438" data-end="2441" />・セッションの値と一致するか</p>
<p data-start="2459" data-end="2489">どちらかでも失敗した場合、<br data-start="2472" data-end="2475" /><strong data-start="2475" data-end="2484">処理を中断</strong> します。</p>
<hr data-start="2491" data-end="2494" />
<h2 data-start="2496" data-end="2511"><span id="toc17">CSRF対策が必要な処理</span></h2>
<p data-start="2513" data-end="2541">特にCSRF対策が必要なのは、<br data-start="2528" data-end="2531" />次のような処理です。</p>
<p data-start="2543" data-end="2568">・登録<br data-start="2546" data-end="2549" />・更新<br data-start="2552" data-end="2555" />・削除<br data-start="2558" data-end="2561" />・設定変更</p>
<p data-start="2570" data-end="2602">逆に、<br data-start="2573" data-end="2576" />表示のみの処理では<br data-start="2585" data-end="2588" />必須ではない場合もあります。</p>
<hr data-start="2604" data-end="2607" />
<h2 data-start="2609" data-end="2622"><span id="toc18">初心者がよくやるミス</span></h2>
<p data-start="2624" data-end="2638">CSRF対策で多いミスです。</p>
<p data-start="2640" data-end="2690">・ログインしているから安全だと思う<br data-start="2657" data-end="2660" />・トークンを検証していない<br data-start="2673" data-end="2676" />・GETで更新処理を行う</p>
<p data-start="2692" data-end="2724"><strong data-start="2692" data-end="2710">更新系処理＝CSRF対策必須</strong><br data-start="2710" data-end="2713" />と覚えておきましょう。</p>
<hr data-start="2726" data-end="2729" />
<h2 data-start="2731" data-end="2756"><span id="toc19">フレームワークがCSRF対策を自動化する理由</span></h2>
<p data-start="2758" data-end="2794">Laravelなどのフレームワークが<br data-start="2776" data-end="2779" />CSRF対策を自動で行うのは、</p>
<p data-start="2796" data-end="2820">・実装ミスが起きやすい<br data-start="2807" data-end="2810" />・忘れると致命的</p>
<p data-start="2822" data-end="2828">だからです。</p>
<p data-start="2830" data-end="2877">基礎を理解しておくことで、<br data-start="2843" data-end="2846" />フレームワークの仕組みも<br data-start="2858" data-end="2861" />正しく理解できるようになります。</p>
<hr data-start="2879" data-end="2882" />
<h2 data-start="2884" data-end="2890"><span id="toc20">まとめ</span></h2>
<p data-start="2892" data-end="2898">CSRFは、</p>
<p data-start="2900" data-end="2937">・ログイン中のユーザーを利用した<br data-start="2916" data-end="2919" />・意図しない操作を実行させる攻撃</p>
<p data-start="2939" data-end="2942">です。</p>
<p data-start="2944" data-end="2951">対策の基本は、</p>
<p data-start="2953" data-end="2992">・CSRFトークンを発行<br data-start="2965" data-end="2968" />・フォームに埋め込む<br data-start="2978" data-end="2981" />・送信時に検証する</p>
<p data-start="2994" data-end="3006">この流れを守ることです。</p>
<p data-start="3008" data-end="3054">ここまで理解できれば、<br data-start="3019" data-end="3022" />フォーム処理に必要な<br data-start="3032" data-end="3035" /><strong data-start="3035" data-end="3050">セキュリティ基礎は完成</strong> です。</p>
<hr data-start="3056" data-end="3059" />
<h2 data-start="3061" data-end="3072"><span id="toc21">次に読むべき記事</span></h2>
<p data-start="3074" data-end="3110">▶ 次の記事<br data-start="3080" data-end="3083" /><a href="https://seek-rise.com/web-development/php-basic/post-443/">6-12 PHPでセッションを使って状態を管理する</a></p>
<p data-start="3112" data-end="3141">▶ 関連記事<br data-start="3118" data-end="3121" /><a href="https://seek-rise.com/web-development/php-basic/post-438/">6-10 XSSとは？なぜ危険なのか</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://seek-rise.com/web-development/php-basic/post-441/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">441</post-id>	</item>
	</channel>
</rss>
