認証タイプJavaScriptとは、JavaScriptファイルを用いるSecurify独自の認証システムです。
参考コードを基にJavaScriptファイルを作成すること、様々なWebサービスの認証に対応可能となります。
JavaScriptファイル作成の目的
認証が存在する診断対象アプリケーションに対して、SecurifyScanでクローリングを実行する際に、認証情報(AuthorizationヘッダやCookieの値を)をリクエストヘッダに設定して、認証の突破をはかります。
そのため、JavaScriptファイルで上述の認証情報を取得及び返却する内容を記述し、認証情報を取得することが目的となります
JavaScriptファイル作成方法
JavaScriptファイル作成の要点
- JavaScriptファイルにて、認証情報を取得して、返り値として返却します。
- 例
- Basic認証であれば、Authorizationヘッダにユーザー名とパスワードをBase64エンコードしたものでリクエストをするため、Authorizationヘッダを返すように、JavaScriptを記述する必要があります。
- 診断対象アプリケーションでのログインの挙動をJavaScriptファイルにて再現するイメージとなります
- JavaScriptファイルが正常に動作するか、正常にリクエストヘッダの値を取得できるかどうかはデバッグ環境にて確認ができます
認証に必要な情報の確認方法
一例として、Chromeでの確認方法を記載します。
上述のサイトの場合のJavaScriptファイルのサンプルコードです。
この例の場合、/loginのURLに対して、POSTを実行して、Cookieの値を取得しています。
POSTを実行する際に必要なリクエストヘッダやボディの値を前半で設定しています。
const https = require('https')
const axios = require('axios')
const jsdom = require("jsdom")
const setCookie = require('set-cookie-parser');
const authentication = async() => {
// ログインページへアクセスしてCSRFトークンとCookieの取得
const lognPage = await axios.get('https://example.com/login')
const { document } = new jsdom.JSDOM(loginPage.data).window
const csrf = document.querySelector('body').getAttribute("data-csrftoken")
const cookies = setCookie.parse(loginPage, {
decodeValues: true,
map: true,
})
const key = 'connect.sid'
const value = cookies[key].value
const cookieValue = key+"="+value
// ログイン処理
const reqBody = new URLSearchParams()
reqBody.append('loginForm[username]', 'example')
reqBody.append('loginForm[password]', 'password')
reqBody.append('_csrf', csrf)
const reqHeaders = {
"Content-Type": "application/x-www-form-urlencoded",
"Cookie": cookieValue,
}
await axios.post('https://example.com/login', reqBody, {headers: reqHeaders})
return {"Cookie": cookieValue}
}
JavaScriptファイルの作成ルール
authentication
関数を定義する- 返り値はmap形式でヘッダを返却する(複数ある場合はカンマ区切りで続けて返す)
const authentication = () => {
// 認証処理
return { "headerKey1": "headerKey2" }
}
参考コード
本コードについてはあくまで書き方の参考となるため、JavaScriptのコードは診断対象の認証方式に合わせて、記載してください。本コードをコピーしても正常に動作しませんので、ご了承ください
Basic認証
以下の情報を記載してください。
- username
- password
const buffer = require('buffer')
const username = "XXX"
const password = "XXX"
const authentication = () => {
const basic = username+":"+password
let base = buffer.Buffer.from(basic).toString('base64') ;
return {"Authorization": "Basic "+base}
}
usernameとpasswordをbase64エンコードして上述のようにmap形式で返却しています。
Cookie認証
テンプレートはFormに「username」「password」を入力し、Cookieに認証情報を設定する場合を記載しています。
const axios = require('axios')
const setCookie = require('set-cookie-parser');
const username = "XXX"
const password = "XXX"
const authentication = async () => {
const res = await axios.post('https://example.com/cookie-login', {
'username': 'XXX',
'passoword': 'XXX',
})
if (res.status != 200) {
throw new Error(res)
}
const cookies = setCookie.parse(res, {
decodeValues: true,
map: true,
})
const key = 'sessionID'
const value = cookies[key].value
return {"Cookie": key+"="+value}
}
ユーザーのログイン情報(username, password)を渡して、Cookieを返すAPI通信をaxiosを使用して行い、そのレスポンスヘッダを取得して返却しています。
JWT認証
const axios = require('axios')
const username = "XXX"
const password = "XXX"
const authentication = async () => {
const res = await axios.post('https://example.com/jwt-login', {
'username': 'XXX',
'passoword': 'XXX',
})
if (res.status != 200) {
throw new Error(res)
}
const jwt = res.data
return {"Authorization": "Bearer "+jwt}
}
ユーザーのログイン情報(username, password)を渡して、JWTを返すAPI通信をaxiosを使用して行い、そのレスポンスを返却しています。
デバッグ方法
JavaScriptを実行
JavaScriptを実行して想定通りのヘッダが得られているか確認してください。
デバッグ環境を用意したので、JavaScriptが正常に実行できるか確認してください。
デバッグ環境のドキュメントに従い、認証処理の記述とデバッグを行ってください。
Securifyで認証通過の確認
想定通りのヘッダが返ってきたら、Securifyで認証が通過できるかの確認をします。
推奨方法は、診断対象をJavaScript認証方式で登録し、ログイン後の画面が表示されるかを確認します。
または、curlコマンドなどを用いて、JavaScriptを実行した結果のヘッダを全て付与した状態で通信し、レスポンスが認証された結果のレスポンスかどうかの確認をしてください。