APIセキュリティチェックリスト の補足説明 | Monotalk書いている時に、OWASP APICheck を見つけました。幾つかAPIのチェック観点があるのですが、jwtのチェックができるようで試しにローカルに立てたjwt 発行APIに対してチェックを実施してみました。実施したことを記載します。


ローカルにjwt発行APIを立てる

APICheckのチェック対象とするAPIが必要なので、djangorestframework-simplejwt を使ってjwt発行APIを立てます。以下の記事が参考になりました。

OWASP APICheck のインストール

OWASP APICheck Quickstart を参考にインストールしてみます。

インストール

pip で apicheck-package-manager をインストールします。

pip install apicheck-package-manager

Collecting apicheck-package-manager
  Downloading https://files.pythonhosted.org/packages/e3/b7/bb723408d1a4b14a544b4ddbbf7abbae681bb78d89c8fabfb5c142a09161/apicheck_package_manager-0.0.15-py3-none-any.whl
Installing collected packages: apicheck-package-manager
Successfully installed apicheck-package-manager-0.0.15

PATHを設定

プロファイルに以下の行を追加して、APICheckのバイナリパスをPATHに含めます。

export PATH="$HOME/.apicheck_manager/bin:$PATH"

上手くPATH設定ができると、acp コマンドが実行できるようになります。

% acp -h  
usage: acp [-h] [-w] {list,info,install,version} ...

APICheck Manager

positional arguments:
  {list,info,install,version}
                        available actions
    list                search in A
    info                show expanded tool info
    install             install an APICheck tool
    version             displays version

optional arguments:
  -h, --help            show this help message and exit
  -w, --disable-warning
                        disable check of RC Shell File

jwt-checker のインストール

jwt-checker をインストールします。

acp list

-----------------------------------------------------------------
 WARNING: 

 You must include apic heck path to your shell RC file.

 Please add: 'export PATH="$HOME/.apicheck_manager/bin:$PATH"'
 to your '.zshrc' file
-----------------------------------------------------------------
+--------------------------------------------------+
| Name           | Version                         |
+--------------------------------------------------+
| acurl          | 1.0.0                           |
+--------------------------------------------------+
| send-to-proxy  | 1.0.2                           |
+--------------------------------------------------+
| sensitive-data | 1.0.1                           |
+--------------------------------------------------+
| jwt-checker    | 1.0.0                           |
+--------------------------------------------------+
| apicheck-proxy | 1.0.2                           |
+--------------------------------------------------+
| replay         | 1.0.0                           |
+--------------------------------------------------+
| openapiv3-lint | 1.0.0                           |
+--------------------------------------------------+
| openapiv2-lint | 1.0.0                           |
+--------------------------------------------------+
| oas-check      | 1.0.0                           |
+--------------------------------------------------+

jwt-checker をインストールします。

acp install jwt-checker 

-----------------------------------------------------------------
 WARNING: 

 You must include apic heck path to your shell RC file.

 Please add: 'export PATH="$HOME/.apicheck_manager/bin:$PATH"'
 to your '.zshrc' file
-----------------------------------------------------------------
[*] Creating path for storing apicheck tools at : /Users/kensakurai/.apicheck_manager/bin
[*] Fetching Docker image for tool 'jwt-checker'

/bin/sh: docker: command not found

[*] Making launch scripts
[*] Updating configuration file 

jwt-checker は内部で dockerコマンドを実行しているようで、dockerをインストールしました。

brew install docker --cask

dockerインストール後に再度jwt-checkerのインストールコマンドを実行したところ、以下のようなメッセージが出力されました。docker がインストールされていない状態でもインストールは成功するようです。

acp install jwt-checker 
-----------------------------------------------------------------
 WARNING: 

 You must include apic heck path to your shell RC file.

 Please add: 'export PATH="$HOME/.apicheck_manager/bin:$PATH"'
 to your '.zshrc' file
-----------------------------------------------------------------

[*] Tools is already installed

curl -H "Content-Type: application/json" -d '{"username":"kensakurai", "password":"kensakurai"}' --trace trace.log http://127.0.0.1:8000/api/v1/token/ 

apicheck のリポジトリをcloneして、curlのtraceファイルから、jwt-checkerの入力ファイルを作成する

jwt-checker のマニュアルには以下のコマンドの記載があり、 acurl というツールをインストールすれば良さそうなのですが、local でデプロイしているjwt 発行 APIにacurl を実行したところ以下のエラーとなりました。

acurl http://127.0.0.1:8000/api/v1/token/ 

Traceback (most recent call last):
  File "gurl/__main__.py", line 32, in <module>
    main()
  File "gurl/__main__.py", line 20, in main
    res = gurl.parse_curl_trace(f.read())
  File "/venv/lib/python3.8/site-packages/gurl/__init__.py", line 104, in parse_curl_trace
    reqres["_meta"]["curl_log"] = log
TypeError: 'NoneType' object is not subscriptable

戻り値が403なのでそれが原因な気がします。
acurlに対するパラメータの指定方法も良くわからず、acurlを介しての実行は諦めて、curl のtraceファイルからjwt-checkerの入力ファイルを作成する方法を試してみました。

  1. apicheck のリポジトリをclone

gitclone https://github.com/OWASP/apicheck.git

  1. ディレクトリ移動

cd apicheck
cd tools/curl/gcurl

  1. ファイル移動 とライブラリのインストール

何か設定が必要なのかもしれませんが、モジュールのimportエラーで起動スクリプトが動かず、ディレクトリを移動しました。 また、ライブラリインストールも必要なのでインストールします。

mv __main__.py ../
cd ..
pip install httptools

  1. traceファイル取得

以下、コマンドでtraceファイルを取得します。

curl -H "Content-Type: application/json" -d '{"username":"[user_name]", "password":"[password]"}' --trace trace.log http://127.0.0.1:8000/api/v1/token/

  1. traceファイルを使って、jwt-checkの入力ファイルを生成

__main__.pyfオプションを指定して実行すると、標準出力にjsonが出力されます。

python __main__.py -f trace.log

---
{"_meta": {"status_text": "OK", "curl_log": []}, "request": {"method": "POST", "url": "http://127.0.0.1:8000/api/v1/token/", "headers": {"Host": "127.0.0.1:8000", "User-Agent": "curl/7.64.1", "Accept": "*/*", "Content-Type": "application/json", "Content-Length": "50"}, "body": "eyJ1c2VybmFtZSI6ImtlbnNha3VyYWkiLCAicGFzc3dvcmQiOiJrZW5zYWt1cmFpIn0=\n", "version": "1.1"}, "response": {"status": 200, "headers": {"Date": "Thu, 22 Jul 2021 11:22:22 GMT", "Server": "WSGIServer/0.2 CPython/3.7.2", "Content-Type": "application/json", "Vary": "Accept", "Allow": "POST, OPTIONS", "X-Frame-Options": "DENY", "Content-Length": "438", "X-Content-Type-Options": "nosniff", "Referrer-Policy": "same-origin"}, "body": "eyJyZWZyZXNoIjoiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKSVV6STFOaUo5LmV5SjBiMnRs\nYmw5MGVYQmxJam9pY21WbWNtVnphQ0lzSW1WNGNDSTZNVFl5TnpBek9UTTBNaXdpYW5ScElqb2lO\nRGswWWpFd016ZGxOakUwTkRVelpqbGpaRFJrTWpaaU0yRmtORFZsWm1NaUxDSjFjMlZ5WDJsa0lq\nb3hmUS5tajhLaWxIZnZhb3FZMXNaR2VLeGxWS0pqbG5YMmQ2WS01S0dmaC1jV3pjIiwiYWNjZXNz\nIjoiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKSVV6STFOaUo5LmV5SjBiMnRsYmw5MGVYQmxJ\nam9pWVdOalpYTnpJaXdpWlhod0lqb3hOakkyT1RVek1qUXlMQ0pxZEdraU9pSmpabU01WmpnM016\nWm1OVE0wTmpreU9URXlOelk1WW1Nek5ETTNPVE5qTXlJc0luVnpaWEpmYVdRaU9qRjkuVU4wWWNZ\nekp1NzZlWFlDNF9WSlVFaklwVVpaWUZjd1JHdVJIM0FrVTMzcyJ9\n", "version": "1.1"}}

jwt-checker を実行

以下のコマンドを実行します。

python __main__.py -f trace.log | jwt-checker --allowAlg HS256 -allowAlg HS384 -issuer bbva-iam -subject subject-id -secret bXlTZWNyZXRQYXNzd29yZG15U2VjcmV0UGFzc3dvcmQK

---

Errors: 
One and only one token must be provided

実行まで行うことができました。

鍵の生成をして、鍵を指定すれば、各チェック項目を実行することはできそうです。
個人的に使うのはこのままゴリ押して使えば良さそうですが、会社で使うにはacurlコマンドから、パラメータ指定して動かせないとちょっと使えないかなと思いました。
動作確認としては、力尽きたので一旦ここで終わろうかと思います。

以上です。

コメント