Skip to main content

HYCOM security analysis

Goal

Lear how to use Codee for Static Application Security Testing (SAST) and generate a SAST report for HYCOM

Getting ready

For this demonstration, we will use HYCOM, an ocean modeling system consisting of dozens of files. Start by cloning the repository:

git clone https://github.com/codee-com/codee-demos.git

Walkthrough

1. Generate the compile_commands.json

Firstly, navigate to the source code directory:

cd codee-demos/Fortran/HYCOM/src/

The project comes with a Makefile, so we can leverage the tool bear (version 3 or later) to generate the compile_commands.json file required by Codee:

bear -- make

It is as simple as prepending bear -- to the make invocation. This command will produce a compile_commands.json file with all the compiler invocations needed to build the source files.

2. Run Codee SAST report

To obtain Codee SAST results for the CWE standard execute the following command; use --compile-commands (or -p as its short version) to point to the compilation database:

Codee Sast command
codee diagnose --sast --compile-commands compile_commands.json
Codee output
Note: the compilation database entries will be analyzed in the order necessary to meet module dependencies between Fortran source files.
Configuration file 'compile_commands.json' successfully parsed.
Date: 2025-08-20 Codee version: 2025.3.4 License type: Professional
Performing Fortran module dependency analysis... Done

[ 1/50] mod_dimensions.F90 ... Done
[ 2/50] mod_xc.F90 ... Done

<...>

mod_dimensions.F90:215:7 [PWR008] [CWE374] (level: L2): Declare the intent for each procedure argument
mod_pipe.F90:1:7 [PWR007] [CWE628] (level: L2): Disable the implicit declaration of variables and procedures
mod_pipe.F90 [PWR075] [CWE474] [CWE1103] (level: L1): Avoid using compiler-specific Fortran extensions
mod_pipe.F90 [PWR063] [CWE477] [CWE1075] [CWE1119] (level: L1): Avoid using legacy Fortran constructs
mod_stokes.F90:280:9 [PWR068] [CWE628] (level: L2): Encapsulate procedures within modules to avoid the risks of calling implicit interfaces
mod_pipe.F90:438:7 [PWR070] [CWE130] (level: L3): Declare array dummy arguments as assumed-shape arrays
mod_dimensions.F90:128:7 [PWR071] [CWE1102] [CWE1339] (level: L3): Prefer real(kind=kind_value) for declaring consistent floating types
forfun.F90:222:14 [PWR073] [CWE1108] [CWE1083] (level: L3): Transform common block into a module for better data encapsulation
mod_dimensions.F90:138:7 [PWR001] [CWE1108] (level: L3): Pass global variables as function arguments

<...>
50 files, 251 functions, 2058 loops, 44679 LOCs successfully analyzed (1547 checkers) and 0 non-analyzed files in 1 m 4 s

3. Re-run the Codee SAST report with --verbose

Running the Codee SAST report with the --verbose flag enabled provides additional details about the reported checkers. The output includes autofixes if available, as well as links to the Open Catalog and the official CWE documentation. We can filter Codee's output with the --check-id flag. For example, let's pick PWR008 and PWR071 for this case study.

Codee command
codee diagnose --verbose --sast --compile-commands compile_commands.json --check-id pwr008,pwr071
Codee output
Note: the compilation database entries will be analyzed in the order necessary to meet module dependencies between Fortran source files.
Configuration file 'compile_commands.json' successfully parsed.
Date: 2025-08-20 Codee version: 2025.3.4 License type: Professional
Performing Fortran module dependency analysis... Done

[ 1/50] mod_dimensions.F90 ... Done
[ 2/50] mod_xc.F90 ... Done

<...>

mod_floats.F90:2607:7 [PWR008] [CWE374] (level: L2): Declare the intent for each procedure argument
Suggestion: Add the missing INTENT for arguments of the procedure 'f_stat':
intent in: 'ser' and 'ls'
intent inout: 'amean', 'var' and 'std'
Documentation:
https://open-catalog.codee.com/Checks/PWR008
https://cwe.mitre.org/data/definitions/374.html
AutoFix:
codee rewrite --check-id pwr008 --in-place mod_floats.F90:f_stat --compile-commands compile_commands.json

<...>

thermf.F90:1148:7 [PWR071] [CWE1102] [CWE1339] (level: L3): Prefer real(kind=kind_value) for declaring consistent floating types
Suggestion: Declare variables 'au5_00', 'au5_10', 'au5_20', 'au5_01', 'au5_11', 'au5_21', 'au5_02', 'au5_12' and 'au5_22' with real(kind=kind_value)
Documentation:
https://open-catalog.codee.com/Checks/PWR071
https://cwe.mitre.org/data/definitions/1102.html
https://cwe.mitre.org/data/definitions/1339.html

<...>

50 files, 251 functions, 2058 loops, 44679 LOCs successfully analyzed (1547 checkers) and 0 non-analyzed files in 1 m 4 s

4. Run the screening report focused on security checkers

Finally, it is also possible to run the screening report focusing only on security checkers. This way, the output will be ordered by priority.

Codee screening command
codee screening --security cwe -p compile_commands.json
Codee output
codee: warning: compile_commands.json was autodetected, using '/home/tamara/Desktop/codee-demos/Fortran/HYCOM/src/compile_commands.json'
Date: 2025-08-20 Codee version: 2025.3.4 License type: Professional
Performing Fortran module dependency analysis... Done

[ 1/50] mod_dimensions.F90 ... Done
[ 2/50] mod_xc.F90 ... Done
<...>

SCREENING REPORT

------Number of files------
Total | C C++ Fortran Other
----- | - --- ------- -----
50 | 1 0 49 0

RANKING OF QUALITY CHECKERS

Checker Category Priority AutoFixes # Title
------- ------------------------------------- -------- --------- ---- ---------------------------------------------------------------------------------------
PWR075 modern, portability, security P12 (L1) 20 Avoid using compiler-specific Fortran extensions
PWR063 correctness, modern, security P12 (L1) 19 Avoid using legacy Fortran constructs
PWR008 correctness, modern, security P9 (L2) 12 196 Declare the intent for each procedure argument
PWR068 correctness, modern, security P9 (L2) 192 Encapsulate procedures within modules to avoid the risks of calling implicit interfaces
PWR007 correctness, modern, security P9 (L2) 19 22 Disable the implicit declaration of variables and procedures
PWR071 modern, portability, security P3 (L3) 831 Prefer real(kind=kind_value) for declaring consistent floating types
PWR073 correctness, modern, security P3 (L3) 5 Transform common block into a module for better data encapsulation
PWR070 correctness, modern, security, memory P2 (L3) 74 Declare array dummy arguments as assumed-shape arrays
PWR001 correctness, modern, security P1 (L3) 188 Pass global variables as function arguments
------- ------------------------------------- -------- --------- ---- ---------------------------------------------------------------------------------------
Total 31 1547

<...>

50 files, 251 functions, 2058 loops, 44679 LOCs successfully analyzed (1547 checkers) and 0 non-analyzed files in 1 m 16 s