
靜態(tài)分析SAST應用安全漏洞掃描代碼質量【免費下載鏈接】codeqlCodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security項目地址https://gitcode.com/gh_mirrors/co/codeql點擊查看免費下載本篇技術指南聚焦 CodeQL 倉庫中 C# 分析庫Modifiable類的三個可見性謂詞——isEffectivelyPrivate、isEffectivelyInternal與isEffectivelyPublic。這一組謂詞曾在 2021-06-15 的變更說明csharp/old-change-notes/2021-06-15-effective-visibility.md中宣告重做核心目的是正確處理 C# 的private protected、internal protected組合可見性以及顯式接口實現成員的可見性。讀完本文你將理解有效可見性effective visibility與聲明可見性的區(qū)別、三個謂詞的判定規(guī)則與實現細節(jié)以及如何通過測試用例驗證這些規(guī)則從而在你的自定義查詢中準確過濾掉實際上不可從當前程序集外部訪問的成員。變更背景從聲明修飾符到有效可見性在 C# 中一個成員的實際可訪問范圍并不總是與它聲明的訪問修飾符一一對應。典型例子包括嵌套類型中的成員一個聲明為public的成員如果它所在的類型本身是internal或private那么該成員實際上不可能被程序集外部引用受保護成員的可重寫性protected成員雖然可以被派生類訪問但private protected與protected internal在跨程序集場景下行為不同顯式接口實現void I.Foo() { }這樣的成員沒有普通意義上的可見性它只能通過接口引用訪問因此其有效可見性取決于被實現的接口本身。為此CodeQL 的 C# 庫在 csharp/ql/lib/semmle/code/csharp/Member.qll 的Modifiable類中提供了三個有效可見性謂詞回答的不是這個成員寫了什么修飾符而是這個成員在程序語義上到底能被誰引用。謂詞語義三個判定規(guī)則有效私有isEffectivelyPrivate在 Member.qll 中isEffectivelyPrivate()的定義為該聲明只能從以下位置引用——聲明它的類型及其嵌套類型與普通private一致以及它的封閉類型enclosing types。其實現包含三條判定路徑predicate isEffectivelyPrivate() { this.isReallyPrivate() or this.getDeclaringType().(Modifiable).isReallyPrivate() or this.(Virtualizable).getExplicitlyImplementedInterface().isEffectivelyPrivate() }自身為私有isReallyPrivate()是一個私有輔助謂詞要求isPrivate()且不是isProtected()同時排除極少數同名成員跨程序集以不同可見性定義的情況Member.qll封閉類型鏈私有this.getDeclaringType()沿聲明類型逐級向上查找表示一個或多個步驟只要任一封閉類型真正私有成員即視為有效私有顯式接口實現通過getExplicitlyImplementedInterface()取得顯式實現的接口若接口本身有效私有則該實現成員同樣有效私有。文檔注釋特別強調兩點顯式接口實現在接口本身有效私有時被視為有效私有而private protected成員不被視為有效私有因為它可以在聲明程序集內被重寫override。有效內部isEffectivelyInternalisEffectivelyInternal()的語義是該聲明只能從聲明它的程序集內部引用Member.qllpredicate isEffectivelyInternal() { this.isReallyInternal() or this.getDeclaringType().(Modifiable).isReallyInternal() or this.(Virtualizable).getExplicitlyImplementedInterface().isEffectivelyInternal() }其輔助謂詞isReallyInternal()判定兩條路徑Member.qllinternal且非protected即普通internalprivate且protected即private protected——注意它與internal的可達范圍相同都限于本程序集。同樣需要排除同名成員跨程序集不同可見性的稀有情況。文檔注釋中的兩個關鍵限定通過InternalsVisibleToAttribute聲明的友元程序集friend assemblies不在考慮范圍內——即只要理論上可能被其他程序集看到就歸為有效內部之外internal protected即protected internal成員不被視為有效內部因為它可以在聲明程序集之外被派生類重寫顯式接口實現成員若實現的接口本身有效內部則該成員同樣被視為有效內部。有效公開isEffectivelyPublicisEffectivelyPublic()是一個兜底定義Member.qll凡不是有效私有、也不是有效內部的聲明即可從程序集外部引用predicate isEffectivelyPublic() { not this.isEffectivelyPrivate() and not this.isEffectivelyInternal() }因此對任意Modifiable三個謂詞構成窮盡且互斥的三分任何成員必然恰好落在有效私有有效內部有效公開之一。測試驗證庫測試 Modifiers倉庫在 csharp/ql/test/library-tests/modifiers/ 提供了完整的庫測試來鎖定這些語義。被測代碼Modifiers.csModifiers.cs 構造了覆蓋各類修飾符組合的樣例其中與本次重做直接相關的成員包括internal protected readonly int F3; // 內部保護字段 public int P1 { get; set; } // 公開屬性 public int P2 { get; private set; } // 公開屬性、私有 setter internal interface I2 { void M1(); } // 內部接口 public class C2 : I2 { void I2.M1() throw null; // 顯式接口實現 protected private void M2() { } // private protected protected internal void M3() { } // internal protected }測試查詢Effectively.qlEffectively.ql 專門用于本組謂詞它找出三種聲明可見性與有效可見性不一致的情況并標記實際的有效可見性from Modifiable m, string s where m.fromSource() and ( m.isEffectivelyInternal() and not m.isInternal() and s internal or m.isEffectivelyPrivate() and not m.isPrivate() and s private or m.isEffectivelyPublic() and s public ) select m, s即對每個源碼中的聲明若isEffectivelyInternal()成立但聲明中并沒有internal修飾符就報告為internal若isEffectivelyPrivate()成立但沒有private修飾符報告為private凡有效公開者報告為public。預期結果Effectively.expected對照 Effectively.expected可以看到重做后的判定結果Modifiers.cs:12:14的M1注釋標記的私有方法→internal因為其封閉類型C默認是internalunsafe class C無可見性修飾符默認為 internal成員隨類型被限制在程序集內Modifiers.cs:24:22的C1被同時報告為internal與privatesealed class C1聲明于internal類內其構造器C1()是public但隨類型降至 internal而類本身隨內部類 C 降至有效私有Modifiers.cs:52:19的Spublic struct→publicModifiers.cs:68:14的I2.M1內部接口的默認實現方法→internalModifiers.cs:73:17的顯式接口實現void I2.M1()→internal這正是本次重做新增的判定——顯式實現成員的可見性繼承自被實現接口I2的可見性Modifiers.cs:75:32的protected private void M2()private protected→internal證明private protected被納入有效內部而非有效私有Modifiers.cs:76:33的protected internal void M3()→public因為internal protected可以被程序集外的派生類重寫故不歸為有效內部。這些預期輸出同時驗證了重做后的三條核心規(guī)則顯式接口實現的可見性跟隨接口、private protected歸入有效內部、internal protected歸入有效公開。謂詞在查詢中的實際應用這一組謂詞在倉庫的多個查詢與庫模塊中被廣泛使用用于過濾從外部實際不可達的成員提升查詢精度。csharp/ql/lib/semmle/code/csharp/telemetry/ExternalApi.qll在統(tǒng)計外部 API 使用情況時需要區(qū)分真正暴露給外部的成員與內部實現細節(jié)isEffectivelyPublic()等謂詞正是判定的基礎csharp/ql/src/Useless code/DefaultToStringQuery.qll、csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql、csharp/ql/src/Likely Bugs/Collections/WriteOnlyContainer.ql這些查詢在判斷成員是否可被外部觀察時使用有效可見性避免把僅程序集內部可見的成員當作公開 API 處理csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll 與 csharp/ql/src/utils/modeleditor/ModelEditor.qll模型生成工具需要按可見性決定是否為成員生成數據流模型csharp/ql/lib/semmle/code/csharp/dataflow/internal/Steps.qll、csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll數據流與派發(fā)分析中跨程序集邊界的數據流需要以有效可見性為準private protected/internal protected的可重寫性直接影響跨程序集調用圖的構造。從源碼結構看重做后的謂詞通過統(tǒng)一收斂到isReallyPrivate/isReallyInternal兩個私有輔助謂詞并把封閉類型鏈與顯式接口實現兩類場景顯式建模使得三個公開謂詞在所有Modifiable聲明上構成互斥且完備的劃分任何后續(xù)查詢只需選擇其一即可得到精確的可見性分類。小結isEffectivelyPrivate、isEffectivelyInternal、isEffectivelyPublic是 CodeQL C# 庫中關于成員可見性的核心抽象。2021-06-15 的重做補齊了三個此前處理不準確的場景private protected歸入有效內部、internal protected因其可跨程序集重寫而歸入有效公開、以及顯式接口實現可見性繼承自被實現接口。理解這三條規(guī)則不僅有助于讀懂ExternalApi、Dispatch等庫模塊的實現也能幫助你在編寫自定義安全查詢時正確判斷一個成員是否真正暴露在程序集外部從而減少誤報、提升分析的準確性。贊分享靜態(tài)分析SAST應用安全漏洞掃描代碼質量【免費下載鏈接】codeqlCodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security項目地址https://gitcode.com/gh_mirrors/co/codeql點擊查看免費下載相關推薦CodeQL C 溢出分析庫 SimpleRangeAnalysisexprMightOverflow* 謂詞如何變得更可靠CodeQL C 溢出分析庫 SimpleRangeAnalysisexprMightOverflow 謂詞如何變得更可靠 本文以 CodeQL C靜態(tài)分析SAST應用安全漏洞掃描代碼質量CodeQL C 庫 0.0.10 新增特性Variable::isStructuredBinding 謂詞詳解CodeQL C 庫 0.0.10 新增特性 Variable::isStructuredBinding 謂詞詳解 CodeQL 的 C 查詢庫在版本靜態(tài)分析SAST應用安全漏洞掃描代碼質量CodeQL C/C 查詢庫通過 Function 新謂詞精確分析 virtual、override 與 final 聲明CodeQL C/C 查詢庫通過 Function 新謂詞精確分析 virtual、override 與 final 聲明 導讀 在編寫 C 安全查詢靜態(tài)分析SAST應用安全漏洞掃描代碼質量上一篇BadPods項目深度挖掘can-they.sh腳本實現集群令牌自動化審計下一篇javascript-mini-projects深度剖析從貪吃蛇游戲看Canvas API的實戰(zhàn)應用創(chuàng)作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考