블로그로 돌아가기

소셜 엔지니어링 경고를 받은 URL 단축 서비스, 대응과 3단계 방어 체계

QuikURL ShortenerSecurityGoogle Safe BrowsingSupabaseIncident Response

Google Search Console에서 보안 경고가 도착했다

3월 7일, Google Search Console에서 메일 한 통이 왔다.

에서 소셜 엔지니어링 콘텐츠가 감지되었습니다.

Google Search Console 보안 문제 알림

추리면 이렇다:

  • Google 세이프 브라우징 시스템이 확인한 결과, 사이트 일부 페이지가 해킹되었거나, 사용자를 속여서 악성 소프트웨어를 설치하거나 민감한 정보를 요구하도록 설계된 서드 파티 리소스를 포함하고 있음
  • 방문자 보호를 위해 영향받은 페이지의 검색 순위가 하락
  • Chrome 등의 브라우저에서 사이트 방문 시 경고가 표시

URL 단축 서비스는 누구나 링크를 만들 수 있는 구조다. 한 사용자가 eronsea라는 short code로 피싱 사이트를 가리키는 단축 URL을 만들었고, 그게 quik.im 도메인에서 서빙되는 바람에 도메인 전체에 경고가 붙었다.


문제 확인

직접 접속해 보니 Chrome이 위험한 사이트 경고를 띄웠다.

Chrome 위험한 사이트 경고 페이지

문제의 핵심은 단순했다. URL 생성 시점에 목적지가 악성인지 검증하는 장치가 없었다.


대응 1: 해당 URL 즉시 비활성화

급한 건 링크부터 끊는 일이었다. Supabase DB에서 해당 단축 URL의 is_active 컬럼을 FALSE로 바꿨다.

-- 해당 URL 확인
SELECT * FROM urls WHERE short_code = 'eronsea';

-- 비활성화 (삭제보다 안전, 기록 보존)
UPDATE urls SET is_active = false WHERE short_code = 'eronsea';

지우지 않고 비활성화만 한 것은 나중에 분석하려면 기록이 남아 있어야 해서다.


대응 2: Google Safe Browsing API 연동

같은 일이 반복되지 않도록, URL 생성 시 Google Safe Browsing API v4로 목적지 URL의 안전성을 검사하는 기능을 붙였다.

API Key 발급

Google Cloud Console에서 Safe Browsing API를 활성화하고 API Key를 발급받았다. 하루 10,000건까지 무료다.

Google Cloud API 서비스에서 Safe Browsing API 활성화

발급받은 키를 환경변수에 등록:

GOOGLE_SAFE_BROWSING_API_KEY=발급받은_키

구현 구조

API Key가 클라이언트에 노출되지 않도록 서버 사이드 API Route를 거치는 구조로 설계했다.

사용자가 URL 단축 요청
  → lib/safe-browsing.ts (클라이언트)
    → /api/v1/url/safe-browsing (서버 사이드 API Route)
      → Google Safe Browsing API 조회
      → 위험 감지 시:
         1. 링크 생성 차단 + 에러 메시지 반환
         2. Slack 보안 채널에 즉시 알림 발송
      → 안전 확인 시:
         정상적으로 단축 링크 생성

검사 대상은 4가지 위협 유형이다:

  • SOCIAL_ENGINEERING: 피싱, 사기 페이지
  • MALWARE: 악성 소프트웨어 배포
  • UNWANTED_SOFTWARE: 애드웨어, 브라우저 하이재커
  • POTENTIALLY_HARMFUL_APPLICATION: 기기 보안을 위협하는 앱

API 장애 시에는 fail-open 정책을 적용했다. Safe Browsing API가 응답하지 않는다고 URL 생성을 막아 버리면, 남의 서비스 장애가 이쪽 핵심 기능을 멈춰 세운다. 그래서 생성은 허용하고, Slack 알림과 관리자 모니터링으로 메운다.


대응 3: is_blocked 로 재활성화 막기

그런데 문제가 하나 남는다. is_active를 FALSE로 바꿔도, 해당 링크를 만든 사용자가 대시보드에서 다시 활성화할 수 있다. is_active는 원래 사용자가 자유롭게 토글하는 값이라서다.

그래서 urls 테이블에 is_blocked 컬럼을 새로 뒀다.

ALTER TABLE urls ADD COLUMN is_blocked BOOLEAN NOT NULL DEFAULT FALSE;

그리고 문제의 URL을 is_blocked = TRUE로 설정했다:

UPDATE urls SET is_blocked = true, is_active = false WHERE short_code = 'eronsea';

DB 트리거로 재활성화 차단

is_blocked가 TRUE인 URL은 어떤 경우에도 is_active를 TRUE로 바꿀 수 없도록 데이터베이스 트리거를 걸었다.

CREATE OR REPLACE FUNCTION prevent_blocked_url_modification()
RETURNS TRIGGER AS $$
BEGIN
  -- 차단된 URL의 활성화 시도 거부
  IF OLD.is_blocked = TRUE AND NEW.is_active = TRUE THEN
    RAISE EXCEPTION 'Cannot activate a blocked URL';
  END IF;

  -- 차단 해제는 admin 권한만 가능
  IF OLD.is_blocked = TRUE AND NEW.is_blocked = FALSE THEN
    IF NOT EXISTS (
      SELECT 1 FROM user_roles WHERE user_id = auth.uid() AND role = 'admin'
    ) THEN
      RAISE EXCEPTION 'Only administrators can unblock URLs';
    END IF;
  END IF;

  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

핵심 설계:

  • is_active: 사용자가 자유롭게 토글하는 값
  • is_blocked: 관리자만 설정하고 해제하는 값
  • 보호 로직이 애플리케이션이 아닌 DB 트리거에 있으므로 클라이언트에서 어떤 요청을 보내든 우회 불가

대시보드에서는 차단된 링크에 빨간 "Blocked" 배지를 달고 활성화 토글을 꺼 둬서, 사용자가 상태를 바로 알아보게 했다.

차단된 링크의 대시보드 UI: Blocked 배지와 비활성화된 토글


대응 4: Google Search Console 검토 요청

조치를 다 끝낸 뒤 Google Search Console에서 검토를 요청했다.

  1. 보안 문제 페이지 → "검토 요청"
  2. 설명에 조치 내용 기재: "악성 단축 URL 비활성화 및 영구 차단, URL 생성 시 Safe Browsing API 검증 추가"
  3. 보통 1~3일 내에 경고가 해제된다

해결 완료: Google 검토 통과

3월 9일 오전 9시, 하루 만에 Google Search Console에서 검토 완료 메일이 왔다.

Google Search Console 검토 완료 알림

Google에서 요청하신 보안 검토 내용을 접수하고 처리했습니다. Google 시스템에 따르면 quik.im에 더 이상 유해한 사이트 또는 다운로드 링크가 포함되어 있지 않습니다.

검토 요청 후 3일 만에 경고가 해제되었다. Chrome 브라우저의 위험 사이트 경고도 사라졌고, 검색 순위도 제자리로 돌아왔다.


정리

URL 단축 서비스는 구조상 악용에 열려 있다. 이번 인시던트를 겪고 방어를 3단계로 쌓았다:

  1. 사전 검증: Google Safe Browsing API로 생성 시점에 악성 URL 차단
  2. 실시간 알림: 악성 URL 생성 시도 시 Slack 보안 알림
  3. 영구 차단: is_blocked + DB 트리거로 관리자만 해제 가능한 차단

사용자가 입력하는 값을 그대로 외부에 노출하는 서비스라면, "입력 시점 검증"만으로는 부족하다. 뒤늦게 찾아낸 문제를 관리자가 영구히 막는 장치, 그리고 그 차단을 사용자가 우회하지 못하게 DB 레벨에서 강제하는 구조가 함께 있어야 실제로 막힌다.

관련 프로젝트

Quik - URL 단축 SaaS 서비스

단축 URL 생성부터 링크 운영(편집·만료·비밀번호 보호), 클릭 분석, 관리자 운영까지 다루는 SaaS형 URL 플랫폼.