[SEC-003][입문] 로그인과 권한 검사를 분리해 이해하기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[SEC-003][입문] 로그인과 권한 검사를 분리해 이해하기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 248회 작성일 26-08-30 18:34

본문

[이번 수업]
인증(authentication)은 요청자가 누구인지 확인하는 과정이고, 인가(authorization)는 그 사용자가 요청한 작업을 해도 되는지 판단하는 과정입니다. 로그인한 일반 사용자가 다른 사람 문서를 읽지 못하도록 기본 거부와 소유권 검사를 로컬 함수로 연습합니다.

[선수지식]
SEC-001의 보안 기본 원칙과 SEC-002의 위협 모델·공격 표면을 알면 좋습니다. Python 3만 필요합니다.

[학습목표]
1. 인증과 인가를 구분합니다.
2. 역할과 리소스 소유권을 함께 검사합니다.
3. 최소 권한과 기본 거부를 설명합니다.

[핵심개념]
인증은 비밀번호, 패스키, 인증 앱 같은 인증자를 검증해 신원을 세션과 연결합니다. 인증에 성공했다고 모든 기능을 쓸 수 있는 것은 아닙니다. 인가는 매 요청에서 현재 주체, 수행 작업, 대상 리소스, 환경 조건을 보고 허용 여부를 결정합니다. 역할 기반 접근 제어(RBAC)는 admin·viewer 같은 역할을 사용하고, 속성 기반 판단은 소유자 ID·부서·시간 같은 값을 함께 봅니다.

최소 권한은 업무에 필요한 권한만 필요한 동안 주는 원칙입니다. 규칙에 명시된 허용이 없으면 거부하는 기본 거부가 출발점입니다. HTTP에서는 일반적으로 인증 정보가 없거나 유효하지 않으면 401, 인증되었지만 권한이 부족하면 403을 사용합니다.

[따라하기]
아래 내용을 `authz_lab.py`로 저장하세요. 비밀번호나 토큰을 다루지 않는 권한 판정 모형입니다.

```python
from dataclasses import dataclass

@dataclass(frozen=True)
class User:
    user_id: str
    roles: frozenset[str]

def read_status(user, document):
    if user is None:
        return 401
    is_owner = document["owner_id"] == user.user_id
    is_admin = "admin" in user.roles
    return 200 if is_owner or is_admin else 403

document = {"id": "doc-1", "owner_id": "u1"}
tests = [
    (None, 401),
    (User("u1", frozenset({"viewer"})), 200),
    (User("u2", frozenset({"viewer"})), 403),
    (User("u2", frozenset({"admin"})), 200),
]

for user, expected in tests:
    actual = read_status(user, document)
    print(getattr(user, "user_id", "anonymous"), actual)
    assert actual == expected
```

macOS/Linux는 `python3 authz_lab.py`, Windows PowerShell은 `python authz_lab.py`를 실행합니다. 예상 결과는 anonymous 401, u1 200, 일반 u2 403, admin u2 200 순서이며 오류 없이 끝납니다. `u1`은 소유자라 허용되고 `u2`는 로그인했어도 권한이 없어 거부됩니다. 실제 서비스에서는 `user`와 역할을 클라이언트 입력에서 받지 않고 서버가 검증한 세션·토큰에서 가져와야 합니다.

[흔한 실수]
로그인만 확인하고 객체 소유권을 검사하지 않거나, 화면에서 버튼을 숨긴 것으로 인가가 끝났다고 생각하지 마세요. 관리자 URL을 추측하기 어렵게 만드는 것도 권한 검사를 대신하지 못합니다. 한 번 계산한 권한을 세션 동안 영구히 믿으면 역할 회수 후에도 접근이 남을 수 있습니다. 401과 403을 모든 경우에 뒤섞으면 클라이언트와 감사 로그 분석이 어려워집니다.

[보안 주의]
모든 읽기·쓰기 요청에서 서버 측 인가를 수행하고 문서 ID 같은 직접 객체 참조에도 소유권을 확인합니다. 비밀번호는 직접 암호화 코드를 만들지 말고 검증된 라이브러리로 소금값을 포함해 해시하며, 위험 수준에 맞는 MFA와 재인증을 적용합니다. 세션 쿠키에는 Secure·HttpOnly·적절한 SameSite를 설정하고 쿠키 인증의 상태 변경 요청에는 CSRF 방어를 둡니다. 거부 사건은 기록하되 비밀번호·토큰·개인정보는 로그에 남기지 않습니다.

[직접 해볼 과제]
문서에 `editors` 목록을 추가하고 소유자·admin·목록에 포함된 사용자만 수정 상태 200을 반환하게 만드세요. 익명, 소유자, 편집자, 관계없는 사용자 네 경우의 예상값을 assert로 검사합니다.

[확인문제]
1. 인증에 성공한 뒤에도 인가 검사가 필요한 이유는 무엇인가요?
2. 일반 u2가 doc-1을 읽을 때 403인 이유는 무엇인가요?
3. 기본 거부와 최소 권한은 어떻게 연결되나요?

[다음 학습]
전체 순환의 다음 수업은 AI-003 ‘지도학습·비지도학습·강화학습’입니다. 이어서 SEC-004 ‘입력 검증과 SQL 인젝션 방어’를 학습하세요.

[공식 참고 자료]
NIST SP 800-63B 인증 지침: https://pages.nist.gov/800-63-4/sp800-63b.html
NIST 인증 용어: https://csrc.nist.gov/glossary/term/authentication
NIST 인가 용어: https://csrc.nist.gov/glossary/term/authorization
NIST 최소 권한 용어: https://csrc.nist.gov/glossary/term/least_privilege
RFC 9110 HTTP 상태 의미: https://www.rfc-editor.org/rfc/rfc9110
OWASP 인가 지침: https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
3,941
어제
6,862
최대
16,772
전체
769,892
Copyright © 소유하신 도메인. All rights reserved.