# Angular
## 체크리스트
[여기](https://lsgeurope.com/post/angular-security-checklist)에서 체크리스트를 확인하세요.
* [ ] Angular는 클라이언트 사이드 프레임워크로 간주되며 서버 사이드 보호 기능을 제공하지 않습니다.
* [ ] 프로젝트 구성에서 스크립트의 소스맵이 비활성화되어 있습니다.
* [ ] 신뢰할 수 없는 사용자 입력은 항상 템플릿에서 사용되기 전에 보간(interpolation) 또는 살균(sanitization)됩니다.
* [ ] 사용자는 서버 사이드 또는 클라이언트 사이드 템플릿을 제어할 수 없습니다.
* [ ] 신뢰할 수 없는 사용자 입력은 애플리케이션이 신뢰하는 것으로 간주되기 전에 적절한 보안 컨텍스트를 사용하여 살균(sanitization)됩니다.
* [ ] `BypassSecurity*` 메서드는 신뢰할 수 없는 입력과 함께 사용되지 않습니다.
* [ ] 신뢰할 수 없는 사용자 입력은 `ElementRef`, `Renderer2`, `Document` 등의 Angular 클래스 또는 다른 JQuery/DOM sink에 전달되지 않습니다.
## Angular란
Angular는 **강력한** 오픈 소스 프론트엔드 프레임워크로, **Google**에서 유지보수하고 있습니다. 코드 가독성과 디버깅을 향상시키기 위해 **TypeScript**를 사용합니다. 강력한 보안 메커니즘을 갖추고 있어 Angular는 **XSS**와 **오픈 리디렉션**과 같은 일반적인 클라이언트 사이드 취약점을 방지합니다. 또한 서버 사이드에서도 사용할 수 있어 보안 고려 사항이 **양쪽 모두** 중요합니다.
## 프레임워크 아키텍처
Angular의 기본 개념을 더 잘 이해하기 위해 핵심 개념을 살펴보겠습니다.
일반적인 Angular 프로젝트는 보통 다음과 같은 구조를 가지고 있습니다.
```bash
my-workspace/
├── ... #workspace-wide configuration files
├── src
│ ├── app
│ │ ├── app.module.ts #defines the root module, that tells Angular how to assemble the application
│ │ ├── app.component.ts #defines the logic for the application's root component
│ │ ├── app.component.html #defines the HTML template associated with the root component
│ │ ├── app.component.css #defines the base CSS stylesheet for the root component
│ │ ├── app.component.spec.ts #defines a unit test for the root component
│ │ └── app-routing.module.ts #provides routing capability for the application
│ ├── lib
│ │ └── src #library-specific configuration files
│ ├── index.html #main HTML page, where the component will be rendered in
│ └── ... #application-specific configuration files
├── angular.json #provides workspace-wide and project-specific configuration defaults
└── tsconfig.json #provides the base TypeScript configuration for projects in the workspace
```
문서에 따르면, 모든 Angular 애플리케이션은 적어도 하나의 컴포넌트, 즉 루트 컴포넌트(`AppComponent`)를 가지고 있으며, 이 컴포넌트는 컴포넌트 계층 구조와 DOM을 연결합니다. 각 컴포넌트는 애플리케이션 데이터와 로직을 포함하는 클래스를 정의하며, 타겟 환경에서 표시할 뷰를 정의하는 HTML 템플릿과 연결됩니다. `@Component()` 데코레이터는 바로 아래의 클래스를 컴포넌트로 식별하고, 템플릿과 관련된 컴포넌트별 메타데이터를 제공합니다. `AppComponent`는 `app.component.ts` 파일에 정의되어 있습니다.
Angular NgModules는 컴포넌트 집합에 대한 컴파일 컨텍스트를 선언하며, 응용 프로그램 도메인, 워크플로우 또는 관련된 기능 세트에 전용됩니다. 모든 Angular 애플리케이션에는 일반적으로 `AppModule`이라는 이름의 루트 모듈이 있으며, 이 모듈은 애플리케이션을 시작하는 부트스트랩 메커니즘을 제공합니다. 일반적으로 애플리케이션에는 많은 기능 모듈이 포함됩니다. `AppModule`은 `app.module.ts` 파일에 정의되어 있습니다.
Angular `Router` NgModule은 애플리케이션의 다른 상태와 뷰 계층 사이에서 탐색 경로를 정의할 수 있는 서비스를 제공합니다. `RouterModule`는 `app-routing.module.ts` 파일에 정의되어 있습니다.
특정 뷰와 관련되지 않은 데이터나 로직을 공유하려면 서비스 클래스를 생성합니다. 서비스 클래스 정의는 `@Injectable()` 데코레이터로 바로 앞에 위치합니다. 이 데코레이터는 다른 프로바이더를 클래스에 의존성으로 주입할 수 있도록 메타데이터를 제공합니다. 의존성 주입(DI)을 사용하면 컴포넌트 클래스를 가볍고 효율적으로 유지할 수 있습니다. 컴포넌트 클래스는 서버에서 데이터를 가져오거나 사용자 입력을 유효성 검사하거나 콘솔에 직접 로그를 기록하지 않습니다. 이러한 작업은 서비스에 위임합니다.
## 소스맵 구성
Angular 프레임워크는 `tsconfig.json` 옵션을 따라 TypeScript 파일을 JavaScript 코드로 변환한 다음 `angular.json` 구성으로 프로젝트를 빌드합니다. `angular.json` 파일을 살펴보면 소스맵을 활성화하거나 비활성화할 수 있는 옵션이 있습니다. Angular 문서에 따르면, 기본 구성은 스크립트에 대한 소스맵 파일이 활성화되어 있으며 기본적으로 숨겨지지 않습니다.
```json
"sourceMap": {
"scripts": true,
"styles": true,
"vendor": false,
"hidden": false
}
```
일반적으로, 소스맵 파일은 디버깅 목적으로 사용되며 생성된 파일을 원본 파일에 매핑합니다. 따라서 프로덕션 환경에서 사용하는 것은 권장되지 않습니다. 소스맵이 활성화되면 Angular 프로젝트의 원래 상태를 복제하여 가독성을 향상시키고 파일 분석을 돕습니다. 그러나 비활성화된 경우에도 리뷰어는 보안에 취약한 패턴을 수동으로 검색하여 컴파일된 JavaScript 파일을 분석할 수 있습니다.
또한, Angular 프로젝트의 컴파일된 JavaScript 파일은 브라우저 개발자 도구 → 소스(또는 디버거 및 소스) → \[id].main.js에서 찾을 수 있습니다. 활성화된 옵션에 따라 이 파일은 끝에 다음 행을 포함할 수 있습니다. `//# sourceMappingURL=[id].main.js.map` 또는 **hidden** 옵션이 **true**로 설정된 경우 포함되지 않을 수도 있습니다. 그러나 **scripts**에 대한 소스맵이 비활성화된 경우 테스트가 더 복잡해지며 파일을 얻을 수 없습니다. 또한, 소스맵은 `ng build --source-map`과 같이 프로젝트 빌드 중에 활성화될 수 있습니다.
## 데이터 바인딩
바인딩은 컴포넌트와 해당하는 뷰 간의 통신 과정을 의미합니다. Angular 프레임워크와 데이터 간의 전송에 사용됩니다. 데이터는 이벤트, 보간법, 속성 또는 양방향 바인딩 메커니즘을 통해 전달될 수 있습니다. 또한, 데이터는 관련 컴포넌트(부모-자식 관계) 및 서비스 기능을 사용하여 두 개의 관련 없는 컴포넌트 간에 공유될 수도 있습니다.
데이터 흐름에 따라 바인딩을 분류할 수 있습니다:
* 데이터 소스에서 뷰 타겟으로 (보간법, 속성, 속성, 클래스 및 스타일 포함); 템플릿에서 `[]` 또는 `{{}}`를 사용하여 적용할 수 있습니다.
* 뷰 타겟에서 데이터 소스로 (이벤트 포함); 템플릿에서 `()`를 사용하여 적용할 수 있습니다.
* 양방향; 템플릿에서 `[()]`를 사용하여 적용할 수 있습니다.
바인딩은 속성, 이벤트 및 속성뿐만 아니라 소스 지시문의 모든 공개 멤버에 대해 호출될 수 있습니다:
| 유형 | 타겟 | 예시 |
| --------- | -------------------------------------------------------- | -------------------------------------------------------------------- |
| 속성 | 요소 속성, 컴포넌트 속성, 지시문 속성 | \ |
| 이벤트 | 요소 이벤트, 컴포넌트 이벤트, 지시문 이벤트 | \