문의 폼 스팸 막기

문의 폼 스팸 막기5분 분량

Webflow 폼 스팸을 막는 방법

Webflow 자체 스팸 설정이 실행되지 않는, 폼 백엔드로 POST하는 Webflow 폼을 화면 밖 허니팟과 사람 확인으로 보호하세요.

Preet SutharIkiform 창업자

Webflow의 reCAPTCHA, 봇 차단, 스팸 필터는 Webflow가 직접 받는 제출에만 작동합니다. 폼이 커스텀 action으로 폼 백엔드에 POST한다면 이 설정들은 POST를 보지 못하므로, 보호는 백엔드에서 이루어져야 합니다. Designer에서 화면 밖 허니팟을 추가하고, 백엔드에서 도메인과 레이트 리밋을 설정하고, 일반 Webflow POST와 코드 없이 작동하는 백엔드의 사람 확인을 켜세요.

Webflow에서 다른 점

Webflow에는 자체 스팸 도구가 있습니다. reCAPTCHA v2, Cloudflare Turnstile을 실행하는 봇 차단 설정, 각 제출의 내용을 읽는 스팸 필터입니다. 모두 Webflow 쪽에 있으므로 Webflow에 도달하는 POST에만 작동합니다. 폼의 Send to를 커스텀 action으로 설정하는 순간 브라우저는 그 URL로 바로 POST합니다. Webflow는 제출을 보지 못하므로, 어떻게 설정되어 있든 어떤 검사도 실행되지 않습니다.

커스텀 action이 있을 때와 없을 때 Webflow 폼의 스팸 검사가 실행되는 곳Webflow가 폼을 처리Ikiform으로 커스텀 actionWebflow 폼WebflowreCAPTCHA, 봇차단, 스팸 필터Webflow 제출Webflow 폼같은 Designer 폼Webflow의 검사POST를 보지 못함Ikiform허니팟, 점수, 제한, 확인받음 또는 스팸커스텀 action이 있을 때와 없을 때 Webflow 폼의 스팸 검사가 실행되는 곳Webflow가 폼을 처리Ikiform으로 커스텀 actionWebflow 폼WebflowreCAPTCHA, 봇 차단, 스팸 필터Webflow 제출Webflow 폼같은 Designer 폼Webflow의 검사POST를 보지 못함Ikiform허니팟, 점수, 제한, 확인받음 또는 스팸
  1. Webflow가 폼을 처리하면 POST는 Webflow로 가고, Webflow가 저장하기 전에 reCAPTCHA, 봇 차단, 스팸 필터를 실행합니다.
  2. 커스텀 action이 있으면 브라우저가 같은 폼을 Ikiform으로 바로 POST합니다.
  3. Webflow의 검사는 설정과 관계없이 그 POST를 보지 못합니다.
  4. Ikiform이 허니팟, 점수, 레이트 리밋, 사람 확인을 실행한 뒤 POST를 받음 또는 스팸으로 저장합니다.
폼을 커스텀 action으로 옮기면 스팸 방지도 함께 옮겨집니다. 같은 날 백엔드에서 설정하세요.

전환 후 Webflow 자체 설정

Webflow 설정커스텀 action을 쓸 때해결 방법
reCAPTCHA 요소와 검증아무도 검증하지 않음. g-recaptcha-response 값이 추가 필드로 도착요소를 지우세요. 이 설정은 사이트의 모든 폼에 적용되므로, Webflow가 아직 처리하는 폼 중 필요한 것이 없을 때만 reCAPTCHA 검증을 끄세요
봇 차단다른 곳으로 가는 POST에는 적용되지 않음Webflow가 아직 처리하는 폼을 위해 그대로 두세요
스팸 필터링적용되지 않음대신 백엔드의 콘텐츠 점수를 쓰세요
폼 제출 한도와 알림적용되지 않음대신 백엔드가 저장하고 이메일을 보냄

문서의 Webflow 가이드에서 Form Block을 Ikiform으로 연결하는 방법을 다룹니다. 아래 단계는 그 위에 스팸 방지를 더합니다.

Designer에서 허니팟 추가하기

Webflow에서 입력을 빠르게 숨기는 방법은 Display: none입니다. 일부 봇은 그렇게 숨긴 필드를 건너뛰므로, 대신 함정을 화면 밖 래퍼에 넣으세요. 1분이면 되고 유료 플랜도 필요 없습니다.

  • 폼 안에 Div Block을 추가하고 hp 같은 클래스를 주세요. Style 패널에서 Position을 Absolute로, Left를 -10000px로, Width와 Height를 1px로, Overflow를 Hidden으로 설정하세요.
  • Div Block의 Custom attributes에 aria-hidden을 true로 추가해, 스크린 리더가 안의 모든 것을 건너뛰게 하세요.
  • Div Block 안에 Leave this empty라는 텍스트의 Label과 Input을 넣으세요. Input의 Name을 _gotcha로 설정하고, 커스텀 속성 tabindex = -1과 autocomplete = off를 추가하세요.
  • 여기에 Required를 체크하지 마세요. 아무도 볼 수 없는 필수 필드는 모든 정상 제출을 막습니다.

_gotcha가 채워지면 Ikiform 스팸 점수에 5가 더해지며, 이것만으로 기준값 5에 도달합니다. 사용하는 템플릿에 이미 다른 이름의 함정이 있다면 Honeypot field에서 폼마다 필드 이름을 바꿀 수 있습니다.

점수 매기기를 위한 필드 이름 짓기

Webflow는 각 입력의 이름을 레이블에서 따오므로 Name, Email, Field 2가 됩니다. 각 입력의 설정에서 name, email, message로 이름을 바꾸세요. 이름은 데이터뿐 아니라 스팸 점수에도 중요합니다.

  • name, first_name, subject 같은 이름 필드에 링크가 있으면 3이 더해집니다. 스패머는 흔히 거기에 URL을 넣지만, 실제 사람은 그러지 않습니다.
  • 일회용 이메일 도메인의 주소는 2가 더해지며, 이메일 주소가 담긴 모든 필드에서 읽습니다.
  • 폼 전체에 링크가 3개 이상이면 2, 알려진 스팸 문구가 있으면 2가 더해집니다.

사람 확인 켜기

Ikiform 폼 설정에서 Spam check를 Ikiform으로 설정하세요. Webflow에서는 아무것도 바뀌지 않습니다. 폼이 평소 방식으로 POST되면 Ikiform은 ikiform.com의 짧은 Checking you're human 페이지로 응답해 Cloudflare Turnstile을 실행하고 필드를 이어서 보내며, 방문자는 Redirect after submit 페이지에 도착합니다. Cloudflare 계정, 키, 커스텀 코드가 필요 없습니다.

Webflow의 성공 및 오류 블록을 유지하려고 문서의 스크립트를 추가했다면, 그 스크립트는 fetch로 POST하며 토큰 없는 fetch POST는 403 challenge_required를 받습니다. 이 버전은 이를 처리합니다. 사람 확인을 위해 일반 POST로 돌아가고, 방문자가 레이트 리밋에 걸리면 대기 시간을 보여 줍니다.

Before </body> tag
<script>
  document.querySelectorAll('form[action^="https://ikiform.com/f/"]').forEach((form) => {
    const wrapper = form.closest(".w-form");
    const done = wrapper?.querySelector(".w-form-done");
    const fail = wrapper?.querySelector(".w-form-fail");
    const button = form.querySelector('[type="submit"]');

    function showError(text) {
      const slot = fail?.querySelector("div") ?? fail;
      if (slot) slot.textContent = text;
      if (fail) fail.style.display = "block";
    }

    form.addEventListener("submit", async (event) => {
      event.preventDefault();
      const label = button?.value;
      if (button) {
        button.disabled = true;
        button.value = button.dataset.wait || label;
      }
      try {
        const response = await fetch(form.action, {
          method: "POST",
          headers: { Accept: "application/json" },
          body: new FormData(form),
        });
        const result = await response.json();
        if (result.ok) {
          form.style.display = "none";
          if (fail) fail.style.display = "none";
          if (done) done.style.display = "block";
          return;
        }
        if (result.error.code === "challenge_required") {
          form.submit();
          return;
        }
        showError(
          response.headers.has("Retry-After")
            ? `Too many messages. Try again in ${response.headers.get("Retry-After")} seconds.`
            : result.error.message,
        );
      } catch {
        form.submit();
      } finally {
        if (button) {
          button.disabled = false;
          button.value = label;
        }
      }
    });
  });
</script>
  • form.submit()은 submit 이벤트를 발생시키지 않고 폼을 POST하므로, 폴백이 스크립트로 다시 돌아오지 않습니다.
  • Page settings > Custom code > Before </body> tag에 붙여 넣거나, 모든 폼에 적용하려면 사이트의 푸터 코드에 넣으세요. 커스텀 코드는 유료 사이트 플랜이 필요하며 게시된 사이트에서만 실행됩니다.
  • action이 https://ikiform.com/f/로 시작하는 폼만 건드리므로, Webflow가 아직 처리하는 폼은 그대로 둡니다.

허용 도메인과 레이트 리밋

Ikiform 폼의 Allowed domains에 커스텀 도메인과 your-site.webflow.io 같은 스테이징 주소를 추가하세요. webflow.io만 단독으로 추가하지 마세요. 다른 사람의 사이트를 포함해 모든 Webflow 사이트가 일치하게 됩니다. 다른 곳에서 온 POST는 스팸으로 저장되거나, Reject를 고르면 거부됩니다.

문의 폼이라면 Rate limit을 방문자당 10분에 2건인 Strict로 설정하세요. 정직한 사람은 10분 안에 두 번 쓰지 않습니다. 붐비는 출시일의 가입 폼에는 방문자당 분당 20건인 Relaxed가 더 어울립니다. 모든 폼은 분당 5건인 Standard로 시작합니다.

스팸으로 판정된 POST는 실제 제출과 같은 성공 응답을 받으므로 봇은 아무것도 알 수 없습니다. spam 상태로 저장되고, 알림 이메일과 웹훅을 보내지 않으며, 사용량에 포함되지 않고, 30일 뒤 삭제됩니다. 스팸을 차단한 워크스페이스에는 매주 월요일 합계, 가장 많이 받은 폼, 주요 사유를 담은 요약 이메일이 한 통 갑니다.

작동 확인하기

  1. webflow.io 스테이징 도메인에 게시하세요. 커스텀 action은 게시된 사이트에서만 POST합니다.
  2. 폼을 평소처럼 제출하세요. 사람 확인이 켜져 있으면 확인 페이지가 잠깐 보인 뒤 감사 페이지로 이동합니다.
  3. 게시된 폼을 검사해 허니팟 래퍼에 aria-hidden이 있고 화면 밖에 있는지 확인하세요.
  4. 허니팟을 채워 _gotcha=bot으로 POST하세요. 여전히 성공 응답을 받지만, 제출은 스팸으로 저장되고 이메일이나 웹훅을 보내지 않습니다.
  5. 대시보드에서 Submissions를 여세요. 보낸 모든 필드가 담긴 새 제출이 있습니다.
  6. 아무것도 도착하지 않았나요? 대시보드의 상태 필터를 Spam으로 바꿔 보세요. 스팸은 실제 제출과 같은 성공 응답을 받습니다.

주의할 점

  • Webflow 설정을 켰는데도 스팸이 옴. Webflow 도구를 켠 뒤에도 스팸이 계속 온다면 폼의 Send to를 확인하세요. 커스텀 action은 이 도구들을 모두 우회합니다.
  • 남아 있는 reCAPTCHA. Ikiform 폼에 필드를 정의했다면 남은 g-recaptcha-response는 알 수 없는 필드로 422 validation_failed 오류가 납니다. 요소를 지우세요.
  • 복제된 폼. 폼을 복사하면 허니팟 입력은 복사되지만 커스텀 속성은 항상 복사되지는 않습니다. 각 사본에서 tabindex와 aria-hidden을 확인하세요.
  • 래퍼에 걸린 인터랙션. 폼의 모든 Div Block에 애니메이션을 주는 Webflow 인터랙션은 허니팟을 화면 안으로 옮길 수 있습니다. 해당 클래스를 제외하세요.

질문

막히는 단계가 있거나 내 상황에 맞는 가이드가 필요하다면 이메일을 보내세요: hello@ikiform.com.