logo
bars

ALTCHA
と CapMonster Cloud

キャプチャの解決、サイトへの設置、テスト。
キャプチャや防御機構が導入済みのサイトを引き継いだのに、ソースコードへアクセスできない? その場合、どの仕組みが入っているのか、設定は正しいのか、どう検証するのかが気になります。

この記事では、よくある疑問にできるだけお答えしました。まず最初のステップは、どのような保護システムが使われているかを特定することです。そのために、代表的なキャプチャやボット対策システムの一覧を参照できます。ここには、どの仕組みが使われているかを素早く見分けるための画面イメージや主な特徴がまとめられています。

もしサイトで ALTCHA が使われていることが分かったら、次のステップはその特徴と動作をより詳しく確認することです。同じこの記事の中で、ALTCHA をサイトに導入するための手順書も確認できるので、あなたのサイト上でどのように機能しているのかをしっかり理解できます。これにより、現在の保護を正しく把握できるだけでなく、今後の運用や保守も計画的に行えるようになります。

ALTCHAとは
ALTCHAとは
ALTCHA(Alternative CAPTCHA)は、ウェブサイトをボットやスパムから保護するシステムです。実際のユーザーと自動プログラムを区別するのに役立ち、サイトの安全かつ安定した運用を実現します。ALTCHAは従来のCAPTCHAの現代的な代替手段であり、軽量の暗号化チャレンジ(proof-of-work)を使用し、クッキーを収集せずユーザーを追跡しません。
Background
ALTCHA の例
Proof-of-Work (PoW)
Proof-of-Work (PoW)
システムはデフォルトでProof-of-Work(PoW)検証を使用し、視覚的なパズルや煩わしい確認を排除します。このアプローチはセキュリティとユーザビリティを両立させ、大多数の訪問者に適した控えめなCaptchaソリューションを提供します。
Code Captcha
Code Captcha
保護はテキストキャプチャの入力まで強化可能です。
Invisible Captcha
Invisible Captcha
確認は目に見えるウィジェットなしで行われ、ユーザーの操作は不要です。

CapMonster Cloud経由でALTCHAを解く方法

ALTCHA を含むフォームをテストする際は、キャプチャが正しく組み込まれ機能しているか確認する必要があります。

サイトに埋め込まれたキャプチャを手動で確認する方法

  • フォームのページを開き、キャプチャが表示されることを確かめます。
  • 解決せずにフォーム送信を試みると、サーバーはエラーを返すはずです。
  • 正しく解決した後は、問題なく送信できる必要があります。

自動解決には CapMonster Cloud のようなツールを使うと便利です。キャプチャのパラメータを送信すると、サーバー側で処理して利用可能なトークンを返してくれます。そのトークンをフォームに挿入すれば、ユーザー操作なしでチェックを通過できます。

CapMonster Cloud API を使った一般的な手順:

タスクの作成タスクの作成
arrow
API リクエストの送信API リクエストの送信
arrow
結果の受信結果の受信
arrow
トークンをページへ適用トークンをページへ適用
arrow
解決、トークン挿入、フォーム送信
あなたのウェブページでのキャプチャ解決の完全なサイクルを示すNode.js例。可能なアプローチ:HTTPリクエストを使用してHTMLとキャプチャパラメータを取得し、応答を送信して結果を処理;または自動化ツール(例:Playwright)を使用 — ページを開き、キャプチャを待ち、パラメータを送信(テスト用に正しいまたは不正なデータを送信可能)、CapMonster Cloudクライアントを通じて結果を取得、フォームにトークンを挿入し、結果を確認。
// npm install playwright
// npx playwright install chromium

const { chromium } = require("playwright");

const API_KEY = "YOUR_API_KEY";
const ALTCHA_PAGE = "https://example.com"; // ALTCHAを設置したあなたのサイト

(async () => {
  const browser = await chromium.launch({ headless: false, devtools: true });
  const context = await browser.newContext();
  const page = await context.newPage();

  // Altchaエンドポイントからの全ての応答を取得
  let challengeResp = null;
  page.on("response", async (response) => {
    try {
      const url = response.url();
      if (url.startsWith("https://captcha.example.com/altcha")) { // Altchaエンドポイント
        challengeResp = await response.json();
        console.log("Captured Altcha response:", challengeResp);
      }
    } catch (err) {
      console.warn("Error parsing Altcha response:", err);
    }
  });

  await page.goto(ALTCHA_PAGE, { waitUntil: "networkidle" });

  // ウィジェットがあればクリック
  const widgetHandle = await page.$("altcha-widget");
  if (widgetHandle) {
    try {
      await widgetHandle.click();
    } catch {}
  }

  // challengeの出現を待つ
  const start = Date.now();
  while (!challengeResp && Date.now() - start < 60000) { // タイムアウト延長
    await new Promise((r) => setTimeout(r, 300));
  }

  if (!challengeResp) {
    console.error("Failed to capture Altcha challenge.");
    await browser.close();
    return;
  }

  const { challenge, salt, signature, maxnumbers } = challengeResp;

  // CapMonster Cloudでタスク作成
  const createTaskBody = {
    clientKey: API_KEY,
    task: {
      type: "CustomTask",
      class: "altcha",
      websiteURL: ALTCHA_PAGE,
      websiteKey: "",
      userAgent:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36",
      metadata: {
        challenge,
        iterations: maxnumbers || 100000,
        salt,
        signature,
      },
    },
  };

  const taskResp = await fetch("https://api.capmonster.cloud/createTask", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(createTaskBody),
  }).then((r) => r.json());

  console.log("CreateTask response:", taskResp);
  if (!taskResp?.taskId) {
    console.error("CreateTask failed:", taskResp);
    await browser.close();
    return;
  }

  const taskId = taskResp.taskId;

  // 解決を取得
  let fullSolution = null;
  const pollStart = Date.now();
  while (Date.now() - pollStart < 120000) {
    const res = await fetch("https://api.capmonster.cloud/getTaskResult", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ clientKey: API_KEY, taskId }),
    }).then((r) => r.json());

    if (res.status === "ready") {
      fullSolution = res.solution;
      console.log("Solution:", fullSolution);
      break;
    }
    await new Promise((r) => setTimeout(r, 3000));
  }

  if (!fullSolution) {
    console.error("No solution received in time.");
    await browser.close();
    return;
  }

  const token = fullSolution?.data?.token || fullSolution?.token || fullSolution?.data;

  if (!token) {
    console.error("Token not found in solution:", fullSolution);
    await browser.close();
    return;
  }

  //トークンを挿入
  await page.evaluate((t) => {
    let input = document.querySelector("#captchaParaValidar");
    if (!input) {
      input = document.createElement("input");
      input.type = "hidden";
      input.id = "captchaParaValidar";
      input.name = "captchaParaValidar";
      (document.querySelector("form") || document.body).appendChild(input);
    }
    input.value = t;

    let alt = document.querySelector('input[name="altcha"]');
    if (!alt) {
      alt = document.createElement("input");
      alt.type = "hidden";
      alt.name = "altcha";
      (document.querySelector("form") || document.body).appendChild(alt);
    }
    alt.value = t;

    const widget = document.querySelector("altcha-widget");
    if (widget) {
      widget.setAttribute("data-state", "verified");
      const checkbox = widget.querySelector("input[type='checkbox']");
      if (checkbox) {
        checkbox.checked = true;
        checkbox.dispatchEvent(new Event("change", { bubbles: true }));
      }
      const label = widget.querySelector(".altcha-label");
      if (label) label.textContent = "Verified";
    }
  }, token);

  console.log("Token injected:", token);
})();
ALTCHAをサイトに接続する方法
サイト上でのキャプチャの動作、検証ロジックを理解し、再接続や再設定を行うには、このセクションを読むことを推奨します。保護統合のプロセスを説明しており、全ての詳細を迅速に理解するのに役立ちます。

1. ウィジェットのインストール

オプション1 — CDN経由(最も簡単)。HTMLの<head>に追加:

<script async defer src="https://cdn.jsdelivr.net/gh/altcha-org/altcha/dist/altcha.min.js" type="module"></script>

オプション2 — npm経由:

npm install altcha

JSファイルにウィジェットをインポート:

import "altcha";

2. フォームへのウィジェット追加。

保護が必要なフォームに<altcha-widget>コンポーネントを挿入:


<form method="POST" action="/submit">
  <altcha-widget challengeurl="/altcha/challenge"></altcha-widget>
  <button type="submit">Send</button>
</form>

challengeurl — チャレンジを発行するサーバーエンドポイント。

もしALTCHA Sentinel(ボットやスパム対策済みサーバー保護、機械学習とトラフィック解析)を使う場合は、自分のサーバーの代わりにそのURLを使用:


<altcha-widget 
  challengeurl="https://sentinel.example.com/v1/challenge?apiKey=YOUR_API_KEY">
</altcha-widget>

3. サーバー側検証。

検証の流れ:

  • 1) ウィジェットはpayloadを生成 — Base64エンコードされたJSON、通常フォームフィールドaltchaとして送信。
  • 2) サーバーでpayloadを暗号的に検証(追加APIリクエスト不要)。
  • 3) 検証成功後、フォームを処理可能。

ALTCHA Sentinelによる検証:

ライブラリ使用ライブラリ使用
arrow

Sentinel HTTP API経由(ライブラリ未利用時):Sentinel HTTP API経由(ライブラリ未利用時):
arrow

4. Sentinelなしで検証(独自サーバー)

チャレンジ生成:


import { createChallenge } from 'altcha-lib';

const hmacKey = '$ecret.key'; // あなたのHMAC秘密キー

const challenge = await createChallenge({ hmacKey });

// ウィジェット用にJSONでチャレンジを返す

フォーム送信時のpayload検証:


import { verifySolution } from 'altcha-lib';

const hmacKey = '$ecret.key'; // あなたのHMAC秘密キー

const verified = await verifySolution(payload, hmacKey);

if (verified) {
  // 検証成功 — フォームデータ処理
}

この場合、/altcha/challengeエンドポイントを自分で作成し、サーバーでチャレンジを検証。

Background
想定されるエラーとデバッグ
Bug Icon
challengeurlまたはAPI Keyが無効
ウィジェットが読み込まれないか、検証時にエラーが返されます。
Bug Icon
解決タイムアウト
サーバーがpayloadを検証する時間がありませんでした。待機時間を延長するか、サーバー側の検証が正しく動作していることを確認してください。
Bug Icon
空のpayload
ウィジェットからサーバーへの結果送信時のエラー。
Bug Icon
Verification failed
Payloadが期限切れ、再利用、または改ざんされています。診断のため、ログを有効にし、サーバーまたはSentinelからの応答でverifiedとverificationDataフィールドを確認してください。
保護の堅牢性チェック
統合後は、システムが本当に自動化された操作からサイトを守れているか確認しましょう。
セキュリティと最適化のヒント
<b>秘密鍵を保持</b>(Sentinel 用 HMAC または API Key)はサーバー上のみにしてください — フロントエンドには送信しないでください。
<b>エラー</b>や検証イベント (<b>verified: false</b> および <b>verificationData</b>) をログに記録して、失敗の原因を把握します。
透明性とユーザーの信頼のため、必要に応じて <b>プライバシーポリシー</b> および <b>ALTCHA 利用規約</b> へのリンクを追加してください。
まとめ

すでにキャプチャや別の保護システムが導入されているサイトを引き継いだものの、コードにはアクセスできない場合でも心配はいりません!どの技術が使われているかを特定するのはそれほど難しくありません。動作が正しいか確認するには、隔離されたテスト環境で認識サービスCapMonster Cloudを利用し、トークン処理の仕組みと検証ロジックが正しく機能しているかをチェックできます。

ALTCHAの場合も、システムを特定し、その挙動を調べて、保護機能が正しく動いていることを確認すれば十分です。この記事では、ALTCHAを見分ける方法と、その導入や再設定に関する手順書の見つけ方を紹介しました。これにより、防御を安心して維持し、その動作をしっかりと管理できます。

Conclusion
参考リンク
DocIconALTCHAドキュメントDocIconALTCHAソースコードDocIconCapMonster Cloudドキュメント(ALTCHA対応)