🔐
安全なWebサイトを作ろう③
ごあいさつ
こんにちは!
オアシステクノロジーズの古本です。
今日はWebアプリケーションを構築する上でめちゃめちゃ重要な「セキュリティ」に関する話題です。
この記事の続きです
Webアプリのセキュリティリスクと対策
1. CSRF(クロスサイトリクエストフォージェリ)
攻撃の概要
CSRF(Cross-Site Request Forgery)は、ユーザーが意図しないリクエストを攻撃者が送信させる攻撃手法です。これにより、ユーザーが意図しないアクション(例: パスワード変更、送金処理など)を実行させられる可能性があります。
発生する問題・具体例
- 不正送金: オンラインバンキングでCSRF攻撃を受けると、ユーザーが知らない間に攻撃者の口座へ送金される。
- アカウント乗っ取り: SNSやECサイトでメールアドレスやパスワード変更をされると、アカウントを奪われる可能性がある。
攻撃例
<!-- 攻撃者のサイト -->
<img src="https://example.com/api/transfer?amount=10000&to=attacker" />
対策
1. SameSite Cookie の設定(Next.js)
Next.js の API で cookies
を使う場合、SameSite
属性を適切に設定することでCSRF攻撃を防ぐことができます。
import { NextRequest, NextResponse } from 'next/server';
export function middleware(req: NextRequest) {
const res = NextResponse.next();
res.cookies.set('session', 'value', { httpOnly: true, secure: true, sameSite: 'Strict' });
return res;
}
2. CSRFトークンの利用(Spring Boot)
Spring Securityを使うと、CSRFトークンがデフォルトで有効になっています。
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
.formLogin(Customizer.withDefaults());
return http.build();
}
}
3. Next.jsのミドルウェアを利用した対策
Next.js ではミドルウェアを活用して Content-Security-Policy
や Permissions-Policy
を適用し、攻撃リスクを低減できます。
import { NextRequest, NextResponse } from 'next/server';
export function middleware(req: NextRequest) {
const res = NextResponse.next();
res.headers.set(
"Content-Security-Policy",
"default-src 'self'; script-src 'self' 'unsafe-inline'; object-src 'none'"
);
return res;
}
2. HTTPヘッダインジェクション
攻撃の概要
HTTPヘッダインジェクションは、適切にエスケープされていないユーザー入力をHTTPレスポンスヘッダに組み込むことで、リダイレクトやXSS攻撃を引き起こす手法です。
発生する問題・具体例
- フィッシングサイトへの誘導: リダイレクトURLを書き換えられ、攻撃者が用意した偽サイトに誘導される。
- Cookieの漏洩: HTTPヘッダを改ざんすることで、セッションCookieを盗み取られる可能性がある。
攻撃例
// Spring Boot(脆弱な実装例)
@GetMapping("/redirect")
public ResponseEntity<Void> redirect(@RequestParam String url) {
HttpHeaders headers = new HttpHeaders();
headers.set("Location", url); // 悪意のあるURLを挿入可能
return new ResponseEntity<>(headers, HttpStatus.FOUND);
}
対策
1. ユーザー入力のバリデーション
@GetMapping("/redirect")
public ResponseEntity<Void> safeRedirect(@RequestParam String url) {
if (!url.startsWith("https://example.com")) {
return ResponseEntity.badRequest().build();
}
HttpHeaders headers = new HttpHeaders();
headers.set("Location", url);
return new ResponseEntity<>(headers, HttpStatus.FOUND);
}
2. Next.jsのリダイレクト制限
Next.js では next.config.js
でリダイレクトルールを制限できます。
module.exports = {
redirects: async () => [
{
source: '/old-route',
destination: '/new-route',
permanent: true,
},
],
};
3. メールヘッダインジェクション
攻撃の概要
メールヘッダインジェクションは、メール送信時に適切にサニタイズされていない入力を使用することで、攻撃者がCCやBCCに別のメールアドレスを追加し、スパム送信や情報漏洩を引き起こす攻撃です。
発生する問題・具体例
- スパムメールの大量送信: メールヘッダを改ざんすることで、企業のサーバーをスパム送信に悪用される。
- フィッシング詐欺: 送信元を偽装し、信頼できる企業を装った詐欺メールを送ることが可能。
攻撃例
// Spring Boot(脆弱な実装例)
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, false);
helper.setTo(userInput); // ユーザー入力をそのまま使用
helper.setSubject("Your Order Confirmation");
helper.setText("Thank you for your order!");
mailSender.send(message);
対策
1. 入力値のバリデーション
private boolean isValidEmail(String email) {
return email.matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
}
参考:
まとめ
残すところあと1回です!
飽きずについてきてください!w
Discussion