M

일회용 이메일 원천적으로 차단하기 (250725 11:23 수정)

· 2025-07-25 (금) 08:55:22 · 3618 · 9

(250725 10:11 수정) 코어 파일 수정에서 extend + 훅 사용으로 변경

(250725 11:23 수정) /bbs/ajax.disposable_email.php 코드 개선 (중복 함수 제거)

 

 

사실 원천적으로 100% 완벽하게 차단하지 못할 수 있으나 두 가지의 방법을 동시에 실행하여 꾸준히 나오는 일회용 이메일들도 어느정도 막을 수 있어 98% 정도는 막을 수 있다고 생각합니다

 

 

※ 주의

http 환경에서는 2순위 API가 작동하지 않을 수 있습니다 (로컬호스트는 가능 확인함)

 

첨부파일에 일회용 블랙 도메인을 모아둔 내용들 첨부해놨으니 http 환경이신 분들은

2순위 API 대신 1순위로 사용하셔야 합니다 (우선 아래 방법대로 테스트 먼저 해보세요)

 

첨부파일 1 설명 : domains.txt

https://raw.githubusercontent.com/disposable/disposable-email-domains/master/domains.txt

현재 1순위로 쓰고 있는 블랙 도메인 (약 5,000 ~ 6,000개)

20 여개의 일회용 이메일 서비스들을 자동으로 크롤링 중 (새로 생긴 일회용 이메일들 빠르게 탐지)

24시간마다 자동으로 새로운 도메인 추가/제거

대신 자동 크롤링이라 오탐 확률 조금 있을 수 있습니다!!

 

첨부파일 2 설명 : disposable_email_blocklist.conf

https://raw.githubusercontent.com/disposable-email-domains/disposable-email-domains/main/disposable_email_blocklist.conf

약 4,500개 / 커뮤니티에서 확실하게 검증된 블랙 도메인 (갯수는 조금 적지만 오탐 될 확률 적어요)

 

첨부파일 3 설명 : denyDomains.txt

https://raw.githubusercontent.com/amieiro/disposable-email-domains/master/denyDomains.txt

블랙 도메인 데이터들 15분마다 자동 업데이트 됨

 

 

==================================================

 

 

코어 파일 수정 없이 적용하기

 

1. /js/jquery.disposable_check.js 파일 생성

생성한 js 파일에 아래 코드 붙여넣기

 

[code]

// 일회용 이메일 전용 검증 함수

var reg_mb_disposable_check = function () {

  var result = '';

  $.ajax({

    type: 'POST',

    url: g5_bbs_url + '/ajax.disposable_email.php',

    data: {

      reg_mb_email: $('#reg_mb_email').val(),

    },

    cache: false,

    async: false,

    success: function (data) {

      result = data;

    },

  });

  return result;

};

[/code]

 

 

2. /bbs/ajax.disposable_email.php 파일 생성

클라이언트 검증 (선택사항)

생성한 php 파일에 아래 코드 붙여넣기

 

[code]

<?php
include_once('./_common.php');
 
if (!isset($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') {
  exit;
}
 
$mb_email = isset($_POST['reg_mb_email']) ? trim($_POST['reg_mb_email']) : '';
 
if (!$mb_email) {
  exit;
}

// 일회용 이메일 검증 실행
if ($msg = disposable_mb_email_server($mb_email)) {
  die($msg);
}

[/code]

 

 

3. /extend/disposable_email_check.php 파일 생성

서버 검증 (필수)

생성한 php 파일에 아래 코드 붙여넣기

 

[code]

<?php

if (!defined('_GNUBOARD_')) exit;

 

// 일회용 이메일 검사 함수

function disposable_mb_email_server($reg_mb_email)

{

  $domain = strtolower(substr(strrchr($reg_mb_email, "@"), 1));

 

  // 1순위: GitHub 리스트

  $fast_context = stream_context_create([

    'http' => [

      'timeout' => 1,

      'ignore_errors' => true

    ]

  ]);

 

  $github_url = "https://raw.githubusercontent.com/disposable/disposable-email-domains/master/domains.txt";

  $github_response = @file_get_contents($github_url, false, $fast_context);

 

  if ($github_response !== false) {

    $github_domains = array_filter(array_map('trim', explode("\n", $github_response)));

    if (in_array($domain, $github_domains)) {

      return "일회용 이메일은 사용할 수 없습니다.";

    }

  }

 

  // 2순위: API

  $normal_context = stream_context_create([

    'http' => [

      'timeout' => 3,

      'ignore_errors' => true

    ]

  ]);

 

  $api_url = "https://disposable.debounce.io/?email=" . urlencode($domain);

  $response = @file_get_contents($api_url, false, $normal_context);

 

  if ($response !== false) {

    $data = json_decode($response, true);

    if (isset($data['disposable']) && $data['disposable'] === "true") {

      return "일회용 이메일은 사용할 수 없습니다.";

    }

  }

 

  return "";

}

 

// hook 연결

add_event('register_form_update_valid', 'check_disposable_email_server', 10, 4);

 

function check_disposable_email_server($w, $mb_id, $mb_nick, $mb_email)

{

  if ($msg = disposable_mb_email_server($mb_email)) {

    alert($msg, "", true, true);

  }

}

[/code]

 

 

4. /skin/member/basic/register_form.skin.php 수정

사이트 일반 로그인 기준 스킨 파일

add_javascript('<script src="'.G5_JS_URL.'/jquery.register_form.js"></script>', 0);

기존 스크립트 아래에 추가

 

[code]

add_javascript('<script src="'.G5_JS_URL.'/jquery.disposable_check.js"></script>', 0);

[/code]

 

 

기존 E-mail 검사 스크립트 조건문 안에 추가

 

[code]

    // 이메일 검증 (기존 코드)

    if ((f.w.value == "") || (f.w.value == "u" && f.mb_email.defaultValue != f.mb_email.value)) {

      var msg = reg_mb_email_check();

      if (msg) {

        alert(msg);

        f.reg_mb_email.select();

        return false;

      }

    }

 

// ==================================================

 

    // 기존 코드를 이렇게 수정

    if ((f.w.value == "") || (f.w.value == "u" && f.mb_email.defaultValue != f.mb_email.value)) {

      var msg = reg_mb_email_check();

      if (msg) {

        alert(msg);

        f.reg_mb_email.select();

        return false;

      }

 

      // 일회용 이메일 검사

      var disposable_msg = reg_mb_disposable_check();

      if (disposable_msg) {

        alert(disposable_msg);

        f.reg_mb_email.select();

        return false;

      }

    }

[/code]

 

 

5. /skin/social/social_register_member.skin.php 수정

소셜 로그인 기준 스킨 파일 (사용 시)

위 4번 항목과 똑같은 방법으로 진행

 

 

 

 

 

============================================================

 

 

 

 

 

아래는 코어 파일 수정해서 적용하는 방법입니다

웬만하면 위의 방법으로 적용하셔서

그누보드 업데이트 편하게 할 수 있도록 대비하세요!!

 

(코어 파일 수정해서 적용하는 방법은 나중에 지울게요

혹시나 이 방법으로 적용한 분 계시다면 내용 보고 되돌리셔서 위 방법으로

다시 작업하시길 권장드립니다)

 

 

1. /lib/register.lib.php

function exist_mb_email($reg_mb_email, $reg_mb_id) 함수 아래에 추가

 

[code]

// 일회용 이메일 검사

function disposable_mb_email($reg_mb_email)

{

  $domain = strtolower(substr(strrchr($reg_mb_email, "@"), 1));

 

  // 1순위: GitHub 리스트

  $fast_context = stream_context_create([

    'http' => [

      'timeout' => 1,

      'ignore_errors' => true

    ]

  ]);

 

  $github_url = "https://raw.githubusercontent.com/disposable/disposable-email-domains/master/domains.txt";

  $github_response = @file_get_contents($github_url, false, $fast_context);

 

  if ($github_response !== false) {

    $github_domains = array_filter(array_map('trim', explode("\n", $github_response)));

    if (in_array($domain, $github_domains)) {

      return "일회용 이메일은 사용할 수 없습니다.";

    }

  }

 

  // 2순위: API (3초)

  $normal_context = stream_context_create([

    'http' => [

      'timeout' => 3,

      'ignore_errors' => true

    ]

  ]);

 

  $api_url = "https://disposable.debounce.io/?email=" . urlencode($domain);

  $response = @file_get_contents($api_url, false, $normal_context);

 

  if ($response !== false) {

    $data = json_decode($response, true);

    if (isset($data['disposable']) && $data['disposable'] === "true") {

      return "일회용 이메일은 사용할 수 없습니다.";

    }

  }

 

  return "";

}

[/code]

 

 

2. /bbs/ajax.mb_email.php

if ($msg = exist_mb_email($mb_email, $mb_id)) die($msg); 아래에 추가

 

[code]

if ($msg = disposable_mb_email($mb_email)) die($msg);

[/code]

 

 

3. /bbs/register_form_update.php

// 이름에 한글명 체크를 하지 않는다.

//if ($msg = valid_mb_name($mb_name))     alert($msg, "", true, true);

if ($msg = valid_mb_nick($mb_nick))     alert($msg, "", true, true);

if ($msg = valid_mb_email($mb_email))   alert($msg, "", true, true);

if ($msg = prohibit_mb_email($mb_email)) alert($msg, "", true, true);

아래에 추가

 

[code]

if ($msg = disposable_mb_email($mb_email)) alert($msg, "", true, true);

[/code]

 

 

코어 파일을 기준으로 수정하신다면,

회원가입 페이지의 상단 PHP에

[code]

add_javascript('<script src="' . G5_JS_URL . '/jquery.register_form.js"></script>', 14);

[/code]

스크립트가 추가되어 있어야 하며,

회원가입 페이지의 스크립트에

[code]

    // 이메일 검증

    if ((f.w.value == "") || (f.w.value == "u" && f.mb_email.defaultValue != f.mb_email.value)) {

      var msg = reg_mb_email_check();

      if (msg) {

        alert(msg);

        f.reg_mb_email.select();

        return false;

      }

    }

[/code]

이메일 검증 코드가 추가 되어 있어야 정상 작동합니다

 

 

==================================================

 

 

 

테스트 결과 1순위는 약 0.3~0.5초, 2순위는 약 1~2초 정도 로딩이 걸립니다

 

1순위에서 일회용 이메일 찾으면 바로 return, 찾지 못하면 2순위로 가서

최대 4초 (모두 검증 안될 시) 걸립니다

 

두 군데 모두 일회용 이메일이 일치하지 않으면 그대로 검증 통과해버리고

타임아웃은 사용자 경험에서 느리면 느릴수록 좋지 않아 테스트 해보시고 조절하시길 권장드립니다

 

첨부파일

domains.txt (1 MB) 5회 2025-07-25 11:19
denyDomains.txt (2.8 MB) 0회 2025-07-25 11:19
|

댓글 9개

2025-07-25 (금) 09:07:04

감사합니다 ^^

이 플러그인은 코어 수정이 없는데 기능면에서 차이가 있는지 궁금합니다.
https://sir.kr/g5_plugin/6565

@WEBOLUTION 

기능적인 면에서 차이가 큽니다. 해당 플러그인은 이미 저장되어 있는 하드 코딩된 블랙 도메인 데이터들로만 읽네요. 제 게시글의 맨 위 첫번째 방법으로 하시면 코어 수정 없이 적용 가능합니다

2025-07-27 (일) 20:20:12

플러그인을 보니 git에서 메일 데이터파일만 교체하면 끝나는것 같네요.
필요한 용도대로 사용하면 됩니다. 어차피 임시메일은 mxtool 돌려서 체크하면 되는걸 굳이 저렇게 코드들을 설치하거나 수정하거나 할 필요가 있나 싶군요.

외국 사이트 접속시 템포러리메일이라고 애네들은 그게 활성화되어 있더군요. 이런걸 막는 방법이 있다니 역시 창과 방패의 싸움인거 같네요. IT 분야는..

@techstar 더 강력한 유료 API도 있지만 웬만해선 이걸로도 충분하다고 봅니다

좋은정보 감사합니다.

좋은 팁 감사합니다~

감사합니다.

댓글을 작성하시려면 로그인이 필요합니다.

그누보드5 팁자료실

2,788건
+
제목 글쓴이 날짜 조회
25-09-03 조회 3,424
25-09-02 조회 3,410
25-09-02 조회 3,247
25-08-29 조회 3,177
25-08-29 조회 3,083
25-08-26 조회 3,635
25-08-18 조회 3,404
25-08-16 조회 3,253
25-08-07 조회 3,390
25-08-05 조회 4,228
25-08-02 조회 3,375
25-07-28 조회 3,403
25-07-27 조회 3,692
25-07-25 조회 3,619
25-07-21 조회 3,159
25-07-19 조회 3,142
25-07-15 조회 4,467
25-07-14 조회 3,358
25-07-09 조회 3,172
25-07-07 조회 3,333
25-07-06 조회 3,369
25-07-06 조회 3,193
25-07-04 조회 2,979
25-06-30 조회 3,434
25-06-27 조회 3,159
25-06-27 조회 3,401
25-06-26 조회 3,183
25-06-26 조회 3,329
25-06-25 조회 3,314
25-06-24 조회 3,220