歡迎來到 黑吧安全網 聚焦網絡安全前沿資訊,精華內容,交流技術心得!

代碼分析平臺CodeQL學習手記(十七)

來源:本站整理 作者:佚名 時間:2020-03-11 TAG: 我要投稿

在前面的文章中,我們首先為讀者展示了如何通過LGTM查詢控制臺來編寫和運行分析JavaScript和TypeScript代碼的查詢。然后,講解了CodeQL的JavaScript標準庫中用于從文本級別和詞法級別分析源代碼的常用類及其謂詞。在本文中,我們繼續講解CodeQL的JavaScript標準庫中的其他類和謂詞。
聲明與綁定模式
我們知道,變量都是通過聲明語句(類DeclStmt)進行聲明的,而聲明語句主要有三種:var語句(由類VarDeclStmt表示),const語句(由類ConstDeclStmt表示)和let語句(由類LetStmt表示)。并且,每個聲明語句都含有一個或多個聲明符,具體由類VariableDeclarator表示。
每個聲明符由謂詞VariableDeclarator.getBindingPattern()返回的綁定模式和VariableDeclarator.getInit()返回的可選初始化表達式組成。
通常情況下,綁定模式就是一個簡單的標識符,如var x=42。然而,在ECMAScript2015及其更高的版本中,它也可以是更復雜的模式,如var [x, y] = arr。
實際上,各種綁定模式都是由類BindingPattern及其子類表示的:
· varref:L值位置的簡單標識符,例如var x中的x,或x=42中的x
· Parameter:函數或catch子句的參數
· ArrayPattern:數組模式,例如,[x,y]=arr語句中的左邊部分
· ObjectPattern:對象模式,例如{x, y: z} = o語句中的左邊部分
下面是一個查詢示例,它用于查找多次聲明同一個變量的聲明語句:
import javascript
 
from DeclStmt ds, VariableDeclarator d1, VariableDeclarator d2, Variable v, int i, int j
where d1 = ds.getDecl(i) and
    d2 = ds.getDecl(j) and
    i
下面是上面的代碼的運行結果:

由于這個問題很少見,因此,我們只在lgtm.com上的angular/angular.js項目找到了一個含有該問題的實例。
需要注意的是,這里及后面幾個查詢中都使用了not ... isMinified()。其作用是排除了在壓縮型代碼中找到的結果。如果我們刪除and not ds.getTopLevel().isMinified(),并重新運行該查詢,則會報告Meteor/Meteor項目中的壓縮型代碼中找到的兩個結果。
屬性
對象字面量中的屬性是由類Property表示的,它也是ASTNode的子類,但既不是Expr的子類,也不是STMT的子類。
類Property有兩個子類,即ValueProperty和PropertyAccessor類,它們分別表示常規值屬性和getter/setter屬性。同時,類PropertyAccessor又有兩個子類:PropertyGetter和PropertySetter類,它們分別表示getter和setter。
謂詞Property.getName()和Property.getInit()用于訪問已定義的屬性的名稱及其初始值。對于PropertyAccessor及其子類來說,可以覆寫getInit()使其返回getter/setter函數。
下面,我們將通過一個例子來介紹如何查詢屬性。在這里,該查詢用于查找包含兩個同名屬性的對象表達式,但不包括壓縮型代碼中的結果:
import javascript
 
from ObjectExpr oe, Property p1, Property p2, int i, int j
where p1 = oe.getProperty(i) and
    p2 = oe.getProperty(j) and
    i
上述示例的運行結果如下圖所示:

我們看到,許多項目都含有帶有兩個同名屬性的對象表達式。
模塊
分析JavaScript代碼的標準庫支持使用ECMAScript2015模塊,以及遺留的CommonJS模塊和AMD風格的各種模塊。其中,類ES2015Module、NodeModule和AMDModule分別用于表示上面所說的這三種類型的模塊,并且這它們都繼承自公共超類Module。
與模塊定義相關的重要成員謂詞包括:
· Module.getName():獲取模塊的名稱,注意,它獲取的名稱只是模塊名稱的主干部分,而不包括擴展名。
· Module.getAnImportedModule():獲取本模塊(通過import或require)導入的其他模塊。
· Module.getAnExportedSymbol():獲取本模塊導出的符號的名稱。
此外,分析JavaScript代碼的標準庫還提供了一個Import類,用于處理ECMAScript2015風格的import語句以及CommonJS/AMD風格的require語句;此外,通過該類的成員謂詞Import.getImportedModule,還可以訪問導入的模塊,如果可以靜態地確定該模塊的話。
名稱綁定
為了對名稱綁定進行建模,用于處理JavaScript代碼的標準庫使用了4個概念:作用域、變量、變量聲明和變量訪問,分別由類Scope、Variable、VarDecl和VarAccess表示。
作用域
在ECMAScript 5中,共有三種作用域:全局作用域(每個程序一個)、函數作用域(每個函數一個)和catch子句作用域(每個catch子句一個)。這三種作用域分別由類GlobalScope、FunctionScope和CatchScope作用域表示。ECMAScript 2015為let-bound變量增加了塊作用域,這些作用域也是通過類作用域(Scope)、類表達式作用域(ClassExprScope)和模塊作用域(ModuleScope)表示的。
用于表示類作用域的Scope類提供了以下應用編程接口:
· Scope.getScopeElement() 返回指向該作用域的AST節點;對于GlobalScope,尚未定義。
· Scope.getOuterScope()返回該作用域的詞法封閉作用域。
· Scope.getAnInnerScope()返回一個詞法上嵌套在此作用域內的作用域。
· Scope.getVariable(name)、Scope.getAVariable()返回在該作用域內(隱式或顯式)聲明的變量。
變量
Variable類可用于對JavaScript程序中的所有變量進行建模,包括全局變量、局部變量和參數(函數和catch子句),無論它們是否顯式聲明的。
重要的是,不要把變量與其聲明搞混了:局部變量可能有多個聲明,而全局變量和隱式聲明的局部參數變量根本不需要進行聲明。

[1] [2] [3] [4]  下一頁

【聲明】:黑吧安全網(http://www.www.hfjixin.com)登載此文出于傳遞更多信息之目的,并不代表本站贊同其觀點和對其真實性負責,僅適于網絡安全技術愛好者學習研究使用,學習中請遵循國家相關法律法規。如有問題請聯系我們,聯系郵箱admin@www.hfjixin.com,我們會在最短的時間內進行處理。
  • 最新更新
    • 相關閱讀
      • 本類熱門
        • 最近下載
        百度 好搜 搜狗

        警告:本站禁止未滿18周歲訪客瀏覽,如果當地法律禁止請自覺離開本站!收藏本站:請使用Ctrl+D進行收藏