Bagaimana cara memfilter penggunaan Fungsi yang Ditentukan Pengguna Skal Nilai dari SQL Server Audit Data?


12

Kami memiliki database SQL Server yang memiliki spesifikasi audit database yang mengaudit semua tindakan yang dilakukan pada database.

CREATE DATABASE AUDIT SPECIFICATION [dbAudit]
FOR SERVER AUDIT [servAudit]
ADD (EXECUTE ON DATABASE::[DatabaseName] BY [public])

Kami telah menemukan bahwa beberapa pertanyaan akan menulis ke audit log penggunaan fungsi skalar untuk setiap baris di set hasil. Ketika ini terjadi, log terisi sebelum kita bisa ETL ke tempat peristirahatan terakhir dan kita memiliki celah dalam pencatatan kita.

Sayangnya karena alasan kepatuhan, kami tidak bisa berhenti mengaudit setiap EXECUTEpernyataan.

Pikiran pertama kami untuk pendekatan masalah ini adalah menggunakan WHEREklausa pada Server Audit untuk menyaring aktivitas. Kode tersebut terlihat seperti ini:

WHERE [object_id] not in (Select object_id from sys.objects where type = 'FN' )

Sayangnya, SQL Server tidak mengizinkan operator IN relasional (mungkin karena ia tidak ingin meminta setiap kali harus menulis ke log audit).

Kami ingin menghindari penulisan proc yang tersimpan yang kode kerasnya ada object_iddalam WHEREklausa, tetapi itulah pemikiran kami saat ini tentang cara terbaik untuk mendekati masalah ini. Apakah ada pendekatan alternatif yang harus kita pertimbangkan?

Kami telah memperhatikan bahwa ketika fungsi skalar digunakan dalam CTE rekursif, maka itu menyebabkan permintaan untuk menulis ke log audit untuk setiap baris dalam hasil yang ditetapkan.

Ada beberapa Fungsi Berharga Skalar yang dikirimkan oleh vendor yang tidak dapat kami hapus atau pindahkan ke database alternatif.


6
We've found that some queries will write to the audit log the use of a scalar function for every row in a result set.- Itulah salah satu efek samping paling menakjubkan dari skalar UDF yang pernah saya dengar, dan saya sering mendengar.
Erik Darling

3
Apakah ada opsi untuk membuat UDF yang Anda tidak ingin diaudit dalam database terpisah (yang tidak diaudit) dan memintanya melalui 3-bagian-nama?
Scott Hodgin

@ScottHodgin, saya suka solusinya, tetapi dalam keadaan kami ada beberapa Fungsi Berharga Scalar yang dikirimkan oleh vendor yang tidak dapat kami hapus atau pindahkan ke database alternatif.
Mark Iannucci

Mereka yang mengikuti mungkin bertanya-tanya kasus apa yang menyebabkan kueri menulis ke log audit untuk setiap baris dalam hasil yang ditetapkan; kami telah memperhatikannya terjadi ketika fungsi skalar digunakan dalam CTE rekursif.
Mark Iannucci

Jawaban:


6

Ada beberapa opsi yang bisa saya peroleh. Semua opsi berurusan dengan variasi predikat filter. CATATAN: Anda harus menonaktifkan Audit Server untuk membuat perubahan, dan kemudian mengaktifkannya kembali .

Pertama, pendekatan yang paling umum adalah menyaring semua UDF Skalar. Anda dapat melakukannya dengan menggunakan class_typebidang audit. Dokumentasi menunjukkan bahwa bidang ini VARCHAR(2), tetapi tidak memungkinkan menentukan string. Namun, saya berhasil menjalankan yang berikut ini:

ALTER SERVER AUDIT [servAudit]
WHERE ([class_type] <> 20038); -- EXECUTE Scalar UDF

(info lebih lanjut tentang penyelidikan itu di sini: Misteri Audit Server: Memfilter class_type mendapat Galat Msg 25713 )

Pendekatan paling umum berikutnya bukanlah pilihan karena dinyatakan bahwa ini adalah database yang disediakan vendor dan karenanya tidak ada perubahan yang dapat dilakukan. Jadi saya akan membahas yang terakhir.

Pendekatan yang paling tidak umum (tetapi yang pasti berhasil) adalah memfilter nama fungsi tertentu:

ALTER SERVER AUDIT [servAudit]
WHERE ([object_name]<>'function_name');

Atau, jika banyak nama:

ALTER SERVER AUDIT [servAudit]
WHERE ([object_name]<>'function_name1' AND [object_name]<>'function_name2');

Meskipun tidak terlalu umum, pendekatan ini harus baik-baik saja karena jumlah fungsi untuk disaring harus cukup kecil, dan tidak akan terlalu sering bahwa fungsi-fungsi baru diperkenalkan.

Akhirnya, untuk orang lain yang menghadapi situasi ini dan tidak dibatasi membuat perubahan: Anda dapat menempatkan fungsi ke dalam Skema mereka sendiri dan kemudian menyaring hanya Skema itu. Ini lebih umum daripada memfilter fungsi secara individual. Dengan asumsi bahwa Anda membuat Skema bernama fndan menempatkan fungsi ke dalamnya:

ALTER SERVER AUDIT [servAudit]
WHERE ([schema_name]<>'fn');

JUGA, mengenai dua komentar berikut dalam pertanyaan:

Sayangnya, SQL Server tidak mengizinkan operator IN relasional (mungkin karena ia tidak ingin meminta setiap kali harus menulis ke log audit).

dan:

Kami ingin menghindari penulisan proc tersimpan yang mengkodekan keras object_id dalam klausa WHERE

The INOperator tidak masalah. Benar, itu tidak didukung, tetapi hanya singkatan untuk daftar ORkondisi. Masalah sebenarnya adalah penggunaan T-SQL. Hanya literal - string atau angka - yang diizinkan. Jadi, Anda tidak akan bisa menjalankan Prosedur Tersimpan. Anda juga tidak dapat menggunakan fungsi bawaan.


terima kasih atas tanggapan ini. Kami sedang dalam proses menerapkan perubahan ini, dan saya akan menerima jawaban ini ketika kami mengonfirmasikannya berfungsi di lingkungan kami.
Mark Iannucci

1
@MarkIannucci Terima kasih! Juga, saya baru saja memperbaiki bug kecil dalam saran ideal saya. Saya telah menyalin dan menempel dari pengujian di mana saya memfilter fungsi FOR alih-alih fungsi APA SAJA. Saya mengubah =menjadi <>dalam jawaban saya. Saya juga baru mengujinya dan berfungsi seperti yang diiklankan :-)
Solomon Rutzky
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.