CAPTCHA의 탐색적 테스트

리뷰 앱 및 로컬 개발 환경(GDK)에서 CAPTCHA를 신뢰할 수 있게 테스트할 수 있습니다. 항상 다음을 할 수 있습니다:

  • 지원하는 곳에서 reCAPTCHA가 나타나도록 강제로 표시합니다.
  • 길거리 표지 이미지 대신 확인란을 표시하도록 강제로 합니다.

테스트를 설정하려면 이 페이지의 구성을 따르세요.

적절한 테스트 데이터 사용

스팸/CAPTCHA가 활성화된 시나리오를 테스트하는지 확인하세요. 예를 들어: 공개 스니펫을 편집하는지 확인하십시오. 공개 스니펫만이 스팸을 확인합니다.

피처 플래그 활성화

스팸/CAPTCHA 지원이 피처 플래그 뒤에 숨겨져 있는 경우 해당하는 피처 플래그를 활성화하세요.

Akismet 및 reCAPTCHA 설정

  1. reCAPTCHA 설정:
    1. GitLab reCAPTCHA 문서를 검토합니다.
    2. Google의 reCAPTCHA 문서의 지침을 사용하여 Google의 공식 테스트 reCAPTCHA 자격 증명을 가져옵니다.
      1. 사이트 키로 다음을 사용하세요: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
      2. 비밀 키로 다음을 사용하세요: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
    3. Admin -> Settings -> Reporting 설정으로 이동: http://gdk.test:3000/admin/application_settings/reporting#js-spam-settings
    4. 스팸 및 안티봇 보호 섹션을 확장하십시오.
    5. reCAPTCHA 사용을 선택합니다. 로그인을 위해 활성화할 필요는 없습니다(테스트하는 경우에만 필요).
    6. 사이트 키비밀 키를 입력합니다.
  2. Akismet 설정:
    1. GitLab Akismet 문서를 검토합니다.
    2. Akismet API 키를 가져옵니다. Akismet에서 테스트 키에 등록할 수 있습니다. 등록 시 로컬 호스트(예: gdk.test) 및 이메일을 입력해야 합니다.
    3. 예를 들어 다음과 같은 GitLab Akismet 설정 페이지로 이동합니다: http://gdk.test:3000/admin/application_settings/reporting#js-spam-settings
    4. Akismet을 활성화하고 Akismet API 키를 입력합니다.
  3. Akismet의 거짓 긍정 스팸 확인을 강제로 실행하려면 Akismet API 문서Akismet 시작 안내 문서를 참조하여 자세한 내용을 확인하세요:
    1. 다음 단계를 사용하여 다음을 이메일 작성자 이메일로 스팸을 강제로 실행할 수 있습니다: akismet-guaranteed-spam@example.com
      1. 사용자 이메일 설정에서 다음으로 이동합니다: http://gdk.test:3000/-/profile/emails
      2. akismet-guaranteed-spam@example.com을 관리자 사용자의 보조 이메일로 추가합니다.
      3. Rails 콘솔에서 확인합니다: bin/rails c -> User.find_by_username('root').emails.last.confirm
      4. 이 확인된 이메일을 당신의 기본 이메일로 전환합니다:
        1. 아바타 드롭다운 디렉터리 -> 프로필 편집 -> 기본 설정으로 이동합니다.
        2. 이메일을 변경하여 admin@example.com을 대체하기 위해 akismet-guaranteed-spam@example.com을 입력합니다.
        3. 변경 사항을 저장하려면 프로필 설정 업데이트을 선택합니다.

웹 UI에서 테스트

위의 모든 구성을 마쳤으면 CAPTCHA를 테스트할 수 있습니다. 스팸을 확인하는 애플리케이션 영역에서 테스트할 수 있습니다. 예를 들어:

  • 이슈를 생성하거나 편집합니다.
  • 공개 스니펫을 생성하거나 편집합니다. 스팸 확인은 공개 스니펫에만 적용됩니다.

개발 환경에서 테스트

위의 단계를 사용하여 스팸 플래깅 + CAPTCHA를 강제로 설정한 후 스팸 방지가 적용된 모델/컨트롤러 작업을 테스트할 수 있습니다.

CAPTCHA 활성화 (CONDITIONAL_ALLOW 판결)인 경우 테스트

이러한 영역에서 CAPTCHA가 활성화된 경우 양식을 다시 제출하기 전에 CAPTCHA 팝업 모달을 해결해야 합니다:

  • Admin -> Settings -> Reporting -> Spam
  • 안티-봇 보호 -> reCAPTCHA 활성화

CAPTCHA 비활성화 시 테스트 (“DISALLOW” 판결)

Admin -> Settings -> Reporting -> Spam안티-봇 보호 -> reCAPTCHA 활성화에서 CAPTCHA가 비활성화된 경우 CAPTCHA 팝업이 나타나지 않습니다. 양식 제출을 위해 방지됩니다.

reCAPTCHA 렌더링을 위한 HTML 페이지

note
Set up Akisment and reCAPTCHA에 나열된 Google의 공식 테스트 reCAPTCHA 자격 증명을 사용하는 경우, CAPTCHA 응답 문자열은 중요하지 않습니다. 어떤 문자열이든 상관없습니다. 실제 유효한 키 쌍을 사용하는 경우 유효한 CAPTCHA 응답을 얻으려면 CAPTCHA를 해결해야 합니다. 이 작업은 한 번만 하면 되며 만료되기 전에만 할 수 있습니다.

GraphQL 탐색기를 통해 직접 GraphQL API를 테스트하려면 (http://gdk.test:3000/-/graphql-explorer), 이 양식을 통해 reCAPTCHA 응답 문자열을 가져올 수 있습니다: public/recaptcha.html (http://gdk.test:3000/recaptcha.html):

<html>
<head>
  <title>reCAPTCHA demo: Explicit render after an onload callback</title>
  <script type="text/javascript">
  var onloadCallback = function() {
    grecaptcha.render('html_element', {
      'sitekey' : '6Ld05AsaAAAAAMsm1yTUp4qsdFARN15rQJPPqv6i'
    });
  };
  function onSubmit() {
    window.document.getElementById('recaptchaResponse').innerHTML = grecaptcha.getResponse();
    return false;
  }
  </script>
</head>
<body>
<form onsubmit="return onSubmit()">
  <div id="html_element"></div>
  <br>
  <input type="submit" value="Submit">
</form>
<div>
  <h1>recaptchaResponse:</h1>
  <div id="recaptchaResponse"></div>
</div>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
        async defer>
</script>
</body>
</html>

스팸/CAPTCHA API 탐색적 테스트 예시

이러한 섹션은 REST 및 GraphQL API에 대한 스팸 및 CAPTCHA 동작의 다양한 시나리오를 매뉴얼으로 탐색적으로 테스트하기 위해 필요한 단계를 설명합니다.

이전에 나열된 모든 단계를 수행하여 개발 환경에서 스팸 및 CAPTCHA를 활성화하고, 양식 제출을 강제로 CAPTCHA가 필요하게 만들어야 합니다.
또한 /public 디렉터리 아래에 CAPTCHA를 렌더링하는 HTML 페이지를 생성했는지 확인하고, 올바른 CAPTCHA 응답 문자열을 매뉴얼으로 생성하는 양식이 포함된 페이지를 만들어야 합니다.
Set up Akismet and reCAPTCHA에 나열된 Google의 공식 테스트 reCAPTCHA 자격 증명을 사용하는 경우, CAPTCHA 응답 문자열의 내용은 중요하지 않습니다.
그리고 관리자 -> 설정 -> 보고 -> 스팸 및 방지로 이동해야 합니다.
시나리오의 요구에 따라 reCAPTCHA 활성화Akismet 활성화를 선택하거나 지워야 합니다.

다음 예시는 코드 스니펫 생성을 사용하고 있습니다. 코드 스니펫 업데이트, 이슈 생성 또는 이슈 업데이트도 사용할 수 있습니다. 이슈와 코드 스니펫은 완전한 스팸 및 CAPTCHA 지원을 제공하는 유일한 모델입니다.

초기 설정

  1. API 토큰을 생성합니다.
  2. REST 명령에 API 토큰을 내보내려면 터미널에 export PRIVATE_TOKEN=<당신의_api_토큰>을 입력합니다.
  3. GraphQL 쿼리를 실행하기 전에 localhost:3000의 GitLab 개발 환경에 로그인되어 있는지 확인합니다.
    그리고 GraphiQL 탐색기를 사용하기 전에 인증된 사용자를 사용하여 GraphQL 쿼리를 실행할 수 있도록 권한을 부여합니다.
  4. GraphQL 예시에서는 http://localhost:3000/-/graphql-explorer의 GraphiQL 탐색기를 사용합니다.
  5. HTTP 응답 헤더, 상태 코드를 포함하려면 curl에서 --include(-i) 옵션을 사용합니다.

시나리오: Akismet 및 CAPTCHA 활성화

이 예시에서는 Akismet 및 CAPTCHA가 활성화되어 있습니다:

  1. 초기 요청.

초기 요청

이 초기 요청은 CAPTCHA 응답이 제공되지 않아 실패합니다.

REST 요청:

curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "http://localhost:3000/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"

REST 응답:

{"needs_captcha_response":true,"spam_log_id":42,"captcha_site_key":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","message":{"error":"Your snippet has been recognized as spam. Please, change the content or solve the reCAPTCHA to proceed."}}

GraphQL 요청:

mutation {
    createSnippet(input: {
        title: "Title"
        visibilityLevel: public
        blobActions: [
            {
                action: create
                filePath: "BlobPath"
                content: "BlobContent"
            }
        ]
    }) {
        snippet {
            id
            title
        }
        errors
    }
}

GraphQL 응답:

{
  "data": {
    "createSnippet": null
  },
  "errors": [
    {
      "message": "Request denied. Solve CAPTCHA challenge and retry",
      "locations": [
        {
          "line": 22,
          "column": 5
        }
      ],
      "path": [
        "createSnippet"
      ],
      "extensions": {
        "needs_captcha_response": true,
        "spam_log_id": 140,
        "captcha_site_key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
      }
    }
  ]
}

두 번째 요청

이 요청은 CAPTCHA 응답이 제공되어 성공합니다.

REST 요청:

export CAPTCHA_RESPONSE="<CAPTCHA response obtained from HTML page to render CAPTCHA>"
export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>"
curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" "http://localhost:3000/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"

REST 응답:

{"id":42,"title":"Title","description":null,"visibility":"public", "other_fields": "..."}

GraphQL 요청:

note
GitLab GraphiQL 구현은 헤더를 전달하는 것을 허용하지 않으므로 이를 curl 쿼리로 작성해야 합니다. 여기에서는 JSON 내장 쿼리에 이스케이프된 이중 인용부호를 올바르게 처리하기 위해 --data-binary를 사용합니다.
export CAPTCHA_RESPONSE="<CAPTCHA response obtained from HTML page to render CAPTCHA>"
export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>"
curl --include "http://localhost:3000/api/graphql" --header "Authorization: Bearer $PRIVATE_TOKEN" --header "Content-Type: application/json" --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" --request POST --data-binary '{"query": "mutation {createSnippet(input: {title: \"Title\" visibilityLevel: public blobActions: [ { action: create filePath: \"BlobPath\" content: \"BlobContent\" } ] }) { snippet { id title } errors }}"}'

GraphQL 응답:

{"data":{"createSnippet":{"snippet":{"id":"gid://gitlab/PersonalSnippet/42","title":"Title"},"errors":[]}}}

시나리오: Akismet 활성화, CAPTCHA 비활성화

이 시나리오에서는 관리자 영역 설정에서 Enable reCAPTCHA를 지워 CAPTCHA가 비활성화되었는지 확인합니다.
CAPTCHA가 활성화되지 않은 경우, CAPTCHA가 성공적으로 해결되었을 경우 다시 제출할 수 있는 잠재적인 스팸으로 플래그 지정된 요청이 실패하며, 그렇지 않은 경우라도 재제출할 수 없습니다.

REST 요청은 CAPTCHA가 활성화된 경우와 동일합니다:

curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "http://localhost:3000/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"

REST 응답:

{"message":{"error":"Your snippet has been recognized as spam and has been discarded."}}

GraphQL 요청:

mutation {
    createSnippet(input: {
        title: "Title"
        visibilityLevel: public
        blobActions: [
            {
                action: create
                filePath: "BlobPath"
                content: "BlobContent"
            }
        ]
    }) {
        snippet {
            id
            title
        }
        errors
    }
}

GraphQL 응답:

{
  "data": {
    "createSnippet": null
  },
  "errors": [
    {
      "message": "Request denied. Spam detected",
      "locations": [
        {
          "line": 22,
          "column": 5
        }
      ],
      "path": [
        "createSnippet"
      ],
      "extensions": {
        "spam": true
      }
    }
  ]
}

시나리오: allow_possible_spam 애플리케이션 설정 활성화

allow_possible_spam 애플리케이션 설정을 활성화하면 API는 200 응답을 반환합니다. 모든 유효한 요청은 성공하며, 요청이 스팸으로 간주되더라도 CAPTCHA가 제시되지 않습니다.