먼저 좁은 결론을 적어둡니다. 이미지 호스트의 로그인 비밀번호가 해시여도, 스크린샷 안에서 이미 글자가 된 비밀번호는 막지 못합니다. 이미지 ID로 조립한 직링크도 막지 못합니다. 호스트 쪽 비밀번호를 바꿔도 끊기는 것은 그 한 곳의 로그인입니다. 화면에 찍힌 살아있는 키는 원래 시스템에서 교체하세요. 이 기기에서 대조할 수 있는 것은, 이제 보낼 픽셀에 읽을 수 있는 비밀이 있는지입니다. 공지에 「해시」라는 단어가 있었는지는 아닙니다.
검색 의도를 한 문장으로 먼저 답하기
비밀번호를 이미지 호스트에 스크린샷으로 올리는 위험은 「로그인 비밀번호가 해시인가」가 아닙니다. 화면 자체와, 그 그림에서 뽑아 낸 글자가 독립된 칸으로 이 기기를 떠나는가입니다. 해시가 덮는 것은 계정 비밀번호 한 열뿐입니다. OCR 텍스트, 이미지 ID, 업로드 출발 IP, User-Agent, EXIF 위치는 다른 묶음입니다. 이들이 새면 비공개 스크린샷은 「링크를 추측할 수 없다」로는 지키지 못합니다. 그림 속 비밀번호도 해시를 먼저 깨야 할 필요가 없어집니다.
이 글은 개발자, 운영, 그리고 오류 화면, 콘솔, 비밀번호 관리자 창을 이미지 호스트에 올린 뒤 카카오톡이나 Slack으로 넘기는 사람을 위한 것입니다. 어느 회사의 사고 공지를 대신하지 않으며, 「스크린샷을 그만두는 절차」도 아닙니다. 가져가야 할 것은 공지된 해시가 덮는 층, 이미지 ID가 무너뜨리는 프라이버시 모델, OCR이 픽셀보다 검색하기 쉬운 이유, 올리기 전에 내보낼 내용을 대조하는 방법입니다.
이번 공개가 갈라 보여 준 층
2026년 9월 16일, Gyazo 운영사는 Helpfeel 영문 공지를 내고 같은 날 일본어판도 냈습니다. 경과는 이렇게 적혀 있습니다. 9월 11일, 제삼자가 이미지 업로드 서버의 취약점을 이용해 임의 명령을 실행했다. 그날 밤 이상 동작을 감지하고, 12일 새벽 전에 침입 경로를 끊고 취약점을 고쳤다. 14일 데이터가 밖으로 나간 것을 확인하고 일부 이미지 배포를 멈췄다. 15일 일본 개인정보보호위원회에 보고하고, 조치가 끝난 뒤 새로 올린 이미지의 배포를 재개했다.
9월 16일 시점에 확인된 범위는 둘로 나뉩니다. 첫째는 사용자 관련 기록 약 2362만 건입니다. 사용자가 적은 이름이나 닉네임, 이메일, 비밀번호 해시, 사용자 ID, 기기 ID, 로그인 세션 ID, 연결돼 있던 경우의 X 연동 토큰, 연결돼 있던 경우의 Google SSO 이메일, 프로필, 사용 언어, 가입 시각, 최근 로그인 시각, 구독 플랜, 결제 상태. 공지는 신용카드 번호 같은 결제 수단 정보는 포함하지 않는다고 적습니다. 이 2362만 건에는 이메일을 등록하지 않은 익명 계정도 들어가며, 실제 인원수는 조사 중입니다.
둘째는 이미지 메타데이터입니다. 주로 2019년 1월 이전에 등록된 약 4.9억 건(이미지 관련 데이터의 약 14.4%)에 더해, 다른 조건으로 꺼낸 약 240만 건. 칸에는 이미지 URL을 구성하는 이미지 ID, 업로드 출발 IP, User-Agent, 이미지에 들어 있는 경우의 EXIF 위치, 이미지에서 뽑아 낸 OCR 텍스트, 이미지 제목, 취득원 URL, 비공개 이미지 비밀번호의 해시가 들어 있습니다. 이 공지의 「이미지」는 스크린샷, GIF, 동영상을 포함합니다. Helpfeel과 Cosense는 다른 계통이며, 당일 시점에는 이 두 계통의 유출은 확인되지 않았습니다. 그 페이지에 심어 둔 Gyazo 이미지는 배포 중단의 영향으로 열리지 않을 수 있습니다.
이것은 「또 비밀번호 해시가 빠져나갔다」는 뉴스의 반복이 아닙니다. 해시, 세션 ID, 이미지 ID, OCR 텍스트는 나란히 가는 네 갈래입니다. 호스트 쪽 로그인 비밀번호만 바꿔도 덮는 것은 첫 갈래뿐입니다. 이미 나간 세션 ID는 막지 못합니다. 공지는 인증 관련 정보를 무효화하고 제한했다는 점, Gyazo 비밀번호와 다른 서비스에서 재사용한 같거나 비슷한 비밀번호의 변경을 요청한다는 점을 적습니다.
로그인 비밀번호 해시는 화면의 평문을 덮지 않는다
비밀번호 해시의 설계 목표는, 사용자 테이블이 빠져나간 뒤에도 공격자가 로그인 비밀번호를 그대로 읽지 못하고, 추측에 계산을 쓰게 만드는 것입니다. 알고리즘, 솔트, 반복 횟수가 이 층의 난이도를 정합니다. 화면에 찍은 다른 비밀번호가 안전한지는 정하지 않습니다. 이미지 호스트 계정 비밀번호와, 스크린샷에 찍힌 운영 데이터베이스 비밀번호는 원래부터 같은 열이 아닙니다.
개발자가 터미널, 브라우저 비밀번호 칸, 클라우드 콘솔, 비밀번호 관리자 창을 찍으면 이미지 호스트가 받는 것은 픽셀입니다. 많은 이미지 호스트는 그다음 문자 인식을 돌려, 검색할 수 있는 OCR 문자열로 저장합니다. 「그 오류가 찍힌 그림」을 찾기 위해서입니다. 인식 결과가 데이터베이스에 들어가면 비밀번호, 접속 문자열, 토큰은 이미지 바이트 안에만 살지 않습니다. 키워드로 걸러 낼 수 있는 칸이 됩니다. 이번 공지는 「이미지의 OCR 텍스트」를 유출된 메타데이터의 독립 항목으로 열거합니다. 댓글의 추측이 아닙니다. 테이블의 정식 열입니다.
그러므로 「비밀번호는 해시로 저장했다」가 뒷받침하는 결론은 좁습니다. 이 한 곳의 로그인 비밀번호는 사용자 테이블에서 평문이 아니다. 그것뿐입니다. 다음은 뒷받침하지 않습니다. 스크린샷 속 SSH 비밀키도 해시를 먼저 깨야 한다. OCR 테이블에서 BEGIN OPENSSH나 AKIA를 찾을 수 없다. 비공개 이미지는 나만 열 수 있다. 뒤의 문장에는 다른 증거가 필요합니다. 메타데이터에 OCR과 이미지 ID가 있는가. 올리기 전 화면에 읽을 수 있는 비밀이 있었는가.
실제 비밀번호, API Key, 가리지 않은 접속 문자열로 실험하지 마세요. 이번에만 쓰는 테스트 문장, 또는 그 문장만 찍힌 스크린샷을 준비하세요. 대조하는 것은 나갈 픽셀과 요청에 그 카나리아가 있는지입니다. 자격 증명을 다시 이미지 호스트로 보내는 일이 아닙니다.
이미지 ID가 「비공개 링크」를 무너뜨리는 이유
많은 이미지 호스트는 「공개로 공유하지 않음」을 이렇게 만듭니다. 프로필에 올리지 않고, 난수처럼 보이는 직링크만 줍니다. 안전 가정은 ID를 모르면 URL을 조립하지 못한다는 것입니다. 이것은 숨긴 주소이지, 접근 제어가 아닙니다. ID를 가진 사람은 같은 규칙으로 같은 주소를 만들 수 있습니다.
Helpfeel 공지는 이미지 ID를 「이미지 URL을 구성하는 정보」라고 쓰고, 제삼자가 이 정보로 해당 이미지에 접근해 무단으로 볼 수 있다고 적습니다. 그 때문에 일부 이미지의 열람을 잠시 막았습니다. 공지는 더 나아가, 비공개 이미지의 파일 목록이 가져가졌다는 점, 일부 비공개 이미지가 제삼자에게 열렸을 가능성을 완전히 부정할 수 없다는 점도 확인합니다. 목록과 ID가 모이면 「이 링크는 나만 안다」는 가정은 빠집니다.
비공개 이미지에 따로 비밀번호를 걸어 두었어도, 공지가 열거한 것은 「해시된 비밀번호」입니다. 해시는 그 비밀번호 자체에 해독의 한 단계를 더합니다. 이미 ID를 가지고, 이미지 호스트가 아직 ID로 그림을 내주는 사람에게서 픽셀을 자동으로 빼앗지는 않습니다. 배포 중단은 운영 쪽의 임시 문입니다. ID가 한 번도 데이터베이스를 떠나지 않았다는 증명이 아닙니다. 「단톡방에 안 붙였다」를 「그림이 저장소에 없다」로 쓰는 것은, 제품 화면의 보임과 저장 층의 보임을 한 문장으로 접습니다.
EXIF 위치, 업로드 출발 IP, User-Agent는 세 번째 맥락입니다. 화면이나 자리를 휴대폰으로 찍으면 GPS가 붙을 수 있습니다. 업로드 요청은 출구 주소와 클라이언트 식별을 실어 나릅니다. 픽셀에 번지가 없어도, 메타데이터는 「누가, 어디에서, 어떤 클라이언트로 한 장을 올렸는가」를 다시 조립할 수 있습니다. 캡처 도구가 위치 정보를 빼는 경우도, 빼지 않는 경우도 있습니다. 「앨범이 아니라 스크린샷을 썼다」는 EXIF가 비어 있다는 증명이 되지 않습니다.
OCR이 픽셀보다 다시 쓰기 쉬운 이유
PNG 한 장을 손으로 넘기거나, 시각 모델을 돌려 어지러운 바탕화면에서 비밀번호 칸을 찾는 일은 무겁습니다. OCR 텍스트는 이미 잘린 문자열입니다. 유출 뒤에 password, BEGIN , sk-, 사내 호스트 이름을 찾는 작업은 4.9억 장을 넘기는 것보다 자릿수가 다릅니다. 공지는 인식 정확도를 밝히지 않았습니다. 필요도 없습니다. 데이터베이스가 「이미지에서 뽑아 낸 글자」를 들고 있다면, 공격자가 마주하는 것은 텍스트 칸이지 썸네일만이 아닙니다.
「비공개로 두었다」가 OCR 층을 막지 못하는 이유도 여기에 있습니다. 보임 스위치가 제어하는 것은 제품 페이지가 그림을 늘어놓는가입니다. OCR이 제어하는 것은 이미지 호스트가 화면을 글자로 만들었는가입니다. 둘 다 동시에 참일 수 있습니다. 화면상은 비공개, 데이터베이스에는 제목, OCR, ID가 있다. 덤프가 가져가는 것은 데이터베이스이지, 공유 버튼의 상태가 아닙니다.
열람 후 파기에서 「상대가 당신 화면을 찍었다」는 주장과는 다른 이야기입니다. 앞선 글이 다루는 것은 수신 쪽 기기의 사본입니다. 호스트가 암호문을 지워도 그것은 지워지지 않습니다. 이 글이 다루는 것은 보내는 쪽이 픽셀을 이미지 호스트에 넘기고, 호스트가 글자를 뽑고 ID를 붙이는 일입니다. 한쪽은 「상대가 남겼다」. 다른 쪽은 「먼저 넘겼다」. 「링크가 무효가 됐다」, 「비밀번호는 해시였다」로는 어느 쪽도 지워지지 않습니다.
| 눈에 들어오는 말 | 뒷받침되는 결론 | 뒷받침되지 않는 결론 |
|---|---|---|
| 공지에 비밀번호는 해시로 저장했다고 적혀 있다 | 호스트 쪽 로그인은 사용자 테이블에서 평문이 아니다 | 스크린샷 속 비밀번호도 해시를 먼저 깨야 한다 |
| 이미지는 비공개이고 한 번도 공유하지 않았다 | 제품 페이지는 공개 목록에 올려 두지 않았을 가능성이 높다 | ID를 모르는 사람은 직링크를 조립하지 못한다 |
| 호스트 쪽 로그인 비밀번호를 바꿨다 | 그 한 곳의 로그인은 교체했다 | 스크린샷 속 데이터베이스 비밀번호와 API Key도 무효가 됐다 |
| 호스트가 일부 이미지 열람을 멈췄다 | 지금은 일부 ID로 픽셀을 가져가지 못한다 | OCR 텍스트와 과거 메타데이터는 한 번도 데이터베이스를 떠나지 않았다 |
| 찍은 것은 오류 화면이지 비밀번호 관리자가 아니다 | 화면에 비밀번호 칸은 없다고 생각한다 | OCR은 토큰, 접속 문자열, 사내 주소를 뽑아내지 못한다 |
| 운영이 세션 ID를 무효화했다 | 그 회사의 현재 세션은 재사용하지 못할 수 있다 | X 토큰, Google SSO 연동, 재사용한 비밀번호는 모두 안전하다 |
올리기 전에 화면을 보고, 보낸 뒤에 요청을 본다
표어는 증거가 되지 않습니다. 다음에 대조하는 것은 당신이 제어할 수 있는 두 가지뿐입니다. 이제 이 기기를 떠날 픽셀에 카나리아가 있는가. 로컬 도구로 바꿨을 때 요청 본문에 원문이 나오면 안 되는가. 실제 운영 비밀번호를 「확인하려고」 어떤 이미지 호스트에도 보내지 마세요.
- 버려도 되는 카나리아를 준비합니다. 예는
canary-fp-20260920-gyazo-ocr. 빈 메모장이나 로컬 HTML에 치고, 그것을 찍습니다. 실제 호스트 이름이나 키를 섞지 마세요. - 스크린샷을 확대해 픽셀 단위로 봅니다. 카나리아가 화면에 전부 들어갔는가. 주변에 상태 표시줄 알림, 다른 비밀번호 칸, 터미널의 옛 명령은 없는가. 사람이 읽을 수 있는 글자는 OCR도 텍스트로 거둘 수 있습니다.
- 그래도 이미지 호스트를 쓴다면, 개발자 도구의 Network를 열고 Preserve log를 켠 뒤 올립니다. 요청 본문을 카나리아로 검색합니다. 이미지 호스트가 올리는 것은 이미지 바이트이므로, 카나리아는 파일로 들어갑니다. 「비밀번호 해시」 열에는 들어가지 않습니다. 이것이 핵심입니다. 해시는 이 한 장을 덮지 않습니다.
- 다른 한 갈래를 대조합니다. 열람 후 파기를 열고, 같은 카나리아를 텍스트로 쓴 뒤 링크를 만듭니다. 다시 Network를 검색합니다.
POST /secrets본문에 있어야 하는 것은 암호문, 만료, 열람 횟수입니다. 원문도, 해시 뒤의 키도 나오면 안 됩니다. 링크 형태는s.html?id={id}#{key}이며, 키는#뒤에만 있습니다. RFC 9110은 요청의 대상 URI에 프래그먼트를 넣지 않는다고 적습니다.
앞의 세 항은, 스크린샷 경로에서는 비밀이 픽셀로, 그리고 호스트가 뽑아낼 수 있는 글자로 이 기기를 떠난다는 점을 보여 줍니다. 네 번째 항은 같은 카나리아를 「이 기기의 AES-256-GCM, 올라가는 것은 암호문만」으로 바꿀 수 있다는 점을 보여 줍니다. 두 갈래를 섞지 마세요. 먼저 이미지 호스트에 올리고 그 직링크를 열람 후 파기에 붙이지 않습니다. 열람 후 파기의 전체 URL을 찍어 그 그림을 이미지 호스트로 되돌리지도 않습니다.
전체 링크와 암호문을 같은 경로로 보내지 마세요. 이미지 호스트가 나르는 것은 픽셀입니다. 열람 후 파기가 나르는 것은 암호문과 # 키입니다. 열쇠를 같은 그림에 찍거나, s.html?id=…#… 전체를 이미지 제목에 쓰면, 해시 뒤의 보호는 그 그림이나 그 메타데이터를 볼 수 있는 사람에게 이미 없습니다.
「이미지 호스트는 안전하다」를 너무 넓게 읽는 세 가지
첫째, 「비공개」를 접근 제어로 읽는 일입니다. 화면에 안 나오는 것은, 제품이 공개 목록에 두지 않았다는 뜻뿐입니다. 이미지 ID가 데이터베이스에 있고 직링크 규칙이 공개라면, 공유하지 않은 그림도 조립됩니다. 이번 공지의 「비공개 목록이 가져가졌다」는 이 읽기에 대한 반례입니다. 한 회사만의 구현 버릇이 아닙니다.
둘째, 비밀번호 변경을 스크린샷 속 비밀의 교체로 읽는 일입니다. 호스트 쪽 로그인, 세션 ID, 제삼자 OAuth 토큰, 화면의 운영 키는 다른 시스템입니다. 공식 안내가 요청하는 Gyazo 비밀번호와 재사용한 같은 비밀번호의 변경은 앞의 몇 항만 덮습니다. 운영 콘솔을 찍었다면 원래 시스템에서 키를 폐기하고, 데이터베이스 계정을 바꾸고, 복구 코드를 무효로 하세요. 로컬 비밀번호 강도 검사가 대조할 수 있는 것은 공개된 고빈도 취약 비밀번호 목록뿐입니다. 어떤 문자열이 이미지 호스트 OCR 테이블에 들어가지 않았다는 증명이 되지 않습니다.
셋째, 「찍은 것은 오류이지 비밀번호가 아니다」를 화면이 깨끗하다고 읽는 일입니다. 터미널의 접속 문자열, 주소창의 token=, 알림의 인증 코드, 옆 창의 받은편지함은 같은 한 장에 들어갑니다. OCR은 당신의 의도로 걸러 주지 않습니다. 올리기 전에 볼 수 있는 것은 이제 보낼 그 한 장뿐입니다. 파일 이름을 error.png로 지어도 도움이 되지 않습니다.
자주 묻는 질문
이미지 호스트가 비밀번호를 해시로 저장한다면, 스크린샷 속 비밀번호도 안전한가요?
다른 층입니다. 로그인 비밀번호 해시가 지키는 것은 그 서비스의 계정 비밀번호뿐입니다. 알고리즘과 솔트 유무에도 달려 있습니다. 스크린샷을 올린 뒤, 이미지 호스트는 OCR 텍스트, 이미지 ID, 업로드 출발 IP, EXIF를 따로 가질 수 있습니다. 화면에 찍힌 비밀번호, 키, 접속 문자열은 OCR 칸에서 이미 검색 가능한 평문인 경우가 많습니다.
비공개이고 한 번도 공유하지 않은 스크린샷은 나만 열 수 있나요?
「비공개」는 대개 제품 화면이 공개 페이지에 올려 두지 않았다는 뜻입니다. 다른 사람이 주소를 조립하지 못한다는 뜻이 아닙니다. 이미지 ID는 이미지 URL을 구성하는 정보입니다. ID가 메타데이터와 함께 밖으로 나가면, 비공개 직링크는 「추측할 수 없다」로는 지키지 못합니다. 운영이 배포를 멈춰도 말할 수 있는 것은, 지금은 일부 ID로 픽셀을 가져가지 못한다는 것뿐입니다. 과거 메타데이터가 한 번도 복사되지 않았다는 뜻은 아닙니다.
이미지 호스트 로그인 비밀번호를 바꾸면, 스크린샷에 찍힌 비밀은 교체하지 않아도 되나요?
나눠서 다루세요. 호스트 쪽 비밀번호 변경이 끊는 것은 그 한 곳의 로그인뿐입니다. 이미 새어 나간 세션 ID는 막지 못합니다. 스크린샷에 찍힌 데이터베이스 비밀번호, API Key, SSH 비밀키, 복구 코드는 원래 시스템에서 교체하세요. 호스트 쪽 비밀번호 변경으로 대신할 수 없습니다. 같거나 비슷한 비밀번호를 재사용했다면 공식 안내대로 그쪽도 바꾸세요.
한 번만 쓸 비밀번호를 스크린샷으로 찍어 동료에게 보내도 되나요?
살아있는 비밀번호를 이미지 호스트나 카카오톡 앨범에 넣지 마세요. 짧은 글은 지금 연 탭에서 AES-256-GCM으로 암호화한 뒤 열람 후 파기로 보내고, 키는 URL의 # 뒤에 둡니다. 형태는 s.html?id={id}#{key}입니다. 만들기와 읽기 모두 열어 바로 쓰며 계정은 필요 없습니다. 32 KB를 넘는 자료는 파일 암호화로 넘기세요. 한 파일은 5 GB까지, 출력은 .lock / .enc. 열람 후 파기를 클라우드 드라이브처럼 쓰지 마세요.
같은 카나리아를 열어 바로 쓰는 경로로 옮기기
계산 경계가 글로 적혀 있는 페이지에서 연습하려면 FastPwd의 열람 후 파기를 열면 됩니다. 가입은 필요 없습니다. 위의 카나리아를 쓰고 열람 횟수는 1로 둔 채 링크를 만든 뒤, 네 번째 절대로 Network를 대조하세요. 본문에 있어야 하는 것은 암호문이며, 원문이나 해시 뒤의 키가 아닙니다. 짧은 비밀번호를 동료에게 넘겨야 할 때만 이 경로를 쓰세요. 먼저 찍지 마세요.
화면에 티켓 본문, 휴대폰 번호, 주민등록번호가 남아 있다면 먼저 링크 정리에서 규칙 마스킹을 하고, 보낼지를 정하세요. 마스킹은 이 기기에서 끝납니다. 원문은 업무 데이터로 올리지 않으며, 접속 분석에도 쓰지 않습니다. 난수 비밀번호는 먼저 비밀번호 생성기에서 이 기기로 만들 수 있습니다. 길이는 6–128자, 기본값은 16자이며, 8자 미만이면 보안이 낮다고 알려 줍니다. 생성 과정은 올리지 않습니다. 스크린샷 파일째 밖으로 내야 한다면 먼저 파일 암호화에서 암호문으로 만들고, 비밀번호는 열람 후 파기로만 보내세요. 이미지 호스트 제목에 적지 마세요.
다음에 찍기 전에 세 가지만 기억하세요. 첫째, 해시가 덮는 것은 호스트 쪽 로그인이지 화면과 OCR이 아닙니다. 둘째, 이미지 ID가 있는 한 비공개 직링크는 접근 제어가 아닙니다. 셋째, 반복해서 관찰할 수 있는 것은 올리기 전 픽셀 단위 확인과, 암호문 경로로 바꿨을 때 카나리아로 Network를 검색하는 일입니다. 인수인계 메모에 적어도 되는 것은 이 세 문장입니다. 「호스트가 비밀번호는 해시라고 했으니 스크린샷은 괜찮다」는 적을 수 없습니다.
더 읽을거리
열람 후 파기가 지우는 것은 서버의 암호문이며, 상대가 스크린샷을 안 찍었다는 증명이 되지 않습니다. 열람 후 파기는 서버가 암호문을 삭제한 것은 증명해도, 상대가 스크린샷을 안 찍은 것은 증명하지 못한다. 클라우드에 올리기 전 압축파일 비밀번호는 파일 이름을 막지 못하며, 이 기기의 AES-GCM도 아닙니다. 클라우드에 올리기 전, 압축파일 비밀번호가 막는 범위와 그것이 기기 AES-256-GCM이 아닌 이유. 「로컬 암호화, 올리지 않음」은 카나리아로 Network를 검색하기 전에는 증거가 되지 않습니다. 브라우저 로컬 암호화에서 원문이 이 기기를 떠나지 않았는지 확인하는 방법.