4P by GN⁺ | ★ favorite | 댓글 1개
  • 공개 이메일 주소를 스팸봇 수집에서 숨기면서도 방문자가 바로 연락할 수 있게, SVG 내부에 이메일 텍스트와 mailto: 링크를 넣는 방식임
  • JavaScript 기반 보호는 더 정교할 수 있지만, 연락 기능 자체가 JS 의존성을 갖는다는 점이 부담이 됨
  • 이 접근은 외부 SVG 문서를 HTML의 <object>로 삽입하고, 실제 링크는 HTML이 아니라 SVG 안의 <a> 요소에 둠
  • SVG는 이미지처럼 내용을 감추는 효과가 있으면서도 <text> 요소를 쓰기 때문에, 방문자는 이메일 주소를 복사할 수 있음
  • 정교한 스팸봇까지 막는 해법은 아니지만, 단순한 이메일 수집 스크립트에 노출되는 위험을 줄이는 데 유용함

SVG로 이메일 주소를 숨기는 방식

  • 공개 이메일 주소는 이메일 수집 스팸봇에 노출되기 쉬워 보호 장치가 필요함
  • 일반적인 보호 기법은 HTML, CSS, JavaScript를 조합하지만, JavaScript를 쓰면 연락 기능이 페이지의 필수 실행 환경에 묶임
  • SVG 방식은 JavaScript를 전혀 쓰지 않고 이메일 표시와 링크 동작을 처리함
  • JavaScript가 꺼져 있어도 방문자는 페이지에 표시된 이메일 주소를 사용할 수 있고, 스팸봇에는 일반 HTML 텍스트보다 덜 직접적으로 노출됨
  • 다른 프런트엔드 기반 보호 기법처럼, 집요하고 정교한 스팸봇으로부터 공개 이메일 주소를 완전히 보호하지는 못함
  • 라이브 데모: SVG-based Email Protection

HTML과 SVG 구현

  • HTML 문서는 외부 SVG 파일을 <object>로 삽입함
<object data="svg-email-protection.svg" type="image/svg+xml"></object>
  • 같은 SVG 그래픽 문서는 HTML 안에 한 번 또는 여러 번 삽입할 수 있음
  • 예시 HTML은 .svg-email-protection 클래스에 width: 180px, height: 24px, vertical-align: middle 스타일을 지정하고, 본문에서 SVG 파일을 <object>로 로드함
  • SVG 파일은 viewBox="0 0 200 24"를 가진 <svg> 문서이며, 내부에 이메일 텍스트와 mailto:myemail@mydomain.tld 링크를 둠
    • <a href="mailto:myemail@mydomain.tld"> 안에 <rect /><text>가 들어감
    • <text>에는 myemail@mydomain.tld가 표시됨
    • rect:hovera:focus 상태에서 배경색, 텍스트 색, 굵기, 밑줄, 그림자 스타일이 바뀜

접근성과 참고 자료

  • SVG 문서 전체는 <title>을 가리키는 aria-labelledby를 사용하고, SVG 내부의 <a>에는 같은 콜투액션을 담은 aria-label 을 둠
  • 키보드 탭 포커스가 SVG 내부 앵커에 도달하면 <rect /><text />가 함께 강조되어 포커스 상태를 드러냄
  • 관련 자료:

댓글과 토론

Hacker News 의견들
  • 정말 그럴까 싶음

    • 맞음. 2000년대 초반에는 웹에 이메일을 올리면 실제로 스팸이 늘었고, 이메일 난독화 기법도 꽤 도움이 됐던 기억이 있음
      하지만 개인적으로는 2015년쯤부터는 전혀 차이가 없어졌고, 필터링할 스팸조차 늘지 않았음
      지금은 회사가 사용자 목록을 팔거나 서버가 털려 나온 거대한 이메일 목록을 살 수 있으니, 웹을 훑어 이메일을 모으는 건 스팸 발송 방식으로 거의 최악의 효율임
    • 작년에 만든 웹사이트 두 곳의 푸터에 이메일 주소를 그대로 넣었는데, 둘 다 그동안 스팸 한 통도 받지 않았음
      두 사이트 모두 방문자가 수천 명이고, 검색 엔진과 AI 봇이 긁어가는 인기 사이트임
    • 정확히 같은 생각임. 반대로 1999~2001년쯤 Usenet에서 쓰던 이메일 주소는 지금도 꾸준히 스팸이 쏟아짐
      웹사이트에 올린 이메일 주소는 스팸함으로 가는 것조차 없음
      일부 메일링 목록은 FIRSTNAME.LASTNAME 형태나 1~10글자 조합으로 Gmail 주소를 사전 공격하듯 추측해서 만드는 것 같음
      그래도 domain@domain.com 주소로 오는 스팸은 1년에 한 통 정도라 아주 적음
      전체적으로 이메일 스팸량도 크게 줄었고, 지금 나가는 스팸은 419 사기꾼이나 20년 된 이메일 목록을 사서 속은 예비 사기꾼들이 섞인 것 같음
    • 이메일 주소 난독화는 과거의 유물처럼 느껴짐. 방법론적으로 탄탄했던 적도 없는데 퍼졌고, 일종의 화물 숭배처럼 계속 살아남은 듯함
    • 개인적으로는 스팸이 눈에 보이지 않더라도, 가능하면 내 이메일이 수집되지 않는 편을 선호함
      심각한 개인정보나 보안 문제라고까지 말하는 건 아니지만, 선호의 문제임
  • 내 도메인은 24년째 등록된 .com이고, 이메일 주소는 첫 화면 맨 위 H3 태그에 그대로 걸려 있음
    이 주소의 스팸은 문제가 되지 않음. 정크 폴더까지 포함해 하루 15개 정도이고 Purelymail 덕분에 괜찮음
    진짜 문제는 거래와 무관한 트랜잭션 메일, 뉴스레터성 홍보 메일, 안 쓴다고 계속 알림 보내는 소셜 네트워크임

    • 하루 스팸 15통이면 꽤 많은 편으로 보임. 나는 그보다 적어도 주소를 차단했을 것 같음
    • “안 쓴다고 불평하는 소셜 네트워크”가 제일 큼. Facebook이 로그인해 달라고 보내는 메일이 거의 다른 스팸보다 많음
      계정을 안 쓴 지 7년쯤 됐는데, 이제는 알아챌 법도 함
    • 90년대 말에 등록한 오래된 도메인이 몇 개 있고, 일부에는 아직 mailto로 내 이메일이 남아 있음
      어떤 곳은 스팸이 거의 없고, 어떤 곳은 하루 수십 통씩 옴. SpamAssassin이 스팸 캐싱을 아주 잘해줌
  • “방문자가 JavaScript를 꺼도 페이지에 표시된 이메일 주소는 계속 쓸 수 있다”는 말과 달리, Firefox의 NoScript 기본 설정은 태그를 렌더링하지 않고 자리표시자로 바꾸기 때문에 이 기법은 여기서 동작하지 않음
    https://imgur.com/2tCAgAf

    • uBlock Origin도 JavaScript를 차단할 수 있음. 확장 메뉴에 편한 버튼이 있음
    • 그건 다른 얘기라서, 왜 이 지점을 들고 오는지 잘 모르겠음
    • Chromium에서도 똑같음
  • 이 기법 자체가 접근성을 갖추지 못할 이유는 없지만, 글에 나온 예시는 정말 나쁨
    글은 svg와 a 요소의 라벨을 “Email us!”로 두는데, 그러면 실제 이메일 주소가 스크린 리더에서 숨겨짐
    이런 식의 aria 라벨 사용은 아주 나쁜 관행임. 아주 특별한 이유가 없는 한 스크린 리더 사용자도 다른 사람과 같은 경험을 해야 하고, 그 이유가 충분하다고 생각한다면 대개 틀렸을 가능성이 큼
    올바른 방법은 라벨에 실제 이메일 주소를 넣는 것임

    • 이 작업의 핵심이 문서 안에 이메일 주소를 기계가 읽을 수 있는 형식으로 넣지 않는 것 아닌가?
    • Dragon 같은 음성 받아쓰기 소프트웨어에도 영향을 줄 수 있음
      사용자가 “Click myemail@mydomain.tld”라고 말해도 브라우저가 링크 텍스트를 “Email us”로 노출하므로 링크가 활성화되지 않을 수 있음
      다만 Dragon이 SVG 안의 링크를 활성화할 수 있는지는 모르겠음
  • 나는 이렇게 함: reanospaml@maisjsl.com
    그래도 “스팸”은 받지만, 웹사이트 주제에 정확히 맞춘 B2B 제안이라 사람이 수동으로 수집한 것 같음

    • 스크레이퍼가 헤드리스 브라우저를 쓰면 이 방법을 우회할 수 있을 것 같음
      다만 이메일 수집에 헤드리스 브라우저를 돌리는 건 비용이 비교적 크니, 그 스팸이 사이트에서 온 게 아닐 수도 있음
  • 다른 사람들이 이미 말했듯 이메일을 “보호”하는 건 무의미할 뿐 아니라, 실제로 해롭기도 함
    JavaScript 없이도 대부분 내용은 잘 읽히는데, “1920x1080@60Hz” 같은 문자열만 말 그대로 “[email protected]”로 표시되는 사이트가 꽤 있음

    • 바로 볼 수 있는 예시가 있음? 너무 황당한데 한 번도 본 적 없음
  • 이런 것에 정말 의미가 있나 싶음. 재미있는 실험이긴 하지만, 스패머를 피하려는 목적이라면 완전한 시간 낭비임
    정보를 전 세계에 공개해놓고도 somehow “좋은 사람들”에게만 접근 가능하기를 기대하는 셈임
    이메일 주소를 최소 매달 바꾸지 않는 한, 누군가가 연락처를 다른 사람에게 넘기거나 데이터베이스/CRM에 넣거나, 한 서비스가 침해되기만 해도 그 주소는 목록에 올라가고 결국 전 세계 스패머에게 퍼짐
    그 이메일을 꾸준히 쓴다면 이런 일이 일어날 확률은 사실상 100% 에 가깝다고 봐도 됨
    스크레이퍼에게 이메일을 숨기는 게 정말 효과가 있었다면 스팸은 존재하지 않았을 것임. 개인 연락처를 어디에도 공개한 적 없는데도 주당 수십 통의 스팸을 받지만, 전부 스팸으로 걸러져 큰일은 아님

  • 친구가 정말 고수인데, JavaScript가 들어간 SVG로 사실상 반응형 이미지를 만들고 있음
    크기에 맞춰 프로그래밍 방식으로 적응하는데 꽤 흥미로움
    SVG 안에 JavaScript를 넣을 수 있다는 사실 자체가 아직 덜 활용된 동시에 좀 위험하게 느껴짐

    • SVG는 기본적으로 반응형 아닌가? SVG 안에서 JavaScript가 무엇을 도와주는지 잘 모르겠음
    • 엄청 흥미로움. 그 친구가 이 작업을 보여주는 GitHub나 사이트가 있으면 링크를 올려줄 수 있나
      백엔드 엔지니어라 기술적으로는 내 영역에서 꽤 멀지만 정말 멋져 보임
    • 이건 보안 커뮤니티에서는 꽤 오래전부터 알려져 있었음
  • 이런 방식은 포기했음. 요즘 스팸 필터가 충분히 좋아서, 이메일 주소를 난독화 없이 공개해도 스팸이 늘어나는 것 같지 않음
    합법적인 이유로 내 이메일을 가진 형편없는 회사들이 제3자에게 파는 것 같은 다른 스팸 출처는 별개임
    일반적으로 받은편지함에 들어오는 스팸은 하루 1통 미만이고, 그 정도면 괜찮음
    물론 이메일 제공자와 스팸 필터에 따라 다를 수 있으니 사람마다 다르겠지만, 내게는 문제가 아니었음

  • 이메일은 여전히 페이지 소스에서 참조되는 XML 문서 안에 평문으로 들어 있음

    • 그래도 document.querySelectorAll('a') 같은 방식으로 조회해보면 다름. 많은 스크레이핑 기법이 이런 접근을 쓰니 1차 방어선으로는 괜찮음
      다만 스크레이핑용 헤드리스 브라우저가 있고, 페이지 위에서 현재 URL을 그대로 fetch한 뒤 평문을 받아 정규식으로 이메일을 찾으면 주소를 얻을 수 있음. 인정하건대 꽤 이상한 접근이긴 함
      [0]: fetch('./').then((res) => res.text()).then((text) => console.log(text))
    • 발상은 스팸 봇이 SVG까지 파싱해 이메일 주소를 찾지는 않고, 페이지 HTML만 본다는 것임
      다만 현대적인 스팸 보호 환경에서 이게 실제로 얼마나 효과적인지는 잘 모르겠음
    • 쓸모없는 걸 똑똑한 것처럼 포장한 느낌임