(UPDATED: )

An Introduction to Zest

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

References