ZAP의 강력한 기능인 Scripting에서 한번 더 강력하게 만들어 주는 것이 바로 Zest script입니다. JSON 기반의 스크립트로 웹 Req/Res 그리고 Headless browser에 대한 컨트롤, 마지막으로 Assertion 등 테스팅 기능을 이용해 간단한 코드로 복잡한 테스팅을 할 수 있는 스크립트입니다. 자세한 내용은 제가 전에 작성했던 글들을 참고해주세요.
오늘은 이 Zest를 CLI에서 실행하는 방법에 대해 이야기할까 합니다.
Zest CLI
제가 쓴 글, 그리고 실제로 사용할 때에도 저는 대부분의 Zest script를 ZAP에서 작성/동작 시킵니다. 이는 Zest가 ZAP과의 궁합이 굉장히 좋기 때문인데요. 사실 Zest는 CLI도 지원합니다.
만약 Zest script가 익숙해진다면, 아니 ZAP에서 GUI로 작성하는 방법에 익숙해진다면 오히려 간단한 자동화 작업이나 Headless를 통한 작업들은 Ruby/Python 등 스크립팅 언어보다 Zest로 작성하는게 더 빠르고 편리할 것 같단 생각이 듭니다. 그래서 오늘 이 내용을 조금 더 풀어보는 것이구요.
Zest의 장점 중 하나가 GUI 기반으로도 작성할 수 있다는 점이에요. 또한 ZAP에서 Proxy Record도 지원하기 때문에 단순하겐 쿠키 처리부터 복잡한 로직까지 클릭으로 쉽게 만들어나갈 수 있습니다 😊
ZAP에서 Zest도 별도로 내장되는게 아니라 Zest libary를 포함시켜 Scripting engine으로 동작시킵니다. 그래서 이 라이브러리를 따로 빌드하면 CLI로 실행할 수 있게 되죠 :D
Build
자 그럼 Zest를 다운로드 받아줍시다. gradle tasks는 ./gradlew tasks
로 확인하실 수 있습니다.
git clone https://github.com/zaproxy/zest
cd zest
./gradlew tasks
우린 빌드를 해야하니 build task를 실행합시다.
./gradlew build
완료되면 ./build/distributions
하위에 tar,zip 파일로 배포되고 압축을 풀면 bin
과 lib
디렉토리가 나타납니다. bin 에는 실행 스크립트가 들어있고, lib에는 java에서 참조할 라이브러리가 들어있습니다.
java -jar build/distributions/zest-0.16.0-SNAPSHOT/bin/zest-0.16.0-SNAPSHOT.jar
Usage: -script <file> [-summary | -list] [-debug] [-timeout <timeout for requests in seconds>] [-prefix <http://prefix>] [-token <name>=<value>]...
[-http-auth-site <site> -http-auth-realm <realm> -http-auth-user <user> -http-auth-password <password>]
[-insecure <skip the SSL certificate check>] For more information about Zest visit https://github.com/zaproxy/zest/
Test
Write zest script
테스트를 위해 ZAP에서 2가지 스크립트를 만들었습니다. 하나는 단순히 웹 요청 후 Print 하는 스크립트, 나머지 하나는 Headless 브라우저로 페이지를 열어 2개 페이지를 탐색한 후 스크린샷을 찍는 스크립트입니다.
{
"about": "hahwulTest.zst / 스크린샷을 찍는 스크립트",
"zestVersion": "0.8",
"title": "Test",
"description": "",
"prefix": "https://www.hahwul.com",
"type": "StandAlone",
"parameters": {
"tokenStart": "{{",
"tokenEnd": "}}",
"tokens": {},
"elementType": "ZestVariables"
},
"statements": [
{
"windowHandle": "firefox",
"browserType": "firefox",
"url": "https://www.hahwul.com",
"capabilities": "",
"headless": false,
"index": 1,
"enabled": true,
"elementType": "ZestClientLaunch"
},
{
"milliseconds": 3000,
"index": 2,
"enabled": true,
"elementType": "ZestActionSleep"
},
{
"windowHandle": "firefox",
"filePath": "/Users/<UserName>/123.png",
"variableName": "screenshot",
"index": 3,
"enabled": true,
"elementType": "ZestClientScreenshot"
}
],
"authentication": [],
"index": 0,
"enabled": true,
"elementType": "ZestScript"
}
Run
편한 작업을 위해 디렉토리를 이동합시다.
cd ./build/distributions/zest-0.16.0-SNAPSHOT/bin/
Request-Base
./zest -script ForZestCLI.zst
Headless-Base
./zest -script hahwulTest.zst
실행이 끝나면 아래와 같이 Headless로 접근해서 찍은 스크린샷이 지정한 경로에 생성됩니다.
Conclusion
Zest 정말 좋습니다. 물론 뭐 서비스를 만들거나 도구를 만든다고 한다면 당연히 프로그래밍 언어를 택하는게 맞습니다. 다만 단순한 자동화나 테스팅을 위한 자동화 로직의 경우 Zest와 친해진다면 정말 쉽고 빠르게 구현하고 사용할 수 있습니다.
현재까지는 제 대부분의 자동화 로직 중 Headless가 필요한 경우들은 모두 Golang
+ Chromedp
또는 Ruby
+ Selenium-Driver
조합으로 진행합니다. 특히나 도구를 만드는게 아닌 단순한 자동화의 경우 Ruby를 굉장히 자주 사용하는데요, 이제는 Ruby 비중을 많이 줄이고 Zest script와 CLI 기반의 조합으로 조금씩 더 늘려볼까 생각중입니다 :D