본문 바로가기
일반IT/AI

임베딩 벡터를 역분석하면 원문이 그대로 복원될까?

by gasbugs 2026. 7. 13.
반응형

LLM과 RAG 시스템에서는 문서나 대화 내용을 검색하기 위해 임베딩을 사용한다.

예를 들어 다음과 같은 문장이 있다고 해보자.

"고객사 A와 1억 원 규모의 보안 교육 계약을 체결했다."

 

임베딩 모델은 이 문장을 다음과 같은 숫자 배열로 변환한다.

[0.132, -0.847, 0.291, ...]

 

이 숫자 배열이 바로 임베딩 벡터다.

이 때문에 종종 다음과 같은 질문이 나온다.

임베딩 벡터를 확보하면 역분석을 통해 원문을 그대로 복원할 수 있는가?

 

결론부터 말하면, 임베딩 벡터만으로 원문이 자동으로 그대로 복원되는 것은 아니다.

하지만 공격자가 임베딩 모델과 후보 데이터, 검색 API, 메타데이터 등을 함께 확보한 경우에는 원문의 의미나 특정 속성을 상당 부분 추론할 수 있다.


임베딩은 암호화 데이터가 아니다

임베딩은 텍스트를 암호화한 결과가 아니다.

암호화는 정상적인 복호화 키가 있으면 원문을 정확히 복원할 수 있도록 설계된다.

 

반면 임베딩은 문장의 의미적 특징을 고차원 숫자 공간에 표현한 것이다.

원문 텍스트
    ↓
임베딩 모델
    ↓
벡터

 

따라서 일반적으로 다음과 같은 역변환 관계는 성립하지 않는다.

벡터
  ↓
단순 역계산
  ↓
정확한 원문

 

임베딩 과정에서는 단어 순서, 표현 방식, 문장 구조와 같은 정보 일부가 손실될 수 있다.

예를 들어 다음 두 문장은 서로 다른 문장이지만 비슷한 벡터를 가질 수 있다.

"고객사 A와 1억 원 규모의 계약을 체결했다."

"A사와 약 1억 원 상당의 계약을 맺었다."

 

의미가 비슷하기 때문에 임베딩 공간에서도 가까운 위치에 배치될 가능성이 높다.


RAG에서 원문이 검색되는 이유

RAG 시스템에서 벡터 검색 결과로 원문이 출력되는 것을 보고, 벡터가 원문으로 역변환된다고 오해할 수 있다.

하지만 실제 구조는 보통 다음과 같다.

원문 문서 ──────────────┐
                       │
                       ├─ 문서 저장소
                       │
                       └─ 임베딩 생성 → 벡터 DB

 

검색 과정은 다음과 같다.

사용자 질문
   ↓
질문 임베딩 생성
   ↓
벡터 DB에서 유사 벡터 검색
   ↓
벡터에 연결된 문서 ID 확인
   ↓
문서 저장소에서 원문 조회

 

즉 원문이 나오는 이유는 벡터를 복원했기 때문이 아니라, 벡터에 연결된 원문이나 문서 조각을 다시 가져왔기 때문이다.

실제 벡터 DB에는 다음과 같은 데이터가 저장될 수 있다.

{
  "id": "doc-1042",
  "vector": [0.132, -0.847, 0.291],
  "metadata": {
    "user_id": "user-a",
    "source": "contract-document",
    "text": "고객사 A와 1억 원 규모의 계약을 체결했다."
  }
}

 

이 구조에서 공격자가 메타데이터나 원문 필드에 접근할 수 있다면 임베딩을 역분석할 필요조차 없다.

따라서 실무에서는 임베딩 복원 공격보다 벡터 DB 접근통제 실패가 더 직접적인 위험이 될 수 있다.


임베딩 벡터를 역분석하는 대표적인 방법

1. 후보 문장 비교 공격

가장 단순한 방식은 공격자가 예상 가능한 후보 문장을 여러 개 만든 뒤 동일한 임베딩 모델로 벡터화하는 것이다.

탈취한 벡터
    ↕ 코사인 유사도 비교
후보 문장 벡터

 

예를 들어 공격자가 다음과 같은 후보를 준비할 수 있다.

"고객사는 삼성SDS다."
"고객사는 LG CNS다."
"고객사는 SK C&C다."

 

각 문장을 임베딩한 뒤 탈취한 벡터와 비교한다.

가장 유사도가 높은 후보를 통해 원문에 포함된 내용을 추론할 수 있다.

 

이 공격은 다음 조건에서 특히 유효하다.

  • 임베딩 모델을 알고 있는 경우
  • 후보 문장의 범위가 좁은 경우
  • 문장이 짧고 정형화된 경우
  • 이름, 회사명, 질병명처럼 선택지가 제한된 경우
  • 공격자가 동일한 임베딩 API를 호출할 수 있는 경우

예를 들어 계약 상태가 다음 세 가지 중 하나라는 사실을 알고 있다면 추론이 쉬워진다.

계약 체결
계약 검토
계약 취소

 

원문 전체를 복원하지 못하더라도 어떤 상태인지 식별할 수 있다.


2. 최근접 이웃 사전 공격

공격자가 대량의 문장이나 문서를 미리 임베딩해 사전을 만들 수도 있다.

문장 사전
   ↓
대량 임베딩 생성
   ↓
벡터 인덱스 구축
   ↓
탈취한 벡터와 최근접 문장 검색

 

예를 들어 다음과 같은 후보 데이터가 있을 수 있다.

candidate_texts = [
    "관리자 비밀번호가 변경되었습니다.",
    "고객의 주민등록번호가 포함되어 있습니다.",
    "계약 금액은 1억 원입니다.",
    "보안 교육 계약이 취소되었습니다."
]

 

공격자는 이 후보들을 임베딩한 뒤 탈취한 벡터와 가장 가까운 문장을 찾는다.

이 방식은 다음과 같은 데이터에서 성공 가능성이 높다.

  • 표준 계약서
  • 이메일 템플릿
  • 고객 상담 문구
  • 인사 평가 양식
  • 진료 기록 코드
  • 공개된 기술 문서
  • 반복적으로 사용되는 사내 문서

원문이 기존 공개 문서나 표준 문구와 유사하다면 최근접 문장 검색만으로도 상당한 정보를 얻을 수 있다.


3. 임베딩 역변환 모델

공격자가 별도의 디코더 모델을 학습하는 방법도 있다.

공격자는 대량의 텍스트와 임베딩 벡터 쌍을 준비한다.

텍스트 → 임베딩 모델 → 벡터

 

그다음 다음과 같은 역방향 모델을 학습한다.

벡터 → 디코더 모델 → 텍스트 추정

 

학습 데이터가 충분하다면 벡터를 입력받아 원문과 유사한 문장을 생성할 수 있다.

예를 들어 원문이 다음과 같다고 해보자.

"고객사 A와 1억 원 규모의 보안 교육 계약을 체결했다."

 

복원 결과는 다음과 같이 나올 수 있다.

"A사와 약 1억 원 규모의 보안 교육 계약을 맺었다."

 

완전히 같은 문장은 아니지만 핵심 의미는 상당 부분 복원될 수 있다.

이 때문에 임베딩 역분석은 정확한 문자열 복구보다는 의미 복원에 가깝다.


4. 속성 추론 공격

공격자는 원문 전체를 복원하지 않고 특정 속성만 알아내려고 할 수 있다.

예를 들어 다음과 같은 질문이다.

이 벡터에는 금융정보가 포함되어 있는가?
특정 회사명이 들어 있는가?
질병 관련 내용인가?
계약 금액이 포함되어 있는가?
보안 사고 내용인가?

 

공격자는 벡터를 입력으로 받는 분류기를 학습할 수 있다.

Embedding
    ↓
속성 분류기
    ↓
"금융정보 포함 확률 92%"

 

이 방식은 원문 전체 복원보다 현실적일 수 있다.

실제 공격자는 모든 문장을 알아낼 필요가 없다.

예를 들어 다음 정보만 알아내도 문제가 될 수 있다.

  • 특정 질병의 존재 여부
  • 특정 기업과의 계약 여부
  • 개인정보 포함 여부
  • 보안 사고 발생 여부
  • 내부 프로젝트 참여 여부
  • 특정 기술 사용 여부

이런 유형을 속성 추론 공격이라고 한다.


5. 멤버십 추론 공격

멤버십 추론은 특정 데이터가 벡터 저장소에 포함되어 있는지를 확인하는 공격이다.

예를 들어 공격자는 다음을 알고 싶어 할 수 있다.

"A사 계약서가 이 데이터베이스에 존재하는가?"
"특정 직원의 인사평가 문서가 포함되어 있는가?"
"특정 환자의 진료기록이 학습 또는 검색 데이터에 들어 있는가?"

 

원문을 직접 확인하지 못하더라도 데이터의 존재 여부 자체가 민감정보가 될 수 있다.

예를 들어 어떤 회사가 특정 보안 사고를 조사하고 있다는 사실만 노출되어도 문제가 될 수 있다.


6. 검색 API를 이용한 반복 추론

공격자가 벡터 자체에 접근하지 못해도 검색 API를 반복 호출하면서 정보를 추론할 수 있다.

예를 들어 다음과 같은 질문을 반복한다.

"A사와 계약했는가?"
"A사 계약 금액은 1억 원 이상인가?"
"A사 계약은 교육 계약인가?"
"A사 계약 시점은 2026년인가?"

 

검색 결과 순위나 유사도 점수가 제공된다면 공격자는 질문을 조금씩 바꿔가며 정보를 좁힐 수 있다.

질문 변경
   ↓
유사도 점수 확인
   ↓
더 높은 점수가 나오는 방향 탐색
   ↓
원문 의미 추정

 

이러한 구조를 검색 오라클 또는 유사도 오라클로 볼 수 있다.

특히 API가 다음 정보를 노출할 경우 위험이 커진다.

  • 상세 유사도 점수
  • 검색 순위
  • 문서 ID
  • 메타데이터
  • 검색된 문서 개수
  • 필터링 전후 결과 차이

7. 좌표 최적화 기반 공격

공격자는 임의의 문장을 만든 뒤 단어나 표현을 조금씩 변경하면서 목표 벡터에 가까워지는 방향을 찾을 수 있다.

초기 문장 생성
   ↓
단어 또는 문장 구조 변경
   ↓
임베딩 생성
   ↓
목표 벡터와 유사도 측정
   ↓
유사도가 높아지는 변경 유지

 

예를 들어 처음에는 다음 문장에서 시작할 수 있다.

"어떤 회사와 계약했다."

 

이후 다음과 같이 조금씩 바꾼다.

"A사와 계약했다."
"A사와 교육 계약을 체결했다."
"A사와 1억 원 규모의 교육 계약을 체결했다."

 

유사도 점수가 계속 높아진다면 원문과 가까운 의미를 가진 문장을 찾을 수 있다.

API가 정밀한 유사도 점수를 제공할수록 이러한 최적화 공격이 쉬워질 수 있다.


8. 메타데이터와 원문 연결정보 탈취

실무적으로는 이것이 가장 직접적인 공격이다.

벡터 DB에는 임베딩만 저장되는 것이 아니라 다음과 같은 메타데이터가 함께 저장될 수 있다.

{
  "vector": [0.132, -0.847, 0.291],
  "metadata": {
    "tenant_id": "company-a",
    "user_id": "user-1004",
    "document_name": "2026-contract.pdf",
    "chunk_text": "계약 금액은 1억 원이다."
  }
}

 

이 경우 공격자는 임베딩을 역분석할 필요가 없다.

벡터 DB의 읽기 권한만 확보하면 다음 정보가 직접 노출될 수 있다.

  • 원문 청크
  • 사용자 ID
  • 테넌트 ID
  • 파일명
  • 저장 위치
  • 문서 제목
  • 작성자
  • 대화 ID
  • 문서 URL

따라서 벡터 DB는 단순 검색 인덱스가 아니라 민감정보 저장소로 봐야 한다.


임베딩 역분석이 쉬워지는 조건

임베딩 벡터가 노출됐다고 해서 항상 원문이 복원되는 것은 아니다.

하지만 다음 조건이 많을수록 공격 성공 가능성이 높아진다.

동일한 임베딩 모델을 알고 있는 경우

공격자가 사용 중인 모델을 알고 있다면 후보 문장들을 같은 방식으로 벡터화할 수 있다.

예를 들어 모델명, 차원 수, 정규화 방식이 공개되어 있다면 비교 공격이 쉬워진다.

임베딩 API를 자유롭게 사용할 수 있는 경우

공격자가 무제한으로 임베딩을 생성할 수 있다면 다양한 후보 문장을 반복해서 비교할 수 있다.

원문 후보 범위가 좁은 경우

다음과 같이 선택지가 제한적이면 추론이 쉽다.

승인
거절
검토 중

 

반대로 자유 형식의 긴 문서라면 정확한 원문 복원은 훨씬 어렵다.

문장이 짧은 경우

짧은 문장은 포함된 정보가 적기 때문에 후보 공간이 줄어든다.

예를 들어 다음 문장은 비교적 추론하기 쉽다.

"계약이 취소되었다."

 

반면 여러 주제가 섞인 긴 문서는 하나의 벡터만으로 정확히 복원하기 어렵다.

청크 크기가 작은 경우

RAG에서는 문서를 짧은 단위로 나누어 저장한다.

문서
  ↓
300~500 토큰 단위 청크
  ↓
각 청크 임베딩

 

청크가 너무 작으면 하나의 벡터가 특정 문장이나 민감정보를 직접적으로 나타낼 수 있다.

메타데이터가 함께 노출된 경우

다음 정보가 함께 있으면 공격자는 후보 범위를 크게 줄일 수 있다.

파일명
부서명
작성자
문서 유형
날짜
고객사명
사용자 ID

유사도 점수를 상세하게 제공하는 경우

유사도 점수가 소수점 단위로 노출되면 공격자가 문장을 조금씩 바꾸면서 목표 벡터에 가까워지는 방향을 찾을 수 있다.


벡터만 있으면 원문이 그대로 나오는가?

정확히 구분할 필요가 있다.

벡터 검색

벡터
  ↓
연결된 문서 ID 확인
  ↓
저장된 원문 조회

이 경우에는 원문을 역분석한 것이 아니다.

벡터에 연결된 원문을 그대로 가져온 것이다.

임베딩 역분석

벡터
  ↓
후보 비교 또는 디코더 분석
  ↓
원문의 의미나 속성 추정

 

이 경우에는 원문을 확률적으로 추론한다.

완전히 동일한 문자열이 나오지 않더라도 핵심 내용이나 민감한 속성이 노출될 수 있다.

따라서 다음과 같이 표현하는 것이 정확하다.

임베딩 벡터를 확보했다고 해서 원문이 자동으로 그대로 복원되는 것은 아니다. 그러나 후보 문장 비교, 속성 추론, 디코더 학습, 검색 API 분석 등을 통해 원문의 의미나 민감한 정보를 추정할 수 있다.


ChatGPT 대화 기록도 벡터로만 저장되는가?

특정 서비스가 대화 기록을 어떤 내부 구조로 저장하는지는 공개된 정보만으로 단정할 수 없다.

대화 히스토리, 메모리, 검색 인덱스가 각각 어떤 데이터베이스 구조로 관리되는지는 서비스 제공자의 내부 설계에 해당한다.

 

따라서 다음과 같이 단정해서는 안 된다.

모든 대화 원문이 임베딩 벡터로만 저장된다.
벡터를 역변환하면 모든 대화가 그대로 나온다.

 

일반적인 서비스에서는 다음 요소가 별도로 존재할 수 있다.

대화 원문 저장소
검색용 임베딩 인덱스
사용자 메모리
메타데이터
로그 및 감사 기록

 

임베딩은 주로 검색과 유사도 비교에 사용되고, 실제 원문은 별도의 저장소에서 관리되는 경우가 많다.


보안 진단에서는 무엇을 확인해야 하는가?

임베딩 역분석 가능성만 확인하는 것으로는 부족하다.

실제 LLM 및 RAG 보안 진단에서는 다음 항목이 더 중요할 수 있다.

사용자 간 데이터 격리

사용자 A가 사용자 B의 문서를 검색할 수 있는지 확인해야 한다.

user_id = A
tenant_id = company-a

 

검색 시 이러한 필터가 누락되면 다른 사용자의 데이터가 노출될 수 있다.

테넌트 단위 접근통제

멀티테넌트 환경에서는 조직별 데이터 분리가 필수다.

tenant-a의 문서
tenant-b의 문서

 

벡터 검색 이후에 권한을 검사하는 것이 아니라 검색 이전부터 접근 범위를 제한해야 한다.

 

메타데이터 최소화

벡터 DB에 원문, 이메일 주소, 주민등록번호, API 키 등을 불필요하게 저장해서는 안 된다.

검색 점수 비공개

상세한 유사도 점수는 공격자의 반복 추론에 활용될 수 있다.

필요하지 않다면 외부 사용자에게 점수를 공개하지 않는 것이 좋다.

질의 횟수 제한

공격자가 수천 번의 후보 문장을 비교하지 못하도록 다음 통제가 필요하다.

Rate limiting
사용자별 요청 제한
이상 질의 탐지
반복 패턴 탐지

임베딩과 원문 모두 암호화

벡터는 원문이 아니지만 민감정보를 포함할 수 있다.

따라서 임베딩 데이터도 원문과 동일한 수준으로 보호해야 한다.

저장 데이터 암호화
전송 구간 암호화
키 관리
접근 로그
권한 분리

마무리

임베딩 벡터는 단순한 무작위 숫자가 아니다.

원문의 의미적 특징을 포함하고 있기 때문에 적절한 보조 정보가 있다면 다음과 같은 공격이 가능하다.

후보 문장 비교
최근접 이웃 검색
임베딩 역변환 모델
속성 추론
멤버십 추론
검색 API 반복 분석
메타데이터 탈취

 

그렇다고 벡터를 뒤집기만 하면 원문이 그대로 나오는 것은 아니다.

보다 정확하게는 다음과 같다.

임베딩은 원문을 직접 복호화할 수 있는 암호문은 아니지만, 공격자가 모델과 후보 데이터, 검색 인터페이스, 메타데이터를 확보하면 원문의 의미나 민감한 속성을 추론할 수 있다.

 

실무적으로는 임베딩 역분석 자체보다 벡터 DB의 접근통제 실패, 테넌트 분리 오류, 메타데이터 노출, 원문 연결정보 유출이 더 직접적인 위험이 될 수 있다.

 

따라서 임베딩 벡터도 단순 검색 데이터가 아니라 원문과 유사한 수준의 민감정보로 취급해야 한다.

반응형