Rumah > Artikel > Operasi dan penyelenggaraan > Bagaimana Codeql menganalisis masalah kuki tidak mendayakan http sahaja
Hari ini kami menggunakan codeql untuk menganalisis isu keselamatan seperti "cookie is not enabled for httponly", dengan itu memperdalam penggunaan codeql kami. Jika ia berfungsi dengan baik, anda boleh mempertimbangkan untuk membetulkan kelemahan lain dalam Vulnerability-goapp.
Apabila menganalisis program go, anda juga mesti memuat turun codeql-go
Vulnerability-goapp: Aplikasi Web golang terdedah untuk pendidikan.
Memandangkan semua kuki dalam projek ini tidak mempunyai set atribut http sahaja, kami perlu mengubah suainya sebelum membuat perbandingan. Berikut ialah penulisan semula ayat asal: Pengubahsuaian rekod: Tambahkan pilihan http sahaja pada beberapa tetapan kuki.
pkgadminadmin.go diubah suai seperti berikut.
pkgloginlogin.go diubah suai seperti berikut.
pkgregisterregister.go diubah suai seperti berikut.
Ingat untuk menjana semula pangkalan data selepas pengubahsuaian (jika anda perlu menulis ganti DTabase lama, anda perlu memadam yang lama dahulu dan kemudian menjana yang baharu.
Ia adalah untuk menggunakan skrip codeql untuk mencari celah di mana httponly tidak ditetapkan dan httponly ditetapkan tetapi nilai httponly adalah palsu (biasanya ini tidak berlaku, tetapi ia tidak dijamin)
Sink sangat mudah Apabila menetapkan kuki, anda perlu menggunakan kaedah http.SetCookie, dan nilai kuki yang diperlukan yang akan ditetapkan ialah parameter kedua bagi fungsi ini. Kemudian kita boleh menulis Cari pernyataan pertanyaan Sink seperti ini Selepas menjalankan
import go from DataFlow::Node sink where exists(DataFlow::CallNode c | c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = sink ) select sink
, anda akan mendapat keputusan berikut segmen daripada keperluan kompaun. semua serpihan kod yang memenuhi syarat, sebagai contoh:
private class Sink extends DataFlow::Node { Sink() { exists(DataFlow::CallNode c | c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = this ) } }akan diperolehi selepas dijalankan parameter yang diterima oleh kaedah http.SetCookie, parameter kedua sebenar ialah penunjuk kepada struktur yang menerima Kuki Jadi kita perlu mencari struktur sedemikian terlebih dahulu. Mula-mula kita boleh menyenaraikan semua struktur dalam projek Mengenai struktur dalam codeql-go contoh,
import go private class Sink extends DataFlow::Node { Sink() { exists(DataFlow::CallNode c | c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = this ) } } from Sink s select s
Langkah seterusnya ialah menghapuskan kandungan lain yang tidak berkaitan dan mengehadkan jenis Mengenai kaedah hasQualifiedName. pelbagai jenis dalam pelbagai Codeql-go mempunyai kaedah yang sama Definisinya adalah seperti berikut pada pakej yang ditandakan dan apakah namanya Jika anda tidak pasti, anda boleh mencetak medan yang berkaitan melalui getPackage dan getName, untuk contoh. 🎜>Hasilnya adalah seperti berikut. ::Node.
Dengan Source dan Sink, tentukan TaintConfig untuk mendapatkan semua aliran data dari Source ke Sink.
import go from StructLit source select sourceHasilnya adalah seperti berikut:
Penghapusan
override predicate isSanitizer(DataFlow::Node node) { exists(Write w, Field f, DataFlow::Node rhs | f.hasQualifiedName("net/http", "Cookie", "HttpOnly") and w.writesField(node, f, rhs) and rhs.getBoolValue() = true ) }
运行结果如下,但有一处地方需要注意。
红框中实际有对HttpOnly进行设置,但我们的脚本并不能识别这样的一个数据流。后面试了各种方法,最终找到一种解决方式,将isSanitizer修改成以下内容。
override predicate isSanitizer(DataFlow::Node node) { exists(Write w, Field f, DataFlow::Node n, DataFlow::Node rhs | f.hasQualifiedName("net/http", "Cookie", "HttpOnly") and w.writesField(n, f, rhs) and rhs.getBoolValue() = true and node = n.getAPredecessor*()n ) }
其中node=n.getAPredecessor*()
是说node是n的前置数据流节点,数据可以在0个或多个步骤中从node流到n。
加上一些信息,模仿官方的示例,最终脚本如下。
/** * @name Cookie未设置httponly * @description Cookies包含一个HTTPOnly的设置选项,可以使此cookie不能被js读取,而只能用于HTTP请求。 * @kind path-problem * @problem.severity error * @precision low * @id go/Cookie-not-set-httponly * @tags security */ import go import DataFlow::PathGraph private class Source extends DataFlow::Node { Source() { exists(StructLit s | s.getType().hasQualifiedName("net/http", "Cookie") and this.asExpr() = s) } } private class Sink extends DataFlow::Node { Sink() { exists(DataFlow::CallNode c | c.getTarget().hasQualifiedName("net/http", "SetCookie") and c.getArgument(1) = this ) } } class Configuration extends TaintTracking::Configuration { Configuration() { this = "HttpOnly" } override predicate isSource(DataFlow::Node source) { source instanceof Source } override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } override predicate isSanitizer(DataFlow::Node node) { exists(Write w, Field f, DataFlow::Node n, DataFlow::Node rhs | f.hasQualifiedName("net/http", "Cookie", "HttpOnly") and w.writesField(n, f, rhs) and rhs.getBoolValue() = true and node = n.getAPredecessor*() ) } } from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink where cfg.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Cookie-not-set-httponly in $@.", source.getNode(), "here"
最终筛选出存在问题的内容。
Atas ialah kandungan terperinci Bagaimana Codeql menganalisis masalah kuki tidak mendayakan http sahaja. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!