any/all
| フィールド | 説明 |
|---|---|
| any | 条件のうち一つ以上を満たせば一致 |
| all | 列挙した条件すべてを満たす場合に一致 |
例 1: method_1 または method_2 の呼び出しを探します。
any:
- pattern: method_1($$$)
- pattern: method_2($$$)
例 2:
all:
- pattern: method_1($$$)
- inside:
pattern: $F(async ($REQ, $RES) => {$$$})
- inside:
pattern: for($IN = $S; $$$; $$$) {$$$}
not
特定のパターンを除外する場合に not を使います。
pattern: $REQ.META
not:
inside:
any:
- pattern: $REQ.META.CONTENT_LENGTH
- pattern: $REQ.META.CONTENT_TYPE
regex
正規表現による照合を行います。
例: メタ変数 STR に格納した文字列を正規表現で調べ、polyfill.io の URL を探します。
pattern: |
"$STR"
metavar:
name: STR
eq:
regex: '(?:https?:)?//(?:[^/]*\.)?polyfill\.io'
以下のコードが一致します。
async function loadPolyfill() {
await import("https://polyfill.io/v3/polyfill.min.js"); // 一致
}
async function loadPolyfillWithQuote() {
await import('https://polyfill.io/v3/polyfill.min.js'); // 一致
}
Inside
別のパターンの内側にあるパターンを探す場合に inside を使います。
例: someMethod メソッド内の target 呼び出しを探します。
inside:
pattern: public void someMethod($$$){$$$}
pattern: target($$$)
以下のコードが一致します。
public class Example {
public void someMethod(String arg) {
target("something"); // 一致
}
}
Metavariable
メタ変数は $ で始めます。
| メタ変数の種類 | 説明 |
|---|---|
| $VAR | 一致した AST ノードを VAR に格納 |
| $$$VARS | 複数の AST ノードを取得 |
| $$$ | 複数行を含む複数のノードに一致 |
$$$ は次のように複数行のパターンで使えます。
pattern: |
public void someMethod($$$) {$$$}
取得したメタ変数の値にもパターンを適用できます。以下のルールは、NOVERIFY がハードコードされた文字列か true の場合に一致します。
pattern: $JWT.decode($TOKEN, $SECRET, $NOVERIFY, $$$)
metavar:
name: NOVERIFY
eq:
any:
- pattern: |
"$$$_STR"
- pattern: "true"
matcher
matcher は、よく使われる機密情報に関する名前の分類を提供します。複数のルールで password|token|api_key|client_secret... のような大きな正規表現を繰り返す必要がなくなります。
使用できる値:
passwordsecretpiisensitive
例:
metavar:
name: FIELD
eq:
matcher: secret
matcher は名前やキーの形をしたノードから引用符を除き、camelCase、snake_case、kebab-case、ドット区切りの名前、数字の接尾辞をトークンに分けて調べます。大きな式のテキスト全体を機密情報の名前として分類するものではありません。また、実際のメールアドレスや電話番号などの PII 値ではなく、名前やキーを分類します。
regex_pair.left でも使えます。
regex_pair:
left:
matcher: secret
right: "[0-9a-zA-Z\\-_.=\\~@]{10,150}"
constantValue
JavaScript、TypeScript、TSX でローカルな定数値をたどり、入れ子のルールを適用する場合に constantValue を使います。明示的に指定した場合だけ有効になり、既存の pattern、metavar、resolvedName、taint 解析の動作は変わりません。
基本形:
constantValue:
matches: unsafe-origin-value
metavar の下でも同じ形式を使えます。
動作:
- 最初に現在のノードへ入れ子のルールを直接適用します。
- ノードが識別子の場合は、最も近いレキシカルスコープの値の束縛を探し、その初期化式へルールを適用します。
const、型付きのconst、初期化式のあるlet/varに対応します。ただし、同じスコープ内で再代入されるlet/varは定数として扱いません。- 文字列、数値、Boolean、正規表現のリテラル、引数がリテラルだけの
new RegExp(...)、対応する定数式だけで構成した配列やオブジェクト、限定的な識別子の別名チェーンに対応します。 - JavaScript、TypeScript、TSX 以外では使えません。
例: CORS の origin が危険な正規表現そのもの、またはその正規表現を格納したローカル定数の場合に一致させます。
utils:
unsafe-origin-value:
any:
- kind: regex
regex: "[a-zA-Z0-9\\-]\\."
- all:
- pattern: new RegExp($PATTERN, $$$)
- has:
kind: string
regex: "[a-zA-Z0-9\\-]\\."
rule:
pattern: "cors({ origin: $ORIGIN, $$$ })"
metavar:
name: ORIGIN
eq:
constantValue:
matches: unsafe-origin-value
以下は origin の初期化式である正規表現リテラルをたどるため一致します。
const origin = /example\./;
cors({ origin });
以下は origin が再代入されるため、定数値として扱わず一致しません。
let origin = /example\./;
origin = safeOrigin;
cors({ origin });
import/require で取得した関数やオブジェクトのパッケージを確認する場合は resolvedName を使ってください。引数や設定値に使うローカル定数の初期化式を調べる場合は、constantValue を組み合わせてください。
compare
メタ変数に対する計算や条件の検査に compare を使います。
- Boolean
- Number
- 16 進、2 進、8 進形式(
0x、0b、0oなど)に対応
- 16 進、2 進、8 進形式(
例: 権限値の検査。BIT が指定された数値範囲に含まれるかを調べます。
any:
- pattern: os.chmod($FILE, $BIT, $$$)
- pattern: os.fchmod($FILE, $BIT, $$$)
- pattern: os.lchmod($FILE, $BIT, $$$)
compare: ( $BIT >= 0o650 && $BIT < 0o100000 ) || $BIT >= 0o100650