강제적 접근 제어(Mandatory Access Control, MAC)

시스템 전체에 걸쳐 중앙에서 정의된 보안 정책에 따라 접근 권한을 강제로 적용하는 접근 제어 방식.
이는 개별 사용자나 소유자가 임의로 접근 권한을 변경할 수 없다는 점에서 DAC와 큰 차이가 있다.

군사, 정부 기관, 금융 기관 등 높은 수준의 보안이 요구되는 환경에서 사용된다.
일반적인 기업이나 개인용 시스템에서는 구현의 복잡성과 관리 부담 때문에 다른 접근 제어 방식을 선호하는 경우가 많다.

작동원리:
두 가지 중요한 보안 원칙을 적용한다:

  1. No Read Up: 주체는 자신의 보안 수준보다 높은 분류 수준을 가진 객체를 읽을 수 없다.
  2. No Write Down: 주체는 자신의 보안 수준보다 낮은 분류 수준을 가진 객체에 쓸 수 없다.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// 보안 레벨 정의
const SecurityLevel = {
    UNCLASSIFIED: 1,
    CONFIDENTIAL: 2,
    SECRET: 3,
    TOP_SECRET: 4
};

class Subject {
    constructor(name, clearanceLevel) {
        this.name = name;
        this.clearanceLevel = clearanceLevel;
    }
}

class Resource {
    constructor(name, classificationLevel) {
        this.name = name;
        this.classificationLevel = classificationLevel;
        this.content = null;
    }
}

class MACSystem {
    constructor() {
        this.subjects = new Map();
        this.resources = new Map();
    }

    // 새로운 주체(사용자) 추가
    addSubject(name, clearanceLevel) {
        if (!Object.values(SecurityLevel).includes(clearanceLevel)) {
            throw new Error('Invalid security clearance level');
        }
        const subject = new Subject(name, clearanceLevel);
        this.subjects.set(name, subject);
    }

    // 새로운 객체(리소스) 추가
    addResource(name, classificationLevel) {
        if (!Object.values(SecurityLevel).includes(classificationLevel)) {
            throw new Error('Invalid classification level');
        }
        const resource = new Resource(name, classificationLevel);
        this.resources.set(name, resource);
    }

    // 읽기 접근 검사 (No Read Up)
    canRead(subjectName, resourceName) {
        const subject = this.subjects.get(subjectName);
        const resource = this.resources.get(resourceName);

        if (!subject || !resource) {
            return false;
        }

        // 주체의 보안 수준이 객체의 분류 수준보다 같거나 높아야 함
        return subject.clearanceLevel >= resource.classificationLevel;
    }

    // 쓰기 접근 검사 (No Write Down)
    canWrite(subjectName, resourceName) {
        const subject = this.subjects.get(subjectName);
        const resource = this.resources.get(resourceName);

        if (!subject || !resource) {
            return false;
        }

        // 주체의 보안 수준이 객체의 분류 수준보다 같거나 낮아야 함
        return subject.clearanceLevel <= resource.classificationLevel;
    }

    // 접근 시도
    accessResource(subjectName, resourceName, operation) {
        const subject = this.subjects.get(subjectName);
        const resource = this.resources.get(resourceName);

        if (!subject || !resource) {
            throw new Error('Subject or resource not found');
        }

        switch (operation) {
            case 'read':
                if (this.canRead(subjectName, resourceName)) {
                    return `${subjectName} can read ${resourceName}`;
                }
                break;
            case 'write':
                if (this.canWrite(subjectName, resourceName)) {
                    return `${subjectName} can write to ${resourceName}`;
                }
                break;
        }

        throw new Error('Access denied');
    }
}

주요 특징

  1. 중앙 집중적 통제: 보안 정책은 시스템 관리자가 중앙에서 제어한다.
  2. 보안 레이블: 주체와 객체에 각각 보안 레이블(등급)이 할당된다.
  3. 규칙 기반: 미리 정의된 규칙에 따라 접근 권한이 결정된다.
  4. 사용자 재량 없음: 사용자는 보안 정책을 수정하거나 우회할 수 없다.

장점

  1. 높은 보안성: 엄격한 접근 제어로 기밀성을 유지한다.
  2. 일관된 정책 적용: 전체 시스템에 걸쳐 동일한 보안 정책이 적용된다.
  3. 내부자 위협 감소: 사용자의 실수나 악의적 행동으로 인한 위험을 줄일 수 있다.

단점

  1. 유연성 부족: 특정 상황에 대한 예외 처리가 어렵다.
  2. 관리의 복잡성: 모든 주체와 객체에 대한 보안 레이블 관리가 필요하다.
  3. 성능 저하: 모든 접근에 대해 보안 검사를 수행하므로 성능에 영향을 줄 수 있다.

예시

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const macSystem = new MACSystem();

// 사용자 추가
macSystem.addSubject('AliceTopSecret', SecurityLevel.TOP_SECRET);
macSystem.addSubject('BobSecret', SecurityLevel.SECRET);
macSystem.addSubject('CharlieConfidential', SecurityLevel.CONFIDENTIAL);

// 리소스 추가
macSystem.addResource('TopSecretFile', SecurityLevel.TOP_SECRET);
macSystem.addResource('SecretFile', SecurityLevel.SECRET);
macSystem.addResource('ConfidentialFile', SecurityLevel.CONFIDENTIAL);

try {
    // 접근 시도 예시
    console.log(macSystem.accessResource('AliceTopSecret', 'SecretFile', 'read')); // 성공
    console.log(macSystem.accessResource('BobSecret', 'TopSecretFile', 'read')); // 실패
    console.log(macSystem.accessResource('AliceTopSecret', 'ConfidentialFile', 'write')); // 실패
} catch (error) {
    console.error(error.message);
}

참고 및 출처