← 전체 글

민감한 JSON을 온라인 도구에 붙여 넣지 말아야 하는 이유

JWT 토큰, API 키, PII, 데이터베이스 익스포트가 온라인 포매터에 일상적으로 붙여진다. 서버 측에서 그 데이터에 무엇이 일어나는지 —— 그리고 브라우저 네이티브 도구가 더 안전한 이유.

한 개발자가 파싱 오류에 부딪혀, API 응답에서 JSON 을 복사해 Google 에서 가장 먼저 뜬 온라인 포매터에 붙여넣습니다. 그 JSON 에는 사용자 ID, 이메일 주소, 세션 토큰, 또는 내부 설정 파일이 들어 있습니다. 이런 일이 모든 엔지니어링 팀에서 매일 수십 번씩 일어납니다. 이 글은 정확히 어떤 위험이 생기는지 —— 그리고 왜 브라우저 네이티브 도구가 그 위험을 없애는지를 설명합니다.

온라인 JSON 도구에 결국 들어가는 데이터 종류

실제로 개발자는 당장 문제가 되는 것을 무엇이든 붙여 넣습니다. 즉:

  • JWT 토큰 —— 사용자 identity claim, 역할, 만료 시각이 들어 있습니다. 서명이 변조를 막지만 payload 는 Base64url 로 인코딩된 평문: 당신의 토큰을 로그로 남긴 사람은 누구나 모든 필드를 읽을 수 있습니다.
  • PII 가 든 API 응답 —— 이름, 이메일, 전화, 생년월일, 주소. 고객용 API 검색 결과 한 페이지에 수백 건이 들어 있을 수 있습니다.
  • 설정 파일 —— DB 연결 문자열, 서드파티 API 키, 피처 플래그 설정, 내부 서비스 URL.
  • 데이터베이스 익스포트 —— 테이블 전체의 JSON dump. 디버깅용으로 만들어 그대로 붙여 넣기도 합니다.
  • 내부 비즈니스 데이터 —— 가격 규칙, 계약 조건, 출시 전 제품 데이터. 공식 분류는 없어도 여전히 민감합니다.

그 순간엔 어느 것도 민감하게 느껴지지 않습니다. 개발자는 구조를 이해하고 싶지 데이터를 공유하려는 게 아닙니다. 하지만 온라인 도구에 붙이는 행위는 기술적으로 제 3 자에게 전송하는 것과 구분되지 않습니다.

온라인 도구에 데이터를 제출하면 어떤 일이 일어나는가

대부분의 온라인 포매터, 검증기, diff 도구는 입력을 서버 endpoint 로 보내 거기서 처리하고 결과를 돌려주는 방식으로 동작합니다. "클라이언트 사이드" 라고 주장하는 도구조차 로그, analytics, 오류 추적 목적으로 데이터를 보내기도 합니다. 그 경로에서 데이터가 거치는 일들:

서버 측 로깅

많은 프레임워크는 기본적으로 web server 가 요청 body 를 로그에 남깁니다. 당신의 JSON payload 를 담은 한 번의 POST 가 다음에 도달할 수 있습니다:

  • 디스크나 로깅 서비스(Datadog, Splunk, CloudWatch)에 저장된 애플리케이션 로그
  • 오류 추적 도구(Sentry, Bugsnag) —— 특히 파싱 실패 시
  • "analytics" 또는 "usage" 테이블의 한 행
  • 도구 운영자가 모니터링조차 안 할 수 있는 CDN 또는 load balancer 액세스 로그

로그 보존 정책은 도구마다 천차만별. 어떤 곳은 90 일, 어떤 곳은 무기한. 어느 쪽이든 운영자 —— 그리고 그들의 시스템에 접근한 누구든 —— 가 당신이 제출한 것을 읽을 수 있습니다.

서드파티 analytics

많은 온라인 도구가 analytics 나 광고를 위해 서드파티 JavaScript 를 포함합니다. 이 스크립트들은 네트워크 요청, 폼 제출, 입력 이벤트를 관찰할 수 있습니다. 도구가 데이터를 자체 서버로 보내면 analytics 레이어도 그 HTTP 트랜잭션을 볼 수 있습니다.

캐싱과 CDN 저장소

일부 도구는 입력 내용으로 키를 잡아 결과를 캐싱합니다. 두 사용자가 동일한 JSON 을 제출하면 두 번째는 캐시된 응답을 받습니다. 입력은 캐시에 몇 시간에서 며칠 남을 수 있습니다. 극단적인 경우 잘못 설정된 캐시 때문에 사용자 제출물이 예측 가능한 URL 로 공개 접근 가능해진 사례도 있었습니다.

검색 엔진 인덱싱

공유 가능한 permalink(당신이 포매팅한 JSON 을 포함하거나 참조하는 URL) 를 만드는 포매터는 역사적으로 검색 엔진이 출력을 크롤링한 적이 있습니다. 내부 설정 파일의 특이한 문자열을 검색하다 어느 JSON 포매터 도메인에서 발견하는 것은 매우 불편한 경험입니다.

규제 노출

조직이 GDPR, HIPAA, CCPA 또는 유사한 프레임워크 아래 개인 데이터를 처리한다면, 사용자 데이터를 서드파티 온라인 도구에 붙이는 것 자체가 무단 데이터 전송에 해당할 수 있습니다 —— 우발적이고 도구가 평판이 좋더라도. 프레임워크는 의도적 공유와 부주의한 도구 선택을 구분하지 않습니다. 묻는 것은 이것뿐: 개인 데이터가 허가된 처리 경계를 벗어났는가?

HIPAA 대상 기관에 한해 말하면, BAA 가 서명되지 않은 서드파티 서비스로 보호 대상 보건 정보를 보내는 것은 데이터 오남용 여부와 무관하게 보고 의무가 있는 위반입니다.

브라우저 네이티브 도구가 왜 다른가

현대 브라우저는 네트워크 요청 없이 JavaScript 엔진 안에서 복잡한 로직 —— 파싱, 검증, diff, 포매팅, 인코딩 —— 을 전부 실행할 수 있습니다. 이 모델로 만든 도구는 마침 웹으로 배포되는 로컬 앱처럼 동작합니다.

브라우저 네이티브 도구에 JSON 을 붙이면:

  • 텍스트는 브라우저 메모리의 JavaScript 변수로 들어갑니다.
  • 파서(역시 JavaScript)가 같은 탭 안에서 처리합니다.
  • 출력은 DOM 에 렌더링됩니다.
  • 당신의 데이터를 payload 로 실은 HTTP 요청은 어떤 서버에도 가지 않습니다.

데이터는 기기를 떠난 적이 없습니다. 전송된 적이 없으니 로깅, 캐싱, 인덱싱될 수도 없습니다.

도구가 정말 로컬인지 확인하는 방법

"당신의 데이터를 절대 저장하지 않습니다" 같은 주장은 흔하고 외부에서 검증할 수 없습니다. 신뢰할 수 있는 유일한 검사는 브라우저의 Network 패널:

  1. DevTools 를 엽니다(F12 또는 Cmd+Option+I).
  2. Network 탭으로 가서 Preserve log 를 체크합니다.
  3. JSON 을 도구에 붙이고 작업을 실행합니다(포매트, 검증 등).
  4. XHR/Fetch 로 요청을 필터링합니다. 당신의 입력을 payload 로 실어 보내는 outbound 요청이 있다면, 그 도구는 클라이언트 사이드가 아닙니다.

진짜 로컬 도구는 당신의 데이터가 실린 outbound POST 나 fetch 가 보이지 않습니다. 정적 자산(CSS, JS 파일) 요청이나 analytics ping 은 보일 수 있지만, 그 어떤 것도 당신의 JSON payload 를 담지 않습니다.

// 로컬 도구가 하는 일 —— 네트워크 호출 없음:
const result = JSON.parse(userInput);   // 브라우저 안에서 실행
render(result);                         // DOM 업데이트

// 서버 사이드 도구가 하는 일:
const res = await fetch('/api/format', {
  method: 'POST',
  body: JSON.stringify({ input: userInput }),  // 데이터가 기기를 떠난다
});

실용 패턴: BAA, WebCrypto, 그리고 마스킹 헬퍼

세 가지 패턴이 남은 위험의 대부분을 막아 줍니다:

  • HIPAA 와 관련된 작업을 위한 BAA(Business Associate Agreement) —— 팀이 보호 대상 보건 정보를 다룬다면, 그것에 닿는 모든 서드파티 서비스는 서명된 BAA 가 미리 있어야 합니다. 그래서 "로컬에서 동작한다" 는 임의의 포매터에 PHI 를 붙이는 일이 기술 문제이자 문서 문제이기도 한 것입니다.
  • 클라이언트 사이드 WebCrypto —— 브라우저에서 해시, 서명, 암복호화, 키 생성이 정말 필요할 때 표준 crypto.subtle API 가 서버 왕복 없이 해줍니다. 암호문을 어디로도 보내지 않으면서 "이 payload 를 복호화해서 보고 싶다" 를 위한 옳은 프리미티브입니다.
  • 마스킹 헬퍼 —— 디버깅 시, 알려진 민감 key(password, token, email, ssn)의 값을 마스킹하는 작은 redactor 를 거치고 나서 어디든 붙이세요. 20 줄짜리 함수가 analytics 도구의 요청 로그에서 토큰을 발견하는 것보다 훨씬 낫습니다.

팀에서 둘 만한 정책

개인의 의식엔 한계가 있습니다. 가벼운 정책이 그 격차를 메웁니다:

  • 붙이기 전에 분류한다. JSON 에 이름, 이메일, ID, 토큰, 키가 있으면 —— 민감합니다. 로컬 도구나 승인된 사내 도구를 쓰세요.
  • 승인된 도구 목록을 유지한다. 검증된 로컬 우선 도구의 짧은 목록이 막연한 "조심하라" 규칙보다 따르기 쉽습니다.
  • 디버깅 세션에서 운영 자격 증명을 절대 공유하지 않는다. 온라인 도구에 붙었던 토큰이나 키는 도구가 안전해 보여도 모두 로테이션.
  • 디버깅엔 가공된 샘플을 쓴다. 붙이기 전에 실제 사용자 값을 합성 데이터로 치환. "email": "test@example.com" 가 들어간 구조도 파싱 오류 디버깅에는 실제 주소와 똑같이 유용합니다.

자주 묻는 질문

민감한 JSON 을 온라인 도구에 붙여도 안전한가요?

도구가 모든 것을 브라우저 안에서 처리할 때만요. 서버 사이드 포매터는 입력을 로깅, 캐싱, 인덱싱할 수 있고 —— PII 를 서드파티에 붙이는 것 자체가 의도와 상관없이 GDPR 이나 HIPAA 위반일 수 있습니다.

JSON 도구가 로컬에서 도는지 어떻게 확인하나요?

DevTools → Network 를 열고 "Preserve log" 를 체크한 뒤 작업을 실행하세요. 당신의 입력을 payload 로 싣고 나가는 요청이 없으면 클라이언트 사이드입니다. 정적 자산이나 analytics 요청은 괜찮고, 당신의 JSON 을 담은 POST 는 곤란합니다.

토큰을 이미 온라인 도구에 붙여 버렸으면 어떻게 해야 하나요?

로테이트하세요. 서드파티 도구에 닿은 자격 증명이나 키는 도구가 평판이 좋아 보여도 침해된 것으로 간주합니다. Base64 로 인코딩된 토큰은 여전히 평문 임을 기억하세요.

팀에서 이걸 완전히 피하려면 어떻게 해야 하나요?

브라우저 네이티브 도구를 쓰고, 승인된 도구 목록을 두고, 실제 레코드 대신 가공된 샘플 데이터("email": "test@example.com")로 디버깅하세요.

fixjson.org 가 하는 일

fixjson.org 의 모든 도구 —— JSON 수리, JSON diff, YAML 포매터, JSON Stringify, Base64 인/디코딩, URL 디코드 —— 는 전부 브라우저 안에서 동작합니다. 파서, diff 엔진, 포매터 모두 로컬에서 실행되는 JavaScript 입니다. Network 탭에서 확인할 수 있습니다: 당신의 입력을 실어 가는 POST 요청은 없습니다.

사이트는 CDN 에서 정적 자산(HTML, CSS, JS)을 한 번 로드합니다. 그 이후엔 오프라인에서도 동작합니다. 어떤 입력도 어떤 서버에도 가지 않습니다. 어떤 데이터도 로깅, 저장, 공유되지 않습니다.

  • JSON Fix —— 잘못된 JSON 을 클라이언트 사이드에서 수리하고 포매팅
  • JSON Diff —— 두 개의 JSON 또는 YAML 문서를 클라이언트 사이드에서 비교
  • Base64 인코딩 & 디코딩 —— JWT payload 와 data URI 를 어디에도 보내지 않고 검사
  • URL Decode —— 쿼리 문자열을 로컬에서 percent 디코드
  • Base64 는 암호화가 아니다 —— 인코딩된 데이터가 문자열을 가진 누구든 읽을 수 있는 이유