Zest는 Mozilla 보안팀에서 개발한 JSON/YAML 기반의 스크립팅 언어입니다. 현재는 ZAP Core 프로젝트의 일부로 관리되고 있으며, HTTP Request/Response 처리, Headless Browser 제어, Assertion을 이용한 테스트 등을 통해 자동화된 보안 테스트 시나리오를 작성하고 실행할 수 있습니다.
개인적으로 ZAP에서 자동화 스크립트를 작성할 때 가장 선호하는 언어입니다.
What is Zest?
Zest 스크립트는 기본적으로 아래와 같은 구조를 가집니다. 최근에는 YAML 포맷도 지원하게 되어 JSON보다 훨씬 편하게 작성할 수 있게 되었습니다.
JSON Format
{
"about": "Zest에 대한 설명",
"zestVersion": "0.8",
"title": "스크립트 이름",
"description": "스크립트 설명",
"prefix": "https://www.hahwul.com",
"type": "StandAlone",
"parameters": {
"tokenStart": "{{",
"tokenEnd": "}}",
"tokens": {},
"elementType": "ZestVariables"
},
"statements": [],
"authentication": [],
"index": 0,
"enabled": true,
"elementType": "ZestScript"
}
YAML Format
about: Zest에 대한 설명
zestVersion: '0.8'
title: 스크립트 이름
description: 스크립트 설명
prefix: 'https://www.hahwul.com'
type: StandAlone
parameters:
tokenStart: '{{'
tokenEnd: '}}'
tokens: {}
elementType: ZestVariables
statements: []
authentication: []
index: 0
enabled: true
elementType: ZestScript
Interfaces
Zest를 사용할 수 있는 몇 가지 방법이 있습니다.
ZAP GUI
Zest는 ZAP의 내장 스크립팅 엔진이므로, ZAP GUI를 통해 직관적으로 스크립트를 작성하고 관리할 수 있습니다.
Zest CLI
Zest는 ZAP 라이브러리로 동작하지만, 독립적인 CLI 인터페이스도 제공합니다. 별도로 빌드하거나, 제가 만들어 둔 zest-env
Docker 이미지를 사용하면 Github Action 등 다양한 환경에서 간편하게 사용할 수 있습니다.
https://github.com/hahwul/zest-env
docker pull hahwul/zest-env:v1.0.0
docker run hahwul/zest-env:v1.0.0 zest -script <YOUR-ZEST-SCRIPT>
How to Write
스크립트 작성 방법은 크게 세 가지로 나눌 수 있습니다.
ZAP Script Console
ZAP 내의 "Scripts" 탭과 "Script Console" 탭에서 GUI와 CLI를 통해 직접 코드를 작성하고 테스트할 수 있습니다.
ZAP Zest Record
ZAP에는 Zest Record 기능이 내장되어 있습니다. 레코딩을 시작하면 사용자의 웹 요청을 기록하여 Zest 스크립트의 초안을 자동으로 생성해 줍니다. 복잡한 흐름을 스크립트로 만들 때 매우 유용합니다.
TextEditor & IDE
물론 JSON/YAML 기반이므로 선호하는 텍스트 에디터나 IDE에서 직접 스크립트를 작성할 수도 있습니다. 다만 JSON은 직접 수정하기에 다소 번거로운 점이 있었는데, 2023년 9월에 YAML 포맷이 추가되면서 훨씬 수월해졌습니다.
Structure
Zest 스크립트는 몇 가지 핵심 구성 요소로 이루어져 있습니다.
graph TD A[Start] --> B(Statement 1: Request); B --> C{Condition: if status == 200}; C -- True --> D[Assertion: body contains 'login_success']; C -- False --> E[Action: Log 'Login Failed']; D --> F(Statement 2: ...); E --> F; F --> G[End];
Statements
Zest의 핵심은 statements
배열입니다. 이 배열에 포함된 액션들은 순차적으로 실행됩니다. Zest는 이 배열을 따라 웹 요청, Action, Assertion, Condition, Assignment 등을 처리하고 최종 결과를 반환합니다.
Condition (ifStatements)
Condition
을 사용하여 스크립트 내에서 분기 처리를 구현할 수 있습니다. if
문과 유사하게 특정 조건에 따라 다른 statements
를 실행하도록 제어합니다.
Assertions
Assertion
은 테스트의 성공/실패를 판정하는 검증 기능입니다. 일반적인 유닛 테스트의 Assertion과 동일한 개념으로, 응답 코드, 헤더, 본문 내용 등이 예상과 일치하는지 확인할 수 있습니다.
Action
Action
은 특정 동작을 수행합니다. 예를 들어 sleep
을 주거나, 변수 값을 설정하는 등의 작업을 처리할 수 있습니다. ZAP 스캐너와 연동되는 Action도 존재합니다.
Assignment
Assignment
는 변수를 다루는 기능입니다. 난수를 생성하거나 특정 값을 계산하는 등 다양한 작업을 처리하고, 그 결과를 {{ 변수명 }}
형태로 스크립트의 다른 부분에서 참조할 수 있습니다.
변수 값은 {{ variable_name }}
과 같은 형식으로 불러와 사용할 수 있습니다.
Loop
Zest는 Loop
를 통해 반복문도 구성할 수 있습니다. 하지만 복잡한 반복 로직은 Assignment
와 함께 사용해야 하므로, 이런 경우에는 Ruby나 Python과 같은 일반 스크립트 언어가 더 효율적일 수 있습니다.
Tools
Articles
- Zest + YAML = ❤️
- Cross handling Cookies in Zest
- Zest script in CLI
- ZAP에서 Zest Script로 Headless 기반의 인증 자동화 처리하기
- Zest와 ZAP! 강력한 보안 테스트 루틴을 만들어봐요 ⚡️
- Zest와 ZAP을 이용한 Semi-Automated Security Testing