보안 센터

클립보드는 이 PC 에 남습니다. 어떻게 지키는지, 어디까지인지 적어 둡니다.

이 페이지의 문장은 모두 소스 코드와 대조해 확인했고, 그것을 강제하는 코드의 이름을 옆에 적었습니다. ClipVault 가 지켜 주지 못하는 부분도 그대로 적었습니다.

ClipVault 0.1.0 코드 기준 확인 · 페이지 생성 2026-09-15

원칙

코드가 지키는 네 가지 약속

누군가 기억해야 하는 방침이 아닙니다. 하나하나를 검사 스크립트나 테스트가 붙잡고 있어서, 어기면 빌드가 실패합니다.

네트워크

클립 내용은 PC 밖으로 나갈 수 없습니다

프로그램에서 연결을 열 수 있는 파일은 net.py 하나뿐이고, 그 안의 유일한 함수 get_json(url, allowed) 에는 요청 본문을 실을 인자가 없습니다. 클립을 올려 보내는 코드 경로가 없습니다 — 실어 보낼 수단 자체가 없기 때문입니다.

매 푸시마다 scripts/check_network.py 가 확인합니다. 다른 모듈이 네트워크 라이브러리를 import 하거나, 게이트웨이에 data·body·payload·content·text 인자가 생기면 빌드가 실패합니다.

텔레메트리

텔레메트리 없음 — 켜는 설정도 없습니다

사용 통계도, 오류 보고도, 분석 도구도 없습니다. 설정 파일에 telemetry 항목이 남아 있지만 그것을 읽어 무언가를 보내는 코드는 없고, 설정을 읽거나 저장할 때마다 Config.normalize() 가 파일 내용과 상관없이 false 로 되돌립니다.

src/clipvault/config.py — 모든 읽기·저장이 normalize() 를 거칩니다.

업데이트

업데이트 확인과 소식은 직접 켜야 동작합니다

새로 설치하면 둘 다 꺼져 있고, 처음 실행할 때 물어봅니다. 거절하면 연결을 아예 열지 않습니다. 허락하면 하루 한 번 작은 버전 파일을 HTTPS GET 으로 한 번 요청합니다 — 본문도, 쿠키도, 식별자도 없고, 붙이는 헤더는 ClipVault 이름과 버전을 적은 User-Agent 하나뿐입니다. 평문 HTTP 와 리디렉션은 거부하고, 64KB 를 넘는 응답은 버립니다.

net.get_json, updates.fetch. 조직은 DisableUpdateCheck·DisablePromos 정책으로 둘 다 끌 수 있습니다.

업데이트 링크

“새 버전 받기” 는 공식 사이트로만 안내합니다

버전 파일은 프로그램이 받아 온 데이터일 뿐 믿는 데이터가 아닙니다. 그 안의 링크는 ClipVault 사이트의 경로이거나 같은 호스트의 https 주소일 때만 받아들이므로, 누군가 파일을 바꿔치기해도 비슷하게 생긴 가짜 다운로드로 보낼 수 없습니다. 버전 번호도 숫자와 점만 받아서, 그 자리에 문구를 끼워 넣을 수 없습니다.

updates.official_link, updates.clean_version — 캐시에 저장된 사본에도 똑같이 적용됩니다.

데이터 흐름

클립이 지나가는 길, 단계별로

위쪽 상자 안의 일은 모두 내 PC 에서, 내 Windows 계정 아래에서 일어납니다. 아래쪽 상자는 프로그램의 유일한 네트워크 경로이고, 클립에는 닿지 않습니다.

ClipVault 데이터 흐름 복사된 클립은 먼저 캡처 관문을 지나며, 기록 제외 표시가 있거나 제외 앱에서 복사된 클립은 여기서 버려집니다. 탐지 단계가 자격증명을 찾고, 자격증명은 Windows DPAPI 로 암호화하며 암호화에 실패하면 아예 저장하지 않습니다. 클립은 폴더 권한을 내 계정으로 잠근 %LOCALAPPDATA%\ClipVault 의 로컬 SQLite 데이터베이스에 저장됩니다. 저장소에서 나오는 것은 앞에 있는 것이 확인된 창에 붙여넣을 때뿐이고, 붙여넣은 자격증명은 클립보드에서 지워집니다. 이와 별개로, 허락한 경우에만 프로그램이 버전 파일을 HTTPS GET 으로 한 번 요청하며, 그 경로에는 클립 데이터가 없습니다.
이 PC · 내 Windows 계정
1클립보드어느 앱에서든 텍스트·이미지·파일을 복사합니다.
2캡처 관문기록 제외 표시 · 제외 앱 · 조직 정책
3탐지앞쪽 1,000,000자에서 자격증명을 찾습니다
4DPAPI 암호화자격증명만. 암호화에 실패하면 저장하지 않습니다.
그 밖의 클립
저장하지 않음앱이 “기록하지 말라” 고 표시했거나 제외 앱에서 복사한 클립
5로컬 데이터베이스%LOCALAPPDATA%\ClipVault 의 SQLite · 폴더 권한을 내 계정으로 잠금
6기록 창과 붙여넣기앞에 있는 것이 확인된 창에만 키를 보냅니다
7붙여넣은 뒤 지우기붙여넣은 자격증명은 30초 뒤 지웁니다 — 그사이 새로 복사했으면 그대로 둡니다
클립에서 네트워크로 가는 길은 없습니다
유일한 네트워크 경로 · 직접 켜기 전에는 꺼짐
업데이트 확인허락한 경우에만, 하루 한 번
HTTPS GET · 본문 없음 · 쿠키 없음
ClipVault 사이트의 release.json최신 버전, 안내 링크, 선택형 소식 — 모두에게 같은 응답
보내는 것: 그 파일의 주소와 ClipVault 이름·버전을 적은 User-Agent, 그리고 연결에 드러나는 IP 주소. 보내지 않는 것: 클립, 기록, 설정, 어떤 식별자도.
ClipVault 데이터 흐름 복사된 클립은 먼저 캡처 관문을 지나며, 기록 제외 표시가 있거나 제외 앱에서 복사된 클립은 여기서 버려집니다. 탐지 단계가 자격증명을 찾고, 자격증명은 Windows DPAPI 로 암호화하며 암호화에 실패하면 아예 저장하지 않습니다. 클립은 폴더 권한을 내 계정으로 잠근 %LOCALAPPDATA%\ClipVault 의 로컬 SQLite 데이터베이스에 저장됩니다. 저장소에서 나오는 것은 앞에 있는 것이 확인된 창에 붙여넣을 때뿐이고, 붙여넣은 자격증명은 클립보드에서 지워집니다. 이와 별개로, 허락한 경우에만 프로그램이 버전 파일을 HTTPS GET 으로 한 번 요청하며, 그 경로에는 클립 데이터가 없습니다.
이 PC · 내 Windows 계정
1클립보드어느 앱에서든 텍스트·이미지·파일을 복사합니다.
2캡처 관문기록 제외 표시 · 제외 앱 · 조직 정책
3탐지앞쪽 1,000,000자에서 자격증명을 찾습니다
4DPAPI 암호화자격증명만. 암호화에 실패하면 저장하지 않습니다.
5로컬 데이터베이스%LOCALAPPDATA%\ClipVault 의 SQLite · 폴더 권한을 내 계정으로 잠금
6기록 창과 붙여넣기앞에 있는 것이 확인된 창에만 키를 보냅니다
7붙여넣은 뒤 지우기붙여넣은 자격증명은 30초 뒤 지웁니다 — 그사이 새로 복사했으면 그대로 둡니다
클립에서 네트워크로 가는 길은 없습니다
유일한 네트워크 경로 · 직접 켜기 전에는 꺼짐
업데이트 확인허락한 경우에만, 하루 한 번
HTTPS GET · 본문 없음 · 쿠키 없음
ClipVault 사이트의 release.json최신 버전, 안내 링크, 선택형 소식 — 모두에게 같은 응답
보내는 것: 그 파일의 주소와 ClipVault 이름·버전을 적은 User-Agent, 그리고 연결에 드러나는 IP 주소. 보내지 않는 것: 클립, 기록, 설정, 어떤 식별자도.

관문. 앱이 “기록하지 말라” 고 표시한 클립 — KeePass·1Password·Bitwarden 이 남기는 표준 표시 — 은 내용을 읽지도 않습니다. 제외 앱에서 온 클립은 저장하기 전에 버립니다. 기본 목록에는 비밀번호 관리자와 국내 금융 보안 모듈이 들어 있습니다. 조직 정책으로 제외 앱을 더하거나 이미지·파일 기록을 끌 수 있습니다. win/clipboard.read, Vault._gate

실패하면 닫히는 암호화. 자격증명은 Windows DPAPI 로 암호화하고 원문 텍스트를 비워서 검색 색인에도 들어가지 않습니다. DPAPI 를 쓸 수 없거나 실패하면 평문으로 남기는 대신 그 클립을 버립니다. Vault._protect

저장. 처음 실행할 때 폴더의 권한 상속을 끊고 내 계정에 명시적으로 권한을 주므로, 상위 폴더 설정이 바뀌어도 따라 넓어지지 않습니다. 자격증명의 중복 확인에는 키가 있는 해시를 써서, 데이터베이스에 값을 추측할 수 있는 지문이 남지 않습니다. win/acl.harden_once, Vault._dedupe_key

붙여넣기. 원래 쓰던 창으로 포커스를 돌려놓고, Ctrl+V 를 보내기 직전에 그 창이 여전히 앞에 있는지 한 번 더 확인합니다. 확인하지 못하면 아무 키도 보내지 않고, 클립은 클립보드에 남아 직접 붙여넣을 수 있습니다. 클립보드에 다시 올리는 자격증명에는 “기록하지 말라” 표시를 함께 붙여서 Windows 클립보드 기록이나 다른 관리자가 가져가지 않게 합니다. actions.deliver, win/exclusions.exclusion_payloads

지우기. 자격증명을 붙여넣으면 기본 30초 뒤 클립보드를 비웁니다 — 그사이 새로 복사한 것이 없을 때만. actions.clear_if_unchanged

네트워크. 요청은 주소와 사용자의 허락, 그 둘만 받는 함수가 보내므로 클립 데이터가 닿을 자리가 없습니다. 평문 HTTP 와 리디렉션은 거부하고 64KB 를 넘는 응답은 버립니다. net.py, updates.fetch

위협 모델

막는 것과 막지 못하는 것

로컬 프로그램은 일부 공격을 어렵게 만들 수 있을 뿐, 이미 뚫린 Windows 계정을 안전하게 만들 수는 없습니다. 그렇지 않은 척하면 엉뚱한 것을 믿게 됩니다.

막아 주는 것

  • 복사해 간 DB 파일이나 백업. 그 안의 자격증명은 내 Windows 계정에 묶인 DPAPI 암호문이고, 지문도 키가 있는 해시입니다.
  • 같은 PC 의 다른 계정. 폴더 권한이 내 계정으로 고정되고, DPAPI 키는 계정마다 따로입니다.
  • 비밀번호 관리자에서 복사한 비밀. 표준 기록 제외 표시가 있는 클립은 읽지 않고 건너뜁니다.
  • 목록을 흘끗 보는 눈. 자격증명 행은 가려지고, 값은 Ctrl+R 을 눌렀을 때만 보입니다.
  • 엉뚱한 창에 붙여넣기. 대상 창이 앞에 있다고 확인되지 않으면 키를 보내지 않습니다.
  • 바꿔치기한 버전 파일이나 가져오기 파일. 업데이트 링크는 공식 호스트로만 제한되고, 가져오기 파일은 경로·해시·라벨을 내용에서 다시 계산해 확인합니다.
  • 앱을 멈추게 하려고 만든 글. 탐지 패턴에는 모두 상한이 있고, 앞쪽 1,000,000자만 검사합니다.

막지 못하는 것

  • 내 계정으로 실행 중인 악성코드. 내 Windows 계정 아래의 프로그램은 ClipVault 와 똑같이 클립보드를 읽고 DPAPI 에 복호화를 요청할 수 있습니다.
  • PC 의 관리자. 관리자 권한 계정은 다른 계정의 파일을 읽고 그 계정으로 행동할 수 있습니다.
  • 클립보드에 올라가 있는 동안의 다른 앱. Windows 클립보드는 실행 중인 모든 프로그램이 함께 씁니다. 붙여넣은 뒤 지우기는 그 시간을 줄일 뿐이고, 자격증명에만 적용됩니다.
  • 화면에 띄운 값. 직접 드러낸 값은 화면 녹화·화면 공유·화면 낭독기, 옆에 있는 사람에게 보입니다.
  • 알아보지 못한 자격증명. 탐지는 알려진 형식과 라벨을 찾습니다. 라벨 없이 비밀번호만 복사하면 일반 텍스트처럼 보이고, 일반 텍스트로 저장됩니다.
  • 일반 클립. 자격증명이 아닌 텍스트·이미지·파일 경로는 암호화하지 않고 폴더에 저장되며, Windows 권한으로만 보호됩니다. 이메일 주소와 전화번호도 마찬가지입니다.
  • 직접 바꾼 설정. 암호화를 끄면 자격증명은 가려지기만 하고 암호화되지 않습니다. 내보낸 파일의 관리는 내보낸 사람의 몫입니다.
  • 업데이트를 확인한다는 사실. 업데이트 확인을 켜 두면 사이트 호스트는 하루 한 번 내 IP 주소와 ClipVault 버전을 봅니다.

프로그램의 관리자 콘솔 → 보안 에 적힌 경계와 같습니다: 이 암호화는 “DB 파일만으로는 읽을 수 없다” 까지를 보장합니다.

자격증명 탐지

무엇을 찾는가

탐지는 클립에 라벨을 붙일 뿐, 스스로 지우지 않습니다. 자격증명 라벨이 붙은 클립은 암호화하고 가립니다. 저장 자체를 거부하는 것은 사용자나 조직 정책이 그렇게 켰을 때뿐입니다.

비밀번호

라벨과 값 — “password:”, “비밀번호:”, “contraseña=” 처럼 앱이 지원하는 12개 언어 모두의 ‘비밀번호’ 단어를 찾고, 전각 콜론도 구분자로 봅니다. scheme://사용자:비밀번호@호스트 형태의 주소도 포함합니다.

API 키와 토큰

OpenAI·Anthropic·Stripe·GitHub·GitLab·npm·SendGrid·AWS·Slack·Google 의 알려진 형식, api_key=client_secret: 처럼 라벨이 붙은 값, DB_PASSWORD= 같은 .env 줄, Azure 연결 문자열의 키.

웹훅 URL

그 자체가 자격증명인 Slack·Discord 웹훅 주소.

개인 키

PEM 형식의 개인 키 블록.

JWT

eyJ 로 시작하는 base64url 조각 세 개.

카드 번호

Luhn 검사를 통과하는 13~19자리 숫자. 0000 0000 0000 0000 같은 자리표시 숫자는 제외합니다.

주민등록번호

생년월일과 검증 번호까지 확인합니다.

이메일 주소와 전화번호

개인정보 라벨은 붙지만 암호화하지 않습니다. 일부러 복사하는 값이기 때문입니다.

멈추지 않도록 만들었습니다

탐지는 복사할 때마다 돌기 때문에, 느린 패턴 하나가 단축키를 얼어붙게 할 수 있습니다. 모든 패턴의 모든 반복에 상한을 두었고, 테스트는 공격용 입력 14가지를 넣어 입력을 4배로 늘렸을 때 시간이 8배를 넘으면 실패합니다 — 역추적 폭발(ReDoS)의 신호입니다. 클립은 앞쪽 1,000,000자만 검사하고, 프로그램은 검사한 것보다 긴 텍스트를 저장하지 않습니다.

sensitive.DETECT_LIMIT, Config.normalize, tests/test_security.py

조직용

정책은 조이기만 할 수 있습니다

IT 부서는 그룹 정책이나 Intune 으로 HKLM\SOFTWARE\Policies\ClipVault 에 설정을 강제할 수 있습니다. 컴퓨터와 사용자 정책 키를 모두 읽어 더 엄격한 값을 쓰고, 일반 사용자는 어느 쪽에도 쓸 수 없습니다.

  • 19가지 규칙. 자격증명 저장 금지, 암호화 강제, 보존 기간·개수 상한, 붙여넣은 뒤 지우는 시간 강제, 제외 앱 추가, 앱별 보존 기간 단축, 탐지 규칙 추가, 이미지·파일 기록·내보내기·업데이트 확인·소식 끄기, 폴더 권한 잠금, 화면 캡처 가림 강제, 비공개 모드 금지, 새 프로그램에 자격증명을 붙여넣을 때 확인 강제.
  • 풀어 주는 스위치는 없습니다. 암호화를 끄거나, 제외 앱을 빼거나, 네트워크를 쓰는 기능을 켜는 정책은 없습니다 — 정책 이름이 Disable·Require·Max·Excluded·LockDown 으로 시작하지 않으면 테스트가 빌드를 실패시킵니다.
  • 읽을 수 없는 값은 무시합니다. 허용으로 해석하지 않습니다.
  • 사용자에게 숨기지 않습니다. 잠긴 설정은 흐리게 표시되고, 관리자 콘솔에 적용 중인 규칙이 나옵니다.

그룹 정책 템플릿

ADMX 와 영어·한국어 ADML, 값마다의 설명서가 들어 있습니다. 그룹 정책과 Intune 의 ADMX 가져오기 모두에서 씁니다.

ClipVault-policy.zip 내려받기
공급망

실행 파일에 무엇이 들어가는가

들어가는 부품이 적을수록 남의 코드가 끼어들 틈도 적습니다.

  • 외부 라이브러리 없음. 프로그램은 Python 표준 라이브러리만 씁니다 — Win32 는 ctypes, 화면은 tkinter, 저장은 sqlite3, PNG 코덱은 직접 작성. PyInstaller 는 묶을 때만 씁니다. scripts/check_stdlib_only.py 가 모든 import 를 읽어 그 밖의 것이 있으면 빌드를 실패시킵니다.
  • 네트워크 문은 하나, 기계가 확인. scripts/check_network.py 가 네트워크 코드를 net.py 안에만 두고, 거기에 본문 인자가 생기지 않게 막습니다.
  • 푸시할 때마다 확인. 전체 테스트, 의존성 검사, 네트워크 검사, 다운로드 집계 테스트, 번역 검사를 CI 의 Windows 환경에서 돌립니다.

이 빌드는 코드 서명되어 있습니다

ClipVault.exe 는 Azure Artifact Signing 을 통해 PROJECTTEAMFORYOU 명의로 서명되어 있습니다. 파일을 우클릭 → 속성디지털 서명 에서 확인할 수 있습니다. 서명이 설정된 빌드는 서명 없이 끝나지 않으며, 파일이 빌드 머신을 떠나기 전에 서명을 한 번 더 검증합니다.

이 웹사이트

다운로드 집계가 남기는 것

어떤 파일이 쓰이는지 알기 위해 웹사이트에서 다운로드 횟수를 셉니다. 기록이 아니라 숫자만 남깁니다.

저장함

  • 날짜(UTC)
  • 파일 이름
  • 호스팅 업체 네트워크가 알려 주는 두 글자 국가 코드

저장하지 않음

  • IP 주소
  • User-Agent — 봇과 링크 미리보기를 거르는 데만 읽습니다
  • 어느 페이지에서 왔는지
  • 쿠키, 그 밖에 사용자에 관한 어떤 것도

이어받기와 크롤러는 세지 않고, 프로그램의 업데이트 확인은 아예 세지 않습니다 — 버전 확인을 허락한 것이지 집계를 허락한 것이 아니기 때문입니다. deploy/cloudflare/lib/downloads.js

회사 자체 광고의 클릭 — 이 웹사이트에서, 또는 소식을 켠 경우 프로그램의 소식에서 — 도 같은 방식으로 날짜·광고·국가만 집계합니다. 프로그램은 팝업에 광고를 절대 띄우지 않고, 다른 회사의 광고는 보여 주지 않습니다. deploy/cloudflare/lib/ads.js

취약점 신고

취약점을 찾으셨나요? 먼저 알려 주세요.

공개되기 전에 고칠 수 있도록 이메일로 비공개 신고를 부탁드립니다.

보안 문제 신고 security@clipvault.dev
보안 신고 메일 쓰기

목표는 신고를 받고 영업일 3일 안에 회신하고, 수정과 공개 일정을 신고자와 함께 정하는 것입니다. 약속이 아니라 목표입니다 — ClipVault 는 작은 팀이 만듭니다.

함께 적어 주시면 좋은 것

  1. ClipVault 버전(clipvault-cli --version)과 Windows 버전
  2. 재현 방법과, 공격자가 얻게 되는 것
  3. 있다면 개념 증명(PoC)
  4. 공개할 계획이 있는지, 언제인지

실제 비밀번호나 다른 사람의 클립보드 데이터는 보내지 마시고, 본인 소유의 컴퓨터와 계정에서만 시험해 주세요.

유료 버그 바운티는 없습니다. 원하시면 릴리스 노트에 이름을 적어 감사를 전합니다.

기계가 읽는 연락처: security.txt →