본문 바로가기
DB

[DB]SQL Injection? 암호화? 5분 만에 배우는 DB 보안 핵심 전략!

by 다다면체 2025. 1. 16.
728x90
반응형

데이터베이스 보안은 현대 사회에서 그 중요성이 날로 커지고 있습니다. 소중한 데이터를 안전하게 지키는 것은 개인뿐만 아니라 기업의 신뢰도와 직결되는 문제이기 때문입니다. 이 글에서는 데이터베이스 보안의 핵심 요소인 사용자 및 역할 관리, 데이터 암호화, SQL Injection 방지 방법을 실전 예제와 함께 알기 쉽게 설명해 드리겠습니다. 마치 튼튼한 성을 짓듯이, 단계별로 데이터베이스를 안전하게 구축하는 방법을 함께 알아보시죠!


반응형

1. 철통 보안의 첫걸음: 사용자 및 역할 관리

데이터베이스 보안의 기본은 바로 '최소 권한 원칙'입니다. 즉, 각 사용자에게 필요한 최소한의 권한만 부여하여 혹시 모를 내부 위협까지 방지하는 것입니다. 마치 집 열쇠를 필요한 사람에게만 나눠주는 것과 같은 이치입니다.

  • 사용자와 역할 정의: 사용자와 역할을 명확히 구분하여 권한을 효율적으로 관리합니다.

MySQL 예제:

-- 사용자 생성 (localhost에서만 접속 허용)
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'secure_password';

-- 역할 생성
CREATE ROLE db_read_only;
CREATE ROLE db_admin;

-- 역할에 권한 부여 (my_database의 모든 테이블에 대한 권한 부여)
GRANT SELECT ON my_database.* TO db_read_only;
GRANT ALL PRIVILEGES ON my_database.* TO db_admin;

-- 사용자에게 역할 부여 및 기본 역할 설정
GRANT db_read_only TO 'app_user'@'localhost';
SET DEFAULT ROLE db_read_only FOR 'app_user'@'localhost';

 

Oracle 예제:

-- 사용자 생성
CREATE USER app_user IDENTIFIED BY secure_password;

-- 역할 생성
CREATE ROLE db_read_only;
CREATE ROLE db_admin;

-- 역할에 권한 부여 (my_schema의 my_table에 대한 권한 부여)
GRANT SELECT ON my_schema.my_table TO db_read_only;
GRANT ALL PRIVILEGES ON my_schema.my_table TO db_admin;

-- 사용자에게 역할 부여 및 기본 역할 설정
GRANT db_read_only TO app_user;
ALTER USER app_user DEFAULT ROLE db_read_only;

2. 데이터는 소중하니까: 강력한 암호화

데이터 암호화는 데이터를 마치 비밀 언어로 바꾸는 것과 같습니다. 허가받지 않은 사용자가 데이터를 획득하더라도 내용을 이해할 수 없도록 만들어 2차 피해를 막는 중요한 방어 수단입니다.

 

🚩암호화 유형:

  • 전송 중 암호화 (SSL/TLS): 데이터가 네트워크를 통해 전송될 때 암호화하여 중간에 가로채더라도 내용을 확인할 수 없도록 합니다. HTTPS를 사용하는 웹사이트에서 흔히 볼 수 있습니다.
  • 저장된 데이터 암호화: 데이터베이스 서버의 디스크에 저장된 데이터를 암호화합니다. 서버가 물리적으로 탈취당하더라도 데이터 유출을 막을 수 있습니다.

MySQL 예제 (InnoDB 엔진 사용 시):

ALTER TABLE sensitive_data ENCRYPTION = 'Y';

 

Oracle 예제 (투명한 데이터 암호화 - TDE):

ADMINISTER KEY MANAGEMENT SET KEY IDENTIFIED BY 'encryption_key' WITH BACKUP;
ALTER TABLE sensitive_data ENCRYPT;
  • 데이터 마스킹: 특정 사용자에게 민감한 데이터의 일부 또는 전부를 가려 보여주는 기술입니다. 예를 들어, 신용카드 번호의 일부를 '*'로 가리는 것이 대표적인 예시입니다.

Oracle 예제:

DBMS_REDACT.ADD_POLICY(
    object_schema => 'my_schema',
    object_name   => 'sensitive_table',
    policy_name   => 'mask_policy',
    column_name   => 'credit_card_number',
    expression    => '1=1',
    function_type => DBMS_REDACT.FULL -- 전체 마스킹
);

3. SQL Injection, 이젠 안녕!

SQL Injection은 웹 애플리케이션의 취약점을 이용하여 악의적인 SQL 쿼리를 실행시키는 공격입니다. 마치 성벽의 허술한 부분을 찾아 공격하는 것과 같습니다.

  • 취약한 예제 (동적 SQL):
SET @query = CONCAT('SELECT * FROM users WHERE username = ''', user_input, '''');
PREPARE stmt FROM @query;
EXECUTE stmt; -- user_input에 악성 SQL 코드가 삽입될 경우 위험

 

🚩해결책: Prepared Statement (PreparedStatement)

MySQL 예제:

PREPARE stmt FROM 'SELECT * FROM users WHERE username = ?';
SET @username = user_input;
EXECUTE stmt USING @username;

 

Python 예제 (MySQL Connector):

cursor.execute("SELECT * FROM users WHERE username = %s", (user_input,))
  • Prepared Statement는 SQL 쿼리를 미리 컴파일해두고, 사용자의 입력 값을 나중에 전달하는 방식입니다. 이렇게 하면 입력 값이 SQL 코드의 일부로 해석되지 않고 단순한 데이터로 처리되어 SQL Injection 공격을 효과적으로 방어할 수 있습니다. 마치 미리 만들어진 틀에 재료를 넣는 것과 같습니다.
  • 추가 방어 전략:
    • 입력 값 검증: 사용자 입력의 형식과 길이를 엄격하게 검사하여 유효하지 않은 입력은 거부합니다.
    • 최소 권한 원칙: 애플리케이션에서 사용하는 데이터베이스 계정에는 필요한 최소한의 권한만 부여합니다.

4. 실전! 사용자 권한 관리와 안전한 SQL 구현 (MySQL)

실습 목표: 최소 권한 부여 및 Prepared Statement를 통한 SQL Injection 방지

-- 1. 웹 애플리케이션 사용자 생성 (모든 호스트에서 접속 허용)
CREATE USER 'web_app'@'%' IDENTIFIED BY 'secure_pass';
-- 필요한 최소 권한만 부여 (SELECT, INSERT, UPDATE)
GRANT SELECT, INSERT, UPDATE ON my_database.* TO 'web_app'@'%';

-- 2. Prepared Statement를 사용한 안전한 쿼리 작성
PREPARE stmt FROM 'UPDATE accounts SET balance = balance - ? WHERE account_id = ?';
SET @amount = 100;
SET @account_id = 1;
EXECUTE stmt USING @amount, @account_id;

5. 튼튼한 데이터 성벽 완성!

데이터베이스 보안은 마치 건물을 짓는 것과 같습니다. 기초를 튼튼히 하고, 벽을 세우고, 문을 잠그는 것처럼, 사용자 권한 관리, 데이터 암호화, SQL Injection 방지 등의 단계를 차근차근 밟아나가면 안전하고 신뢰할 수 있는 데이터베이스를 구축할 수 있습니다. 이 글에서 배운 내용을 바탕으로 여러분의 데이터베이스를 더욱 안전하게 관리하시길 바랍니다. 궁금한 점이 있다면 언제든지 댓글로 문의해주세요!

728x90
반응형