search_path 하이재킹: 들어본 적 없는 PostgreSQL 공격

발행: (2026년 1월 3일 오전 04:49 GMT+9)
4 min read
원문: Dev.to

Source: Dev.to

대부분의 개발자는 SQL 인젝션에 대해 알고 있습니다. 하지만 search_path 하이재킹에 대해서는 거의 모릅니다.

위험성은 똑같습니다.

search_path란?

PostgreSQL의 search_path스키마를 지정하지 않은 테이블 이름을 참조할 때 어느 스키마를 검색할지 결정합니다.

-- search_path = public 일 때, 아래 두 문장은 동일합니다:
SELECT * FROM users;
SELECT * FROM public.users;

공격

공격자가 search_path를 제어할 수 있다면, 여러분의 쿼리를 악의적인 테이블로 리다이렉트할 수 있습니다:

// ❌ 사용자 입력으로부터 동적으로 설정된 search_path
const schema = req.query.tenant; // 공격자가 제어함
await client.query(`SET search_path TO ${schema}`);
await client.query('SELECT * FROM users'); // 이제 공격자의 스키마를 조회함

동작 방식

  1. 공격자는 악성 users 테이블을 가진 스키마를 생성합니다.
  2. 공격자는 search_path를 자신의 스키마로 설정합니다.
  3. 여러분의 쿼리는 가짜 데이터를 반환합니다.

왜 중요한가?

공격 종류영향
데이터 탈취가짜 데이터를 반환하고 입력을 수집함
권한 상승보안 함수를 교체함
코드 실행악성 트리거·함수를 실행함

올바른 패턴

// ✅ 정적인 search_path
await client.query(`SET search_path TO tenant_${tenantId}`);

// ✅ 허용 목록을 통한 검증
const ALLOWED_SCHEMAS = ['tenant_1', 'tenant_2', 'tenant_3'];
if (!ALLOWED_SCHEMAS.includes(schema)) {
  throw new Error('Invalid schema');
}
await client.query(`SET search_path TO ${schema}`);

// ✅ 완전한 스키마 지정 테이블 이름
await client.query('SELECT * FROM public.users'); // 스키마를 명시

ESLint로 잡아내기

npm install --save-dev eslint-plugin-pg
import pg from 'eslint-plugin-pg';
export default [pg.configs.recommended];

동적 search_path는 다음과 같이 감지됩니다:

src/tenants.ts
  8:15  error  🔒 CWE-426 | Dynamic search_path detected
               Fix: Use static schema name or validate against allowlist

다중 테넌트 패턴

// ✅ 검증된 스키마를 사용한 안전한 다중 테넌트
async function queryTenant(tenantId, sql, params) {
  // 테넌트 존재 여부 검증
  const tenant = await getTenant(tenantId);
  if (!tenant) throw new Error('Unknown tenant');

  const client = await pool.connect();
  try {
    // 사용자 입력이 아닌 신뢰할 수 있는 소스에서 스키마 이름을 가져옴
    await client.query(`SET search_path TO tenant_${tenant.id}`);
    return await client.query(sql, params);
  } finally {
    // search_path 초기화
    await client.query('SET search_path TO public');
    client.release();
  }
}

빠른 설치

npm install --save-dev eslint-plugin-pg
import pg from 'eslint-plugin-pg';
export default [pg.configs.recommended];

공격자가 여러분의 쿼리를 하이재킹하지 못하도록 하세요.

Back to Blog

관련 글

더 보기 »

eslint-plugin-pg 시작하기

빠른 설치 bash npm install --save-dev eslint-plugin-pg Flat Config js // eslint.config.js import pg from 'eslint-plugin-pg'; export default pg.configs.reco...