小程序APIの不正アクセス対策実装と課題

ショート動画プラットフォームを経由して公開した小程序で予期せぬアクセス集中が発生。リソースパックが短期間で枯渇し、アクセスログ分析により不正リクエストの存在を確認。自然流量と対照実験の結果、名前の選定がアクセスパターンに与える影響を明確に把握。以下、実際の対策手法と課題を技術的視点で解説。

アクセス異常の検出

30時間分のリソースパックが数日で消費されるアラートが発生。アクセスログを調査したところ、特定IPからの連続的な動画テキスト抽出リクエストが確認。通常の利用パターンとは異なるリクエスト間隔とPCクライアントからのアクセスが多数を占めていた。

署名検証機構の実装

リクエスト正当性を検証するため、SHA1ベースの署名メカニズムを導入。フロントエンド処理では、リクエストパラメータをソートし静的キーを追加してハッシュ値を生成。バックエンドでは同様のアルゴリズムで検証を実施。

const createRequestHash = (payload) => {
  const timestamp = Date.now();
  const nonce = Math.floor(100000 + Math.random() * 900000);
  payload.ts = timestamp;
  payload.nonce = nonce;
  payload.apiKey = config.secretKey;

  const sortedValues = Object.values(payload).sort();
  const rawString = sortedValues.join('');
  payload.signature = sha1(rawString);
  delete payload.apiKey;
  return payload;
};
サーバーサイドではSpring Bootのインターセプタを用いて検証ロジックを実装。タイムスタンプ有効性チェックとパラメータ再計算による署名一致判定を実施。

@Component
public class ApiAuthInterceptor implements HandlerInterceptor {
    private static final String SECRET_KEY = "secure_value";
    private static final long TIME_WINDOW = 300;

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
        try {
            String body = IOUtils.toString(req.getInputStream(), StandardCharsets.UTF_8);
            JSONObject json = JSON.parseObject(body);
            String clientSig = json.getString("signature");
            long timestamp = json.getLongValue("ts");

            if (System.currentTimeMillis() / 1000 - timestamp > TIME_WINDOW) {
                sendError(res, "Timestamp expired", 401);
                return false;
            }

            List<String> params = new ArrayList<>();
            json.forEach((k, v) -> {
                if (!"signature".equals(k) && !"ts".equals(k)) {
                    params.add(v.toString());
                }
            });
            params.add(SECRET_KEY);
            Collections.sort(params);
            String serverSig = SecureUtil.sha1(String.join("", params));

            if (!clientSig.equals(serverSig)) {
                sendError(res, "Invalid signature", 401);
                return false;
            }
            return true;
        } catch (Exception e) {
            sendError(res, "Request processing failed", 400);
            return false;
        }
    }
}

RPAツールによる回避策

署名検証を導入後も、RPAツールが人間の操作を模倣してリクエストを送信。PCクライアントからのアクセスが異常に多く、定期的なリクエストパターンが確認された。署名検証のみでは自動化ツールを完全に防げないことが判明。

利用制限の最適化

ユーザーごとの日次利用上限を設定し、RPAロボットによる一斉アクセスを抑制。特定ユーザーの制限値を優先的に適用することで、通常利用者への影響を最小化。さらに、IPアドレスとユーザーIDの組み合わせによる追加制限を実装。

今後の展開

短編動画コンテンツ需要の増加に伴い、200MB制限を超える動画処理のための圧縮機能を検討中。動画処理の効率化とリソース管理の最適化が今後の開発課題となっている。

タグ: APIセキュリティ SHA1署名 RPA対策 微信小程序 Spring Boot

7月13日 00:34 投稿