Mengonfigurasi atribut bahasa aturan kustom

Setiap aturan kebijakan keamanan Google Cloud Armor memiliki prioritas, kondisi kecocokan, dan tindakan. Google Cloud Armor melakukan tindakan aturan prioritas tertinggi yang cocok dengan permintaan. Aturan dengan prioritas lebih rendah daripada aturan pencocokan prioritas tertinggi tidak dievaluasi, meskipun memiliki kondisi pencocokan yang sama.

Setiap aturan kebijakan keamanan mendukung dua jenis kondisi kecocokan:

  • Kondisi kecocokan dasar berisi daftar alamat IP atau daftar rentang alamat IP. Kondisi kecocokan dasar ditentukan menggunakan flag --src-ip-ranges saat membuat aturan menggunakan Google Cloud CLI.
  • Kondisi pencocokan lanjutan berisi ekspresi dengan maksimal lima subekspresi yang dapat mencocokkan berbagai atribut permintaan yang masuk. Kondisi pencocokan lanjutan ditentukan menggunakan flag --expression saat membuat aturan menggunakan Google Cloud CLI.

Halaman ini membahas kondisi pencocokan lanjutan dan bahasa aturan kustom Google Cloud Armor yang Anda gunakan untuk menulis ekspresi dalam kondisi pencocokan lanjutan aturan kebijakan keamanan. Bahasa aturan kustom Google Cloud Armor adalah subset dari Common Expression Language (CEL). Ekspresi yang ditulis dalam bahasa aturan kustom Google Cloud Armor memerlukan dua komponen:

  • Atribut: data yang akan diperiksa
  • Operasi: cara menggunakan data

Misalnya, ekspresi berikut menggunakan atribut origin.ip dan 9.9.9.0/24 dalam operasi inIpRange(). Dalam hal ini, ekspresi akan menampilkan true jika origin.ip berada dalam rentang alamat IP 9.9.9.0/24.

inIpRange(origin.ip, '9.9.9.0/24')

Meskipun ekspresi contoh sebelumnya hanya cocok dengan alamat IP sumber, saat Anda menggunakan ekspresi contoh dalam aturan kebijakan keamanan Google Cloud Armor, aturan tersebut dianggap sebagai aturan dengan kondisi pencocokan lanjutan dari perspektif kuota. Untuk informasi selengkapnya, lihat Kuota dan batas Google Cloud Armor.

Atribut

Atribut mewakili informasi dari permintaan masuk, seperti alamat IP asal atau jalur URL yang diminta.

Kolom Jenis Deskripsi kolom
origin.ip string Alamat IP sumber permintaan.
origin.user_ip string Alamat IP klien asal, yang disertakan dalam HTTP-HEADER oleh proxy upstream. Sebelum menggunakan atribut ini, Anda harus mengonfigurasi opsi userIpRequestHeaders[] di kolom advancedOptionsConfig kebijakan keamanan agar cocok dengan sumber seperti True-Client-IP, X-Forwarded-For, atau X-Real-IP.

Jika Anda tidak mengonfigurasi opsi userIpRequestHeaders[], jika header yang dikonfigurasi berisi nilai alamat IP yang tidak valid, atau jika header yang dikonfigurasi tidak ada, origin.user_ip akan ditetapkan secara default ke origin.ip. Untuk informasi selengkapnya, lihat referensi resource securityPolicy.

origin.tls_ja3_fingerprint string Sidik jari TLS/SSL JA3 jika klien terhubung menggunakan HTTPS, HTTP/2, atau HTTP/3. Jika tidak tersedia, string kosong akan ditampilkan.
request.headers map Peta string-ke-string dari header permintaan HTTP. Jika header berisi beberapa nilai, nilai dalam peta ini akan berupa string yang dipisahkan koma dari semua nilai header. Semua kunci dalam peta ini berhuruf kecil. Semua header yang diterima oleh Load Balancer Aplikasi eksternal akan diperiksa, dan batasan header yang sama akan berlaku.

Pendekatan yang direkomendasikan adalah memeriksa ketersediaan terlebih dahulu menggunakan has(), seperti has(request.headers['header-key']) && request.headers['header-key'] != 'header-value'.

request.method string Metode permintaan HTTP, seperti GET atau POST.
request.path string Jalur URL HTTP yang diminta.
request.scheme string Skema URL HTTP seperti http atau https. Semua nilai untuk atribut ini adalah huruf kecil.
request.query string Kueri URL HTTP dalam format name1=value&name2=value2, seperti yang muncul di baris pertama permintaan HTTP. Tidak ada decoding yang dilakukan.
origin.region_code string Kode negara Unicode yang terkait dengan IP asal, seperti US. Jika Anda membuat aturan atau ekspresi yang menggunakan kode negara atau wilayah ISO 3166-1 alpha 2, Google Cloud Armor akan memperlakukan setiap kode secara terpisah. Aturan dan ekspresi Google Cloud Armor secara eksplisit menggunakan kode region tersebut untuk mengizinkan atau menolak permintaan.

Untuk mengetahui informasi selengkapnya, lihat unicode_region_subtag dalam Standar Teknis Unicode.

origin.asn bilangan bulat Nomor sistem otonom (ASN) yang terkait dengan alamat IP asal. ASN unik secara global ditentukan berdasarkan operator jaringan yang mendukung awalan alamat IP yang berisi alamat IP asal.

Atribut reCAPTCHA

Bagian ini mencantumkan atribut yang hanya berlaku untuk token reCAPTCHA atau cookie pengecualian. Subekspresi berdasarkan atribut ini menampilkan false jika token reCAPTCHA atau cookie pengecualian yang akan dievaluasi tidak tersedia atau tidak valid karena salah satu alasan berikut:

  • Token memiliki format yang salah dan tidak dapat didekode.
  • Token berisi atribut yang tidak valid. Misalnya, token dibuat menggunakan kunci reCAPTCHA yang tidak cocok dengan kunci reCAPTCHA terkait aturan.
  • Masa berlaku token telah berakhir.
Kolom Jenis Deskripsi kolom
token.recaptcha_exemption.valid bool Adanya cookie pengecualian reCAPTCHA yang valid.

Atribut token tindakan

Kolom Jenis Deskripsi kolom
token.recaptcha_action.score float Skor dari token tindakan reCAPTCHA. Skor valid berkisar dari 0.0 hingga 1.0, dengan 0.0 sangat mungkin pengguna tidak sah, dan 1.0 sangat mungkin pengguna sah.
token.recaptcha_action.captcha_status string Status captcha dari token tindakan reCAPTCHA. Status yang valid adalah NONE, PASS, atau FAIL, dengan NONE mengacu pada saat tidak ada tantangan yang terlibat selama penilaian reCAPTCHA, sehingga kolom captcha tidak ada di token tindakan.
token.recaptcha_action.action string Nama tindakan (maksimal 100 karakter) dari token tindakan reCAPTCHA. Lihat Nama tindakan.
token.recaptcha_action.valid bool Adanya token tindakan reCAPTCHA yang valid.

Atribut token sesi

Kolom Jenis Deskripsi kolom
token.recaptcha_session.score float Skor dari token sesi reCAPTCHA. Skor yang valid berkisar dari 0.0 hingga 1.0, dengan 0.0 sangat mungkin pengguna tidak sah, dan 1.0 sangat mungkin pengguna sah.
token.recaptcha_session.valid bool Adanya token sesi reCAPTCHA yang valid.

Operasi

Referensi berikut menjelaskan operator yang dapat Anda gunakan dengan atribut (diwakili oleh x, y, dan k) untuk menentukan ekspresi aturan.

Ekspresi Deskripsi
x == "foo" Menampilkan true jika x sama dengan literal string konstan yang diberikan.
x == R"fo'o" Menampilkan benar jika x sama dengan literal string mentah yang diberikan yang tidak menafsirkan urutan escape. Literal string mentah mudah digunakan untuk mengekspresikan string yang harus menggunakan karakter urutan escape.
x == y Menampilkan nilai benar jika x sama dengan y.
x != y Menampilkan nilai benar jika x tidak sama dengan y.
x + y Menampilkan string yang digabungkan xy.
x && y Menampilkan benar jika x dan y benar.
x || y Menampilkan nilai benar jika x, y, atau keduanya benar.
!x Menampilkan benar jika nilai Boolean x salah, atau menampilkan salah jika nilai Boolean x benar.
x.contains(y) Menampilkan benar jika string x berisi substring y.
x.startsWith(y) Menampilkan nilai benar jika string x diawali dengan substring y.
x.endsWith(y) Menampilkan nilai benar jika string x diakhiri dengan substring y.
x.matches(y) Menampilkan true jika string x sebagian cocok dengan pola RE2 yang ditentukan y. Pola RE2 dikompilasi menggunakan opsi RE2::Latin1 yang menonaktifkan fitur Unicode.
inIpRange(x, y) Menampilkan true jika alamat IP x terdapat dalam rentang IP y.
x.lower() Menampilkan nilai huruf kecil dari string x.
x.upper() Menampilkan nilai huruf besar dari string x.
x.base64Decode() Menampilkan nilai x yang didekode base64; karakter _ - pertama-tama diganti dengan / +. Menampilkan "" (string kosong) jika x bukan nilai base64 yang valid.
has(m['k']) Menampilkan true jika kunci k tersedia di peta m.
m['k'] Menampilkan nilai pada kunci k dalam peta string ke string m jika k tersedia; jika tidak, menampilkan error. Pendekatan yang direkomendasikan adalah memeriksa ketersediaan terlebih dahulu menggunakan "has(m['k'])==true".
int(x) Mengonversi hasil string x menjadi jenis int. Kemudian, nilai ini dapat digunakan untuk melakukan perbandingan bilangan bulat menggunakan operator aritmetika standar seperti > dan <=. Hal ini hanya berfungsi untuk nilai yang seharusnya berupa bilangan bulat.
size(x) Menampilkan panjang string x.
x.urlDecode() Menampilkan nilai x yang didekode URL; urutan karakter dalam format %## diganti dengan yang setara non-ASCII, dan + diganti dengan spasi. Encoding yang tidak valid akan ditampilkan apa adanya.
x.urlDecodeUni() Menampilkan nilai x yang didekode URL; selain urlDecode(), ini juga menangani urutan karakter unicode dalam format %u###. Encoding yang tidak valid akan ditampilkan apa adanya.
x.utf8ToUnicode() Menampilkan representasi Unicode huruf kecil dari x yang dienkode UTF-8.

Contoh ekspresi

Untuk setiap ekspresi ini, tindakan yang diambil bergantung pada apakah ekspresi disertakan dalam aturan tolak atau aturan izinkan.

Mengizinkan atau menolak akses berdasarkan rentang alamat IP di IPv4 atau IPv6

  • Ekspresi berikut cocok dengan permintaan dari rentang alamat IP 198.51.100.0/24:

    inIpRange(origin.ip, '198.51.100.0/24')
    
  • Ekspresi berikut cocok dengan permintaan dari rentang alamat IP 2001:db8::/32:

    inIpRange(origin.ip, '2001:db8::/32')
    

Mengizinkan atau menolak akses berdasarkan rentang alamat IP klien kustom di belakang proxy upstream

Jika telah mengonfigurasi operator origin.user_ip, Anda dapat mencocokkan berdasarkan nilai header yang ditentukan di kolom advancedOptionsConfig.userIpRequestHeaders[].

  • Ekspresi berikut cocok dengan permintaan yang berasal dari rentang alamat IP 192.0.2.0/24:

    inIpRange(origin.user_ip, '192.0.2.0/24')
    
  • Ekspresi berikut cocok dengan permintaan yang berasal dari rentang alamat IP 2001:db8::/32:

    inIpRange(origin.user_ip, '2001:db8::/32')
    
  • Ekspresi berikut cocok dengan permintaan yang memiliki cookie yang berisi 80=BLAH:

    has(request.headers['cookie']) && request.headers['cookie'].contains('80=BLAH')
    

Mengizinkan atau menolak traffic dengan header referer yang tidak kosong

  • Ekspresi berikut cocok dengan permintaan yang memiliki header referer yang tidak kosong:

    has(request.headers['referer']) && request.headers['referer'] != ""
    

Mengizinkan atau menolak traffic berdasarkan URL host di header

  • Ekspresi berikut cocok dengan permintaan ke URL tertentu:

    request.headers['host'].lower().contains('test.example.com')
    

Mengizinkan atau menolak traffic dari wilayah tertentu

Jika aplikasi web Anda tidak tersedia di region AU, semua permintaan dari region tersebut harus diblokir.

  • Dalam aturan tolak, gunakan ekspresi berikut, yang cocok dengan permintaan dari region AU:

    origin.region_code == 'AU'
    

Atau, jika aplikasi web Anda hanya tersedia di wilayah AU, permintaan dari semua wilayah lain harus diblokir.

  • Dalam aturan tolak, gunakan ekspresi berikut, yang cocok dengan permintaan dari semua region selain region AU:

    origin.region_code != 'AU'
    

Kode wilayah didasarkan pada kode ISO 3166-1 alpha 2. Dalam beberapa kasus, wilayah sesuai dengan negara, tetapi hal ini tidak selalu berlaku. Misalnya, kode US mencakup semua negara bagian Amerika Serikat, satu distrik, dan enam area terpencil.

Mengizinkan atau menolak traffic dari ASN tertentu

Jika aplikasi web Anda perlu diblokir untuk pelanggan yang dilayani oleh operator jaringan tertentu, Anda dapat menggunakan nomor ASN operator jaringan untuk memblokir.

  • Dalam aturan penolakan, gunakan ekspresi berikut, yang cocok dengan permintaan dari ASN tertentu:

    origin.asn == 123
    

Atau, jika aplikasi web Anda hanya tersedia untuk pelanggan di belakang operator jaringan tertentu, permintaan dari semua operator jaringan lainnya harus diblokir.

  • Dalam aturan tolak, gunakan ekspresi berikut, yang cocok dengan semua operator jaringan lain selain yang ingin Anda izinkan:

    origin.asn != 123
    

Beberapa ekspresi

Untuk menyertakan beberapa kondisi dalam satu aturan, gabungkan beberapa subekspresi.

  • Dalam contoh berikut, permintaan dari 1.2.3.0/24 (seperti penguji alfa Anda) di region AU cocok dengan ekspresi berikut:

    origin.region_code == "AU" && inIpRange(origin.ip, '1.2.3.0/24')
    
  • Ekspresi berikut cocok dengan permintaan dari 1.2.3.4 tempat agen pengguna berisi string WordPress:

    inIpRange(origin.ip, '1.2.3.4/32') &&
    has(request.headers['user-agent']) && request.headers['user-agent'].contains('WordPress')
    

Mengizinkan atau menolak traffic untuk URI permintaan yang cocok dengan ekspresi reguler

  • Ekspresi berikut cocok dengan permintaan yang berisi string example_path di URI:

    request.path.matches('/example_path/')
    
  • Ekspresi berikut cocok dengan permintaan yang memiliki Chrome di kolom header User-Agent:

    request.headers['user-agent'].matches('Chrome')
    
  • Ekspresi berikut menunjukkan pencocokan yang tidak peka huruf besar/kecil untuk header User-Agent yang berisi wordpress; pencocokan ini cocok dengan User-Agent:WordPress/605.1.15, User-Agent:wordPress, dan variasi wordpress lainnya:

    request.headers['user-agent'].matches('(?i:wordpress)')
    

Mengizinkan atau menolak traffic yang berisi nilai yang didekode base64 tertentu

  • Ekspresi berikut cocok dengan permintaan yang memiliki nilai myValue yang didekode base64 untuk header user-id:

    has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')
    

Mengizinkan atau menolak traffic yang berisi nilai string dengan panjang tertentu

  • Ekspresi berikut cocok dengan permintaan yang memiliki panjang URL lebih dari 10 karakter:

    size(request.path) > 10
    
  • Ekspresi berikut cocok dengan permintaan yang memiliki panjang x-data header lebih besar dari atau sama dengan 1.024 karakter:

    size(request.headers['x-data']) >= 1024
    

Mengizinkan atau menolak traffic yang memiliki content-length nol di isi HTTP

  • Ekspresi berikut cocok dengan permintaan yang memiliki content-length nol dalam isi HTTP:

    int(request.headers["content-length"]) == 0
    

Mengizinkan atau menolak traffic yang berisi nilai yang dienkode URL tertentu

  • Ekspresi berikut cocok dengan permintaan yang memiliki nilai cookie yang berisi %3c:

    has(request.headers['cookie']) && request.headers['cookie'].urlDecode().contains('<')
    

Mengizinkan atau menolak traffic yang berisi nilai string Unicode yang dienkode URL tertentu

  • Ekspresi berikut cocok dengan permintaan yang memiliki nilai cookie yang sama dengan Match%2BValue atau Match%u002BValue:

    has(request.headers['cookie']) && request.headers['cookie'].urlDecodeUni() == 'Match+Value'
    

Mengizinkan atau menolak traffic yang berisi string Unicode tertentu dari teks UTF-8

  • Ekspresi berikut cocok dengan permintaan yang memiliki nilai cookie yang sama dengan ¬:

    has(request.headers['cookie']) && request.headers['cookie'].utf8ToUnicode() == '%u00ac'
    

Mengizinkan atau menolak traffic berdasarkan sidik jari JA3 yang diketahui

  • Ekspresi berikut cocok dengan permintaan yang memiliki sidik jari JA3 yang sama dengan e7d705a3286e19ea42f587b344ee6865:

    origin.tls_ja3_fingerprint == 'e7d705a3286e19ea42f587b344ee6865'
    

Mengizinkan atau menolak traffic berdasarkan daftar sidik jari JA3

  • Ekspresi berikut cocok dengan permintaan yang memiliki sidik jari JA3 yang sama dengan salah satu sidik jari JA3 berikut:

    • e7d705a3286e19ea42f587b344ee6865
    • f8a5929f8949e846267b582072e35f84
    • 8f8b62163873a62234c14f15e7b88340
    origin.tls_ja3_fingerprint == 'e7d705a3286e19ea42f587b344ee6865' || origin.tls_ja3_fingerprint == 'f8a5929f8949e846267b582072e35f84' || origin.tls_ja3_fingerprint == '8f8b62163873a62234c14f15e7b88340'
    

Aturan WAF yang telah dikonfigurasi sebelumnya

Aturan WAF yang telah dikonfigurasi sebelumnya menggunakan tanda tangan statis, ekspresi reguler, atau keduanya yang telah dikonfigurasi sebelumnya untuk dicocokkan pada isi HTTP POST, header permintaan HTTP, dan parameter kueri. Aturan WAF yang telah dikonfigurasi sebelumnya dan tersedia didasarkan pada kumpulan aturan inti Modsecurity OWASP versi 3.3. Google Cloud Armor menyediakan beberapa aturan WAF pra-konfigurasi yang telah ditetapkan sebelumnya. Untuk mengetahui daftar lengkap aturan WAF yang telah dikonfigurasi sebelumnya, lihat Ringkasan aturan WAF yang telah dikonfigurasi sebelumnya oleh Google Cloud Armor.

Untuk mencantumkan semua aturan WAF yang telah dikonfigurasi sebelumnya, lihat Mencantumkan aturan WAF yang telah dikonfigurasi sebelumnya yang tersedia.

Untuk mengetahui informasi selengkapnya tentang aturan WAF yang telah dikonfigurasi sebelumnya, lihat kasus penggunaan Memitigasi serangan lapisan aplikasi menggunakan aturan WAF yang telah dikonfigurasi sebelumnya.

Nama aturan WAF yang telah dikonfigurasi sebelumnya

Nama aturan WAF yang telah dikonfigurasi sebelumnya memiliki format <attack category>-<ModSecurity CRS version>-<version field>. Kategori serangan menentukan jenis serangan yang ingin Anda lindungi, seperti xss (skrip lintas situs) atau sqli (injeksi SQL).

Kolom versi yang didukung adalah stable dan canary. Penambahan dan perubahan pada aturan dirilis dalam versi canary terlebih dahulu. Jika penambahan dan modifikasi dianggap aman dan stabil, keduanya akan dipromosikan ke versi stable.

ID anggota aturan WAF yang telah dikonfigurasi sebelumnya

Aturan WAF yang telah dikonfigurasi sebelumnya berisi beberapa ekspresi, masing-masing dengan tanda tangannya. Misalnya, aturan WAF pra-konfigurasi xss-v33-stable menyertakan ekspresi yang disebut owasp-crs-v030301-id941100-xss, yang sesuai dengan ID aturan id941100 untuk versi 3.3. Anda dapat menggunakan tanda tangan untuk mengecualikan ekspresi tertentu agar tidak digunakan, yang berguna jika ekspresi tertentu secara konsisten memicu hasil positif palsu. Untuk mengetahui informasi selengkapnya, lihat informasi pemecahan masalah hasil positif palsu.

Untuk informasi tentang kumpulan aturan inti dan penyesuaian pada berbagai tingkat sensitivitas, lihat Menyesuaikan aturan WAF Google Cloud Armor.

Operator untuk aturan WAF yang telah dikonfigurasi sebelumnya

Ekspresi Deskripsi
evaluatePreconfiguredWaf(string, MAP<string, dyn>) Menampilkan true jika salah satu tanda tangan WAF di dalam kumpulan aturan WAF yang ditentukan menampilkan true. Argumen pertama adalah nama kumpulan aturan WAF, seperti xss-v33-stable. Argumen kedua (opsional) adalah peta dengan kunci berupa string dan nilainya di-type secara dinamis, bergantung pada kunci. Tujuan argumen ini adalah untuk menyesuaikan tanda tangan WAF mana yang dievaluasi. Kunci yang diterima mencakup hal berikut:
  • "sensitivity": Ini sesuai dengan tingkat paranoia Kumpulan Aturan Inti ModSecurity, yang memiliki 4 tingkat, mulai dari 1 hingga 4. Nilainya adalah bilangan bulat dengan rentang yang valid dari 0 hingga 4. Perhatikan bahwa 0 dicadangkan sebagai nilai yang valid saat digunakan bersama dengan "opt_in_rule_ids" (dijelaskan nanti). Saat menentukan sensitivitas x (x >= 1), semua tanda tangan WAF terkait dengan nilai sensitivitas dari 1 hingga x akan dievaluasi. Jika dihilangkan, 4 akan digunakan sebagai nilai sensitivitas.
  • "opt_out_rule_ids": Tanda tangan WAF (diwakili oleh ID aturan) yang tidak akan diikutsertakan dalam evaluasi, dengan kumpulan dasar ditentukan oleh nilai sensitivitas. Nilainya adalah daftar string. Jumlah maksimum ID aturan yang diizinkan adalah 128.
  • "opt_in_rule_ids": Tanda tangan WAF (diwakili oleh ID aturan) yang akan diikutsertakan dalam evaluasi, dengan set dasar kosong. Nilainya adalah daftar string. Jumlah maksimum ID aturan yang diizinkan adalah 128. Saat menggunakannya, "sensitivitas" 0 harus ditentukan.

Kunci "opt_out_rule_ids" dan "opt_in_rule_ids" tidak dapat terjadi bersamaan. Anda dapat memilih untuk menggunakan "opt_in_rule_ids" jika ingin meninjau dan mengaktifkan secara manual tanda tangan WAF baru yang ditambahkan nanti ke kumpulan aturan yang ada.

evaluatePreconfiguredExpr(string, LIST)

Menampilkan nilai benar jika salah satu ekspresi di dalam aturan WAF pra-konfigurasi yang ditentukan menampilkan nilai benar.

Argumen pertama adalah nama aturan WAF yang telah dikonfigurasi sebelumnya, seperti xss-stable. Argumen kedua (opsional) adalah daftar string ID yang dipisahkan koma yang harus dikecualikan dari evaluasi. Daftar pengecualian berguna saat anggota tertentu dari aturan WAF yang telah dikonfigurasi sebelumnya memicu positif palsu.

Contoh aturan WAF yang telah dikonfigurasi sebelumnya

  • Ekspresi berikut menggunakan aturan WAF yang telah dikonfigurasi sebelumnya xss-v33-stable untuk mitigasi serangan XSS:

    evaluatePreconfiguredExpr('xss-v33-stable')
    
  • Ekspresi berikut menggunakan semua ekspresi dari aturan WAF yang telah dikonfigurasi sebelumnya xss-v33-stable kecuali untuk ID anggota 941100 dan 941110:

    evaluatePreconfiguredExpr('xss-v33-stable', ['owasp-crs-v030301-id941100-xss',
    'owasp-crs-v030301-id941110-xss'])
    
  • Ekspresi berikut menggunakan aturan WAF yang telah dikonfigurasi sebelumnya untuk mengurangi serangan SQLi dari rentang alamat IP 198.51.100.0/24:

    inIpRange(origin.ip, '198.51.100.0/24') && evaluatePreconfiguredExpr('sqli-v33-stable')
    

Langkah selanjutnya