Fortify 掃描耗盡了記憶體

Fortify 掃描發生 java.lang.OutOfMemoryError: GC overhead limit exceeded,代表 JVM 記憶體 Heap 空間不足,且垃圾回收(GC)耗費超過 98% 的時間卻只能回收不到 2% 的記憶體。堆疊訊息顯示 Fortify 在解析 PHP 的 hereDoc (Heredoc語法) 時耗盡了記憶體。

請依序嘗試以下解決方案:

1. 增加 Fortify 掃描的記憶體上限

預設的記憶體設定可能不足以處理大型專案或複雜的 PHP 檔案。可以在執行 sourceanalyzer 命令行中加入 -Xmx 參數來提高記憶體配額:

命令列執行 (CLI):

sourceanalyzer -b <build_id> -Xmx16G -scan -f result.fpr 

(可依你的伺服器硬體規格調整,例如 -Xmx12G-Xmx24G)

若使用 GUI (Audit Workbench / ScanWizard):

開啟 Fortify Audit Workbench。

進入 Options > Global Settings > Memory Options

Maximum Allocation (-Xmx) 調大(如 16384 MB)。

修改全域設定檔 (fortify-sca.properties):

找到 Fortify 安裝目錄或使用者目錄下的設定檔(例如 <Fortify_Home>/Core/config/fortify-sca.properties),修改或加入以下參數:

com.fortify.sca.ProjectScanMemoryMB=16384

2. 排除不必要的檔案或大型自動生成檔

從錯誤堆疊可看出問題出在解析 PHP 的 hereDoc 語法(可能是巨大的模板檔、自動生成的 SQL/Data 檔、或是包含大字串陣列的檔案)。

如果增加記憶體後仍失敗,建議排除非必要的第三方套件與靜態檔:

在翻譯(Translation)階段使用 -exclude 排除特定目錄或檔案:

sourceanalyzer -b <build_id> -exclude "/vendor/" -exclude "/node_modules/" -exclude "/*.min.js" src/

過濾大檔案:

可以在 fortify-sca.properties 中限制 Fortify 解析單一檔案的大小上限:

com.fortify.sca.limit.file.size=10240 

(單位為 KB,例如設定 10240 會跳過大於 10MB 的單一原始碼檔案)

3. 採用「雙階段掃描」分離記憶體開銷

若原本是單一指令執行,請改為將翻譯 (Translation)掃描 (Scan)拆為兩個獨立步驟,並只在掃描階段調大記憶體:

# 第一步:翻譯階段
sourceanalyzer -b myproject -clean
sourceanalyzer -b myproject ./src

# 第二步:分析掃描階段 (在此處給予最大記憶體)
sourceanalyzer -b myproject -Xmx16G -scan -f result.fpr

建議處理順序

  1. 直接將記憶體調大至 16G (-Xmx16G) 重試一次。
  2. 若依然爆記憶體,檢查專案中是否有包含大量文字資料的 .php 檔案(如大陣列檔、DB dump 檔、巨型 Heredoc 模板),並使用 -exclude 將其排除。

detail error message:

[error]: There is not enough memory available to complete analysis.  For details on making more memory available, please consult the user manual.
java.lang.OutOfMemoryError: GC overhead limit exceeded
at com.fortify.frontend.php.parser.PHPLexerBase.nextToken(PHPLexerBase.java:95) ~[?:?]
at org.antlr.v4.runtime.BufferedTokenStream.fetch(BufferedTokenStream.java:169) ~[antlr4-runtime-4.13.1.jar:4.13.1]
at org.antlr.v4.runtime.BufferedTokenStream.sync(BufferedTokenStream.java:152) ~[antlr4-runtime-4.13.1.jar:4.13.1]
at org.antlr.v4.runtime.BufferedTokenStream.nextTokenOnChannel(BufferedTokenStream.java:325) ~[antlr4-runtime-4.13.1.jar:4.13.1]
at org.antlr.v4.runtime.CommonTokenStream.adjustSeekIndex(CommonTokenStream.java:70) ~[antlr4-runtime-4.13.1.jar:4.13.1]
at org.antlr.v4.runtime.BufferedTokenStream.consume(BufferedTokenStream.java:137) ~[antlr4-runtime-4.13.1.jar:4.13.1]
at org.antlr.v4.runtime.Parser.consume(Parser.java:571) ~[antlr4-runtime-4.13.1.jar:4.13.1]
at org.antlr.v4.runtime.Parser.match(Parser.java:205) ~[antlr4-runtime-4.13.1.jar:4.13.1]
at com.fortify.frontend.php.parser.PHPParser.hereDocPart(PHPParser.java:9032) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.hereDocExpr(PHPParser.java:8947) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.primaryExpr(PHPParser.java:9230) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.exponentExpr(PHPParser.java:8627) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.unaryExpr(PHPParser.java:8571) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.instanceofExpr(PHPParser.java:8470) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.notExpr(PHPParser.java:8412) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.productExpr(PHPParser.java:8321) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.sumExpr(PHPParser.java:8222) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.shiftExpr(PHPParser.java:8123) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.comparisonExpr(PHPParser.java:8037) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.equalityExpr(PHPParser.java:7960) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.bitwiseAndExpr(PHPParser.java:7883) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.bitwiseXorExpr(PHPParser.java:7805) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.bitwiseOrExpr(PHPParser.java:7727) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.booleanAndExpr(PHPParser.java:7649) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.booleanOrExpr(PHPParser.java:7571) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.nullCoalescingExpr(PHPParser.java:7501) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.ternaryExpr(PHPParser.java:7426) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.assignExpr(PHPParser.java:9557) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.primaryExpr(PHPParser.java:9276) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.exponentExpr(PHPParser.java:8627) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.unaryExpr(PHPParser.java:8571) ~[?:?]
at com.fortify.frontend.php.parser.PHPParser.instanceofExpr(PHPParser.java:8470) ~[?:?]

這兩個問題解答如下:

第一題:Bash 命令列上的 myproject 存在哪裡?

在 Fortify 命令列中:

sourceanalyzer -b myproject -clean
sourceanalyzer -b myproject ./src
sourceanalyzer -b myproject -scan -f result.fpr

-b myproject 中的 myproject 稱為 Build ID(建置識別碼)

不是一個真實的專案資料夾名稱,而是 Fortify 在系統內部用來記錄「翻譯(Translation)階段抽取的原始碼 AST 語法樹與中間檔」的暫存標籤

1. 實際檔案存在哪裡?

Fortify 會將 myproject 的中間檔案儲存在使用者家目錄下的 Fortify SCA 暫存區

  • Linux / macOS:
    ~/.fortify/sca<版本號>/build/myproject/
  • Windows (PowerShell / CMD):
    C:\Users\<帳號>\.fortify\sca<版本號>\build\myproject\

2. 注意事項

  • 執行 -clean 時(如 sourceanalyzer -b myproject -clean),Fortify 就會刪除這個路徑下名為 myproject 的暫存資料夾。
  • 在同一次掃描任務中,Translation(翻譯)和 Scan(分析)必須使用完全相同的 Build ID

第二題:如何匯出 DeveloperWorkbook PDF 報告?

Fortify 提供了一個專門的命令行報表工具 ReportGenerator,可以直接讀取掃描結果檔(.fpr)並套用 DeveloperWorkbook 範本產生 PDF 報告。

1. 匯出命令(Command-line)

請在 Terminal / Command Prompt 執行:

ReportGenerator -format pdf -f DeveloperWorkbook.pdf -source result.fpr -template DeveloperWorkbook.xml

2. 參數說明

  • -format pdf:指定輸出格式為 PDF(亦支援 rtf)。
  • -f DeveloperWorkbook.pdf:輸出的 PDF 檔案名稱。
  • -source result.fpr:你前面掃描完成所產生的 .fpr 結果檔。
  • -template DeveloperWorkbook.xml:指定使用研發團隊常用的 Developer Workbook 報表範本。

3. 補充技巧 (進階)

如果是系統找不到 DeveloperWorkbook.xml請加上完整的範本路徑,預設位在 Fortify 安裝目錄下:

# Linux / macOS
ReportGenerator -format pdf -f DeveloperWorkbook.pdf -source result.fpr -template /opt/Fortify/Core/config/reports/DeveloperWorkbook.xml

# Windows
ReportGenerator -format pdf -f DeveloperWorkbook.pdf -source result.fpr -template "C:\Program Files\Fortify\Core\config\reports\DeveloperWorkbook.xml"

如果報告顯示的弱點數量被限制(例如預設只印前 5 個):可以將 DeveloperWorkbook.xml 複製一份出來,用文字編輯器開啟,搜尋 limit="5" 並將其修改為 limit="-1"(代表不限數量,印出全部),再將修改後的 XML 作為 -template 帶入即可。


翻譯(Translation)階段需要限制 memory usage?

答案是需要。

雖然 Fortify 官方文件常強調在「分析(Scan)」階段給予大記憶體,但翻譯(Translation)階段如果記憶體不足,同樣會直接發生 OutOfMemoryError 或導致解析中斷(Crash)。

特別是你的案例中有大型 PHP 檔案(帶有巨型 Heredoc 語法),Fortify 在 Translation 階段進行語法解析(Lexing/Parsing)並建構 AST(抽象語法樹)時,就會在記憶體中吃掉大量空間。

1. 為什麼 Translation 階段也需要限制/調大記憶體?

  1. 語法分析(AST 建構): 翻譯階段並非只是「複製檔案」,而是將原始碼編譯成 Fortify 的內部中間語言(NST/AST)。遇到複雜的 PHP 樣板、巨型 JSON/SQL 字串或第三方套件時,記憶體開銷會瞬間衝高。
  2. 預設記憶體通常太小: 若未手動指定,-b 翻譯階段會使用 Fortify 的預設配額(通常僅 1GB~2GB),極易觸發 java.lang.OutOfMemoryError: GC overhead limit exceeded

2. 如何在 Translation 階段設定記憶體?

語法與 Scan 階段完全相同,直接在 sourceanalyzer 命令列加上 -Xmx 參數:

# 1. 先清除舊的 Build ID 暫存
sourceanalyzer -b myproject -clean

# 2. 【Translation 階段】給予足夠的記憶體(例如 16G)
sourceanalyzer -b myproject -Xmx16G ./src

# 3. 【Scan 階段】同樣給予足夠的記憶體
sourceanalyzer -b myproject -Xmx16G -scan -f result.fpr

3. Translation 階段記憶體優化的最佳做法

如果給了 -Xmx16G 在 Translation 階段依然記憶體溢位,請搭配以下優化策略:

主動過濾不需翻譯的目錄(最有效):不要將非業務邏輯的套件帶入 Translation 階段:

sourceanalyzer -b myproject -Xmx16G \ -exclude "/vendor/" \ -exclude "/node_modules/" \ -exclude "/*.min.js" \ ./src

設定單一檔案大小上限(全域設定):fortify-sca.properties 設定檔中加上 limit,防止 Translation 階段去解析幾十 MB 的巨型檔案:

com.fortify.sca.limit.file.size=10240

全域預設記憶體配置:若不想每次命令列都打 -Xmx,可在 fortify-sca.properties 中調整全域預設值,這會同時作用於 Translation 與 Scan 階段

com.fortify.sca.ProjectTranslationMemoryMB=16384
com.fortify.sca.ProjectScanMemoryMB=16384

要匯出符合 OWASP Top 10 安全標準的 PDF 報告,選取的範本(Template)檔案說明如下:

1. 建議選擇的 Template 檔案

Fortify 官方內建了不同年份版本的 OWASP Top 10 報本 XML 檔,位於 Fortify 報表目錄中:

範本檔名 (Template File)適用 OWASP 版本說明 / 適用場景
OWASP Top 10 2021.xmlOWASP Top 10 (2021)【最推薦】 目前最主流的官方標準版本,建議優先選用。
OWASP Top 10 2017.xmlOWASP Top 10 (2017)適用於客戶或公司稽核規範明確指定 2017 年版的專案。
OWASP Top 10.xml通用/預設連結版部分 Fortify 舊版本的預設檔名(會指向該版本的預設 OWASP)。

2. 命令行 (ReportGenerator) 執行指令

預設範本檔案存放在 Fortify 安裝目錄下的 Core/config/reports/ 資料夾中。

Linux / macOS:

ReportGenerator -format pdf \
  -f OWASP_Top10_Report.pdf \
  -source result.fpr \
  -template "/opt/Fortify/Core/config/reports/OWASP Top 10 2021.xml"

Windows:

ReportGenerator -format pdf ^
  -f OWASP_Top10_Report.pdf ^
  -source result.fpr ^
  -template "C:\Program Files\Fortify\Core\config\reports\OWASP Top 10 2021.xml"

(注意:路徑中包含空白字元,必須使用雙引號 "..." 包裹)

3. 在 Audit Workbench (GUI) 中選擇

若使用圖形化介面匯出:

  1. 開啟 .fpr 結果檔。
  2. 點擊選單 Tools > Generate Report
  3. Report Template 下拉選單中選擇 OWASP Top 10 2021 (或 OWASP Top 10)。
  4. Format 設為 PDF,點擊 Save Report 即可。

💡 關鍵技巧:印出「所有」弱點細節 (解除預設 5 筆限制)

Fortify 官方預設的 OWASP 範本為了控制 PDF 頁數,預設每個漏洞分類只會列出前 5 筆弱點細節 (limit="5")

若你的報告需要列出全部弱點:

  1. OWASP Top 10 2021.xml 複製到你的工作目錄,改名為 OWASP_Custom.xml
  2. 用文字編輯器打開它,將裡面的 limit="5" 全部覆蓋替換為 limit="-1"-1 代表不限制數量)。
  3. 執行指令時帶入 -template OWASP_Custom.xml 即可印出完整清單。

command line manual:

sourceanalyzer --help
OpenText SAST (Fortify) CE 25.2.0.0116
Copyright (c) 2003-2025 Open Text

Usage:

  Clean:
     sourceanalyzer.exe -b <build-id> -clean
  Build:
     sourceanalyzer.exe -b <build-id> <sca-build-opts>
  Scan:
     sourceanalyzer.exe -b <build-id> -scan <sca-scan-opts>

Detailed invocation:

  Build:
     sourceanalyzer.exe -b <build-id>
          [ <sca-build-options> ]
          <file-specifier>
     sourceanalyzer.exe -b <build-id>
          [ <sca-build-options> ]
          <compiler> <compiler-options>
     sourceanalyzer.exe -b <build-id>
          [ <sca-build-options> ]
          touchless <build-tool> [ <build-tool-options> ]
     sourceanalyzer.exe -b <build-id>
          [ <sca-build-options> ]
          devenv <solution-file> /REBUILD
     sourceanalyzer.exe -b <build-id>
          [ <sca-build-options> ]
          msbuild /t:rebuild <solution-or-project-file>
     sourceanalyzer.exe -b <build-id>
          [ <sca-build-options> ]
          xcodebuild -project <xcodeproj-file>
     sourceanalyzer.exe -b mybuild
          -source-base-dir <webapp-root> <cfm-file-specifier>
  Scan:
     sourceanalyzer.exe -b <build-id> -scan
          [ -f <output-file> ]
          [ -scan-precision <level> ]
          [ -rules <rules.xml> [ -no-default-rules ] ]
          [ -filter <filter-file> ]
  Clean:
     sourceanalyzer.exe -b <build-id> -clean
  Query:
     sourceanalyzer.exe -b <build-id> { -show-build-warnings | -show-files }
     sourceanalyzer.exe { -version | -show-build-ids }
     sourceanalyzer.exe { -h | -? | -help }



Options


General Options
These options are applicable to all sourceanalyzer.exe invocations.

  @<file>                     Reads command line options from the specified
                              file.  Note that there is no space before the
                              file argument.

  -debug                      Causes the build step to write additional
                              troubleshooting information to the log file.
                              Use if instructed by Fortify Customer Support.
                              Also see "-logfile".

  -logfile <file>             Specifies a destination for the log file.

  -verbose                    Outputs verbose messages to the console.

  -Xmx<num>M                  Specifies the maximum Java heap size.
                              Default is -Xmx1800M.

  -autoheap                   Instructs SCA to set the maximum Java heap size
                              based on available physical memory. Use instead
                              of -Xmx.  Enabled by default.

  -fcontainer                 When run in a Docker container, instructs SCA
                              to detect and use only the memory allocated to
                              the container.

  -version                    Shows the sourceanalyzer.exe version.


Command Options
Note: Only one "command" option is allowed per invocation.


  -h                          Displays this help text.
  -help
  -?

  -clean                      Deletes all intermediate files and build records.
                              When a build ID is also specified with -b, only
                              files and build records related to that build ID
                              are deleted.

  -show-binaries              See the user guide.
  -show-build-tree            See the user guide.

  -show-build-ids             Lists all the Fortify build IDs (analysis models).

  -show-build-warnings        Displays all the actionable warnings that
                              occurred during the translation phase of the build
                              ID specified by "-b".

  -show-files                 Displays all the source files built into the model
                              specified by "-b".

  -show-loc                   Displays lines of code processed for files built
                              into the model specified by "-b".

  -scan                       Causes sourceanalyzer.exe to run an analysis.

  (none)                      If no command option is present, a build step
                              is assumed.


Build Options
"Build" options translate source code into a Fortify analysis model.


  -b <build-id>               Specifies a unique name that identifies the
                              Fortify analysis model to be built. Also see
                              "-scan".

  -build-label <label>        Specifies an optional, arbitrary string value to
                              the Fortify analysis model. Will be included in
                              the output file.

  -build-project <project>    Specifies an optional, arbitrary string value to
                              the Fortify analysis model. Will be included in
                              the output file.

  -build-version <version>    Specifies an optional, arbitrary string value to
                              the Fortify analysis model. Will be included in
                              the output file.

  -encoding <encoding-name>   Specifies the source file encoding.
                              Default value is the platform default.

Compiler Integration Build Options
These options are used when integrating OpenText SAST (Fortify) with a compiler.

  <compiler> <compiler-opts>  Specifies the compiler command line. The file
                              being compiled will be added to the analysis
                              model, and the compiler will be invoked.

  touchless <build-tool>      Specifies a build tool command. The build tool
    [ <build-tool-options> ]  will be invoked, and any file being compiled
                              will be added to the analysis model.

  -nc                         When specified, the compiler is not invoked.


File Specification Build Options
These options are used to pass source files directly to OpenText SAST (Fortify).

  <file-specifier>            Expression denoting a file or a group of files,
                              optionally matching a pattern:
                              file1.java - a file
                              file*.java - files matching expression
                              "path/**/*.java" - recursive expression matches.
                              Note: Always escape ** expressions in quotes.

  -exclude <file-specifier>   Excludes any files matched by <file-specifier>
                              from the set of files to translate


Java-specific Build Options
These options should be used in conjunction with file specification options.

  -classpath <classpath>      Uses the specified classpath value for Java
  -cp <classpath>             builds.

  -extdirs                    Accepts a colon or semicolon separated list
                              of directories.  Any jar files found in
                              these directories are included on the
                              classpath. Equivalent to the -extdirs option
                              to javac.

  -sourcepath                 Specifies the location of source files which will
                              not be included in the scan but will be used for
                              name resolution. Equivalent to the -sourcepath
                              option to javac.
                              The sourcepath is like classpath, except it uses
                              source files rather than class files for
                              resolution.

  -source <value>             Indicates which version of the Java language the Java
  -jdk <value>                code adheres to.  Valid values are 1.8, 8, 11, 17, 21.
                              Default is "11".

  -java-build-dir <dir>       Used to specify one or more directories to which
                              Java sources are being compiled. May also be
                              specified at scan time.

Other Language-Specific Build Options

  -source-base-dir <root>     The base directory for a ColdFusion application.

  -python-path                Add an import directory for a Python application.

  -apex                       Set ".cls" file extension to Apex language.
                              (detected based on file content by default). Equivalent to
                              -Dcom.fortify.sca.fileextensions.cls=APEX

  -apex-sobject-path          Add file to load SObject types in Apex application.

Scan Options

  -b <build-id>               Specifies the build ID.  The build ID is used
                              to track which files are compiled and linked
                              as part of a build, to later scan those files.
                              This option may be specified more than once to
                              include multiple build IDs in the same scan.

  -bin <binary>               All source files compiled and linked into the
                              specified binary are scanned.  Multiple binaries
                              may be specified.

  -disable-default-rule-type  See the user guide.

  -f <file>                   The file to which analysis results are written.
                              Default is stdout.

  -filter <file>              Specifies a filter file.  For more information,
                              see the user guide.

  -scan-policy <policy>       Specifies a scan policy for vulnerability prioritization.
                              Valid values are classic, security, devops. Default is security.
                              For more information, see the user guide.

  -java-build-dir <dir>       Used to specify one or more directories to which
                              Java sources have been compiled.  May also be
                              specified at build time.

  -no-default-issue-rules     See the user guide.
  -no-default-sink-rules      See the user guide.
  -no-default-source-rules    See the user guide.

  -no-default-rules           Indicates that OpenText SAST (Fortify) should not use its
                              default rules.  Must be used in conjunction with
                              "-rules"

  -rules <specifier>          Specifies custom rules file or directory.  If a
                              directory is specified, all files ending in ".bin"
                              or ".xml" are included.
                              This option may be used multiple times.

  -quick                      Runs a quick scan. Quick scans complete faster at
                              the cost of reduced accuracy.

  -scan-precision <level>     Configures the depth, precision and speed of the scan
  -p <level>                  with configuration properties specific for the level.
                              The valid values are 1, 2, 3, and 4.

  -quiet                      Disables the command line progress bar.

  -scan                       Causes OpenText SAST (Fortify) to perform analysis against a
                              model.  The model must be specified with "-b".


Build Sessions

  -export-build-session <file.mbs>

                              Store the translated model specified by -b to the
                              specified file.

  -import-build-session <file.mbs>

                              Load the specified file into a build model.  If
                              the build ID of the model already exists in the
                              model registry, the import fails with the message
                              that a build already exists with that ID.


License Directives

  -store-license-pool-credentials "<lim_url>|<lim_pool_name>|<lim_pool_pwd>|<proxy_url>|<proxy_user>|<proxy_pwd>"

                              Stores your LIM license pool credentials to
                              allow OpenText SAST (Fortify) to use the
                              LIM for licensing. Proxy information is optional.

  -clear-license-pool-credentials

                              Removes the LIM license pool credentials from
                              the fortify-sca.properties file.

  -request-detached-lease <duration>

                              Requests a detached lease from the LIM license
                              pool for exclusive use on this system for the
                              specified duration (in minutes).

  -release-detached-lease

                              Releases a detached lease back to the license
                              pool.


EXAMPLES


Build examples:
  Generic (Java, configuration, PHP, JavaScript, ASP/VBScript, VB6):
     sourceanalyzer.exe -b mybuild .
     sourceanalyzer.exe -b mybuild file1.java file2.java
     sourceanalyzer.exe -b mybuild *.bas *.cls *.frm
     sourceanalyzer.exe -b mybuild "site/**/*.php"

  ColdFusion translation:
     sourceanalyzer.exe -b mybuild -source-base-dir /www/app "/www/app/**/*.cfm"

  SQL translation:
     sourceanalyzer.exe -b mybuild -Dcom.fortify.sca.fileextensions.sql=PLSQL *.sql
     sourceanalyzer.exe -b mybuild -Dcom.fortify.sca.fileextensions.sql=TSQL *.sql

  C/C++ builds:
     sourceanalyzer.exe -b mybuild gcc -c test.c
     sourceanalyzer.exe -b mybuild CL.EXE /o HelloWorld HelloWorld.c
     sourceanalyzer.exe -b mybuild make
     sourceanalyzer.exe -b mybuild devenv myproject.msproj /REBUILD

  Objective-C/C++ builds:
     sourceanalyzer.exe -b mybuild clang -ObjC HelloWorld.m
     sourceanalyzer.exe -b mybuild xcodebuild -project myproject.xcodeproj

  .NET builds:
     sourceanalyzer.exe -b mybuild devenv myproj.sln /REBUILD
     sourceanalyzer.exe -b mybuild msbuild /t:rebuild myproj.csproj

  Java specific builds:
     sourceanalyzer.exe -b mybuild -cp lib/dependency.jar "src/**/*.java"
     sourceanalyzer.exe -b mybuild -cp mytaglibs.jar webapp/*.jsp
     sourceanalyzer.exe -b mybuild touchless ant

  J2EE specific builds:
     sourceanalyzer.exe -b mybuild -cp "app/WEB-INF/lib/*.jar" app/*.jsp

Scan step:
     sourceanalyzer.exe -b mybuild -scan -f results.fpr


See OpenText(TM) Static Application Security Testing (Fortify) User Guide for a complete explanation of each option.


You can open a support case for Fortify products online using
our customer support system. This streamlined procedure is designed to
provide easier access and improved customer satisfaction.

Access your account at https://softwaresupport.softwaregrp.com/.

這代表即使給了 32G 記憶體,ANTLR 在解析 PHP 語法時仍陷入了死迴圈或極度消耗記憶體的狀態(問題依然卡在 PHPParser.hereDocPart / PHPLexerBase)。

通常這有兩個主因:

  1. Windows 通配符問題-exclude "/vendor/" 在 CMD/PowerShell 根本沒有生效,Fortify 依然把 vendor 進去了。
  2. 存在「超大檔」或「極長 Heredoc 檔」:例如大型 SQL dump、Base64 圖片檔、自動生成的測試資料或超大樣板檔,導致 ANTLR Parser 記憶體暴增。

請依序透過以下方法徹底解決:

1. 修正 Windows 的 -exclude 語法(最常踩坑)

在 Windows 命令列,-exclude必須使用雙引號,且建議使用 ** (Ant 語法) 與 Windows 反斜線,否則過濾會無效:

DOS

sourceanalyzer -b portal_project -clean

sourceanalyzer -b portal_project -Xmx32G -exclude "**/vendor/**" -exclude "**/node_modules/**" -exclude "**/*.min.js" backend/

2. 開啟弱點檔大小限制 (Limit File Size)

這是解決 hereDoc 爆記憶體最有效的武器。直接限制 Fortify 跳過單檔超過指定大小的檔案(例如 1MB 或 2MB):

做法 A:命令列加上 -D 參數

DOS

sourceanalyzer -b portal_project -Xmx32G -Dcom.fortify.sca.limit.file.size=2048 -exclude "**/vendor/**" backend/

( 2048 代表超過 2MB 的原始碼檔案就跳過不安裝/解析,可有效避免吃到包含巨大字串或 Heredoc 的 PHP 檔案)

做法 B:修改 fortify-sca.properties

C:\Users\<你的帳號>\.fortify\fortify-sca.properties 或 Fortify 安裝目錄下的 Core\config\fortify-sca.properties 加入:

Properties

com.fortify.sca.limit.file.size=2048

3. 找出到底是哪個「元凶檔案」卡住,單獨排除它

如果是業務邏輯資料夾內有一個幾十 MB 的 PHP 檔案(例如包含超大字串陣列或字典):

請加上 -debug-verbose 參數重新執行一次,並觀察 log 印到哪一個 .php 檔案時卡死:

DOS

sourceanalyzer -b portal_project -Xmx32G -verbose backend/ > scan_log.txt

打開 scan_log.txt 翻到最底端,查看崩潰前最後進行解析(Parsing/Lexing)的是哪一個 .php 檔案,接著直接將該檔案加入排除:

DOS

sourceanalyzer -b portal_project -Xmx32G -exclude "**/ProblematicFile.php" backend/

4. (終極方案)調整 ANTLR / PHP 語法分析設定

如果特定 PHP 檔案無法排除,但包含極長的 Heredoc,可以在 fortify-sca.properties 加入以下參數,限制語法樹深度或停用部分 ANTLR 耗效能的檢查:

# 限制 Fortify 對單一檔案最大解析時間(單位:秒,預設無限制,可設為 300 秒)
com.fortify.sca.PhaseTimeout=300

# 關閉部分過度深度的 AST 解析
com.fortify.sca.DisablePHP2MethodCallDataflow=true

建議嘗試步驟:

  1. 先執行 sourceanalyzer -b portal_project -clean 清除快取。
  2. 加上限制檔案大小參數 -Dcom.fortify.sca.limit.file.size=2048 並修正過濾語法 -exclude "**/vendor/**" 重新執行。

從你提供的完整 log 可以精準定位出問題的根源所在:

Log 在處理到 SendForgotPasswordTotpApi.php(或緊隨其後的下一個 PHP 檔)時,Fortify 的 PHP 語法解析器 (PHPFrontEnd) 因為遇到極長或結構極度複雜的 Heredoc / String,導致 ANTLR 語法分析器陷入計算迴圈並爆記憶體崩潰,進而拋出 NullPointerException

請採用以下 4 步驟解決方案 來繞過這個解析器的死區:

步驟 1:強制限制單檔大小 (File Size Limit)

這是最快且最有效的方法。加載此參數能直接讓 Fortify 跳過過大或包含巨大字串 (Heredoc/Blob) 的單一原始碼檔案,避免 ANTLR 解析器卡死。

在 command 加入 -Dcom.fortify.sca.limit.file.size=2048(單位為 KB,即 2MB):

DOS

sourceanalyzer -b portal_backend -clean

sourceanalyzer -b portal_backend -Xmx32G -Dcom.fortify.sca.limit.file.size=2048 backend/

步驟 2:明確排除 TestTools 或測試/資料庫備份檔案

從 Log 中可以看到你的 backend/ 下包含了 TestToolsdb/migrations。通常測試工具與 Migration 檔中會含有大量假資料、巨型 SQL 字串或 Heredoc 模板。

請使用 Windows 專用 Ant 通配符 將它們排除:

DOS

sourceanalyzer -b portal_backend -clean

sourceanalyzer -b portal_backend -Xmx32G -Dcom.fortify.sca.limit.file.size=2048 -exclude "**/TestTools/**" -exclude "**/db/**" -exclude "**/vendor/**" backend/

步驟 3:定位「致命檔案」並直接單獨排除

如果前兩步執行後依然在 SendForgotPasswordTotpApi.php 附近崩潰,代表問題出在業務邏輯程式碼本身的某個特定檔案。

  1. 打開 SendForgotPasswordTotpApi.php 以及與它在同一目錄下的前後檔案。
  2. 檢查程式碼中是否有使用 <<<EOD/SendForgotPasswordTotpApi.php” “/TestTools/” “/db/” “/vendor/” # ### (2048 (5分鐘),防止 Heredoc — -Dcom.fortify.sca.limit.file.size=”2048″ -Xmx32G -b -clean -exclude -f -scan / 2MB 3. 300 4:寫入 ANTLR Fortify HTML KB) Nowdoc PHP Phase Timeout,讓 -exclude <<<HTML C:\Users\max\.fortify\fortify-sca.properties cmd “`properties fortify-sca.properties backend/ com.fortify.sca.PhaseTimeout=”300″ com.fortify.sca.limit.file.size=”2048″ portal_backend portal_backend_result.fpr sourceanalyzer 之類的 在檔案末端寫入以下設定: 完成上述設定後,執行以下完整的標準清洗與翻譯流程: 將它單獨排除: 建議的標準執行指令 或 找到該檔案後,直接使用 檔案也發生 步驟 無限迴圈 秒 若要避免以後其他 解析單一檔案逾時自動跳過,而不是直接崩潰: 設定全域超時(終極防護) 設定單一階段解析超時為 語法,且裡面放了極長的 語法卡死,直接開啟 請開啟以下檔案(若沒有請自行建立): 資料或密碼學金鑰/雜湊值。 郵件模板、JSON 限制單一檔案解析上限>

這個檔案 (SendForgotPasswordTotpApi.php) 正是導致 Fortify ANTLR 語法分析器崩潰爆記憶體的元凶

為什麼是這個檔案?

  1. 使用了巨大的 Heredoc ($htmlBody = <<<EOD ### #### $htmlBody="str_replace('{$totpCode}'," $htmlTemplate="file_get_contents($templatePath);" $htmlTemplate); $templatePath="__DIR__" $totpCode, '/../../templates/emails/forgot_password_totp.html'; (Inline) (圖案樣式)、HTML **ANTLR **修改後的 --- . ... / // 2. 25.2 <<<EOD A:重構此 Base64 CSS、內嵌 Data EOD; EOD;): Fortify GC HTML Heredoc PHP SVG URI $htmlBody$textBody.blade.php.htmlHeredocPHPLexerBasePHPParser.hereDocPart\、雙引號、SVG php java.lang.OutOfMemoryError: exceeded。 limit overhead 使用的 使用簡單的字串替換填入動態變數 在處理包含複雜字元(如反斜線 字串。 將 將原本巨大的 抽離至獨立的 方案 時,內部的詞法狀態轉換會陷入計算遞迴,進而導致 替換為讀取外部模板檔案: 標籤的巨型 模板抽離,這同時也能讓你的程式碼結構更乾淨。 模板檔案中,改用檔案讀取方式載入: 檔案(最推薦,一勞永逸) 的 的內聯 程式碼: 與 解析器缺陷: 解決方案:重構此檔案(推薦)或針對性排除 語法)的長 這個檔案裡包含了一整段包含 這有兩種解決方式,最根本的方法是重構程式碼,將> 優勢:抽離後 Fortify 解析這個 .php 時就不會觸發 Heredoc 的 ANTLR 解析 Bug,掃描能順利通過,且不會遺漏該 API 的安全弱點分析!

方案 B:單獨排除此檔案(最快)

如果你目前不想改動原始碼,可以在執行命令時,直接將該檔案單獨排除掉:

sourceanalyzer -b portal_backend -clean

sourceanalyzer -b portal_backend -Xmx16G -Dcom.fortify.sca.limit.file.size=2048 -exclude "**/SendForgotPasswordTotpApi.php" -exclude "**/TestTools/**" -exclude "**/db/**" -exclude "**/vendor/**" backend/

方案 C:將檔案大小限制調低

因為這個 .php 檔案因為包含巨型 HTML,檔案大小可能較大。你可以嘗試將檔案限制從 2048 (2MB) 調小到 100 (100KB):

sourceanalyzer -b portal_backend -clean

sourceanalyzer -b portal_backend -Xmx16G -Dcom.fortify.sca.limit.file.size=100 -exclude "**/vendor/**" backend/

(這樣 Fortify 會自動跳過此類包含巨型模板的過大 PHP 檔)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *