diff --git a/.github/custom-queries/matlab/ Improper Input Handling.ql b/.github/custom-queries/matlab/ Improper Input Handling.ql new file mode 100644 index 00000000..f5168c88 --- /dev/null +++ b/.github/custom-queries/matlab/ Improper Input Handling.ql @@ -0,0 +1,23 @@ +/** + * @name Improper input handling in mathematical operations + * @description Detects mathematical operations on untrusted inputs without proper validation or sanitization, leading to potential data integrity issues. + * @kind problem + * @problem.severity high + * @tags security, input-validation + */ +import javascript + +class ImproperInputInMathOp extends Expr { + ImproperInputInMathOp() { + this.getFile().getName().endsWith(".m") and + exists(Expr mathOp | + mathOp.getSource() = this and + mathOp.toString().matches("(\\+|\\-|\\*|\\/|\\^|sqrt|log)%") and + not exists(Expr inputValidation | + inputValidation.getSource() = mathOp and inputValidation.toString().matches("(validate|sanitize)%")) + ) + } +} + +from ImproperInputInMathOp mathOp +select mathOp, "Improper input handling in mathematical operations detected. Ensure inputs are validated or sanitized." diff --git a/.github/custom-queries/matlab/ Improper Use of cd.ql b/.github/custom-queries/matlab/ Improper Use of cd.ql new file mode 100644 index 00000000..db82e7c9 --- /dev/null +++ b/.github/custom-queries/matlab/ Improper Use of cd.ql @@ -0,0 +1,23 @@ +/** + * @name Improper use of cd command + * @description Detects usage of `cd` to change directories without validating whether the directory exists, potentially leading to errors. + * @kind problem + * @problem.severity warning + * @tags security, directory-management + */ +import javascript + +class ImproperCdUsage extends Expr { + ImproperCdUsage() { + this.getFile().getName().endsWith(".m") and + exists(Expr cdCall | + cdCall.getSource() = this and + cdCall.toString().matches("cd%") and + not exists(Expr check | + check.getSource() = cdCall and check.toString().matches("(exist|isdir)%")) + ) + } +} + +from ImproperCdUsage cdCall +select cdCall, "Improper use of cd command without validating the directory path." diff --git a/.github/custom-queries/matlab/ Unsafe Use of mkdir.ql b/.github/custom-queries/matlab/ Unsafe Use of mkdir.ql new file mode 100644 index 00000000..0ede7d0c --- /dev/null +++ b/.github/custom-queries/matlab/ Unsafe Use of mkdir.ql @@ -0,0 +1,23 @@ +/** + * @name Unsafe mkdir usage + * @description Detects the use of `mkdir` without checking for the directory's existence or permissions. + * @kind problem + * @problem.severity warning + * @tags security, resource-management + */ +import javascript + +class UnsafeMkdir extends Expr { + UnsafeMkdir() { + this.getFile().getName().endsWith(".m") and + exists(Expr mkdirCall | + mkdirCall.getSource() = this and + mkdirCall.toString().matches("mkdir%") and + not exists(Expr check | + check.getSource() = mkdirCall and check.toString().matches("(exist|isdir)%")) + ) + } +} + +from UnsafeMkdir mkdirCall +select mkdirCall, "Unsafe use of mkdir without checking for directory existence or permissions." diff --git a/.github/custom-queries/matlab/ Use of Deprecated Functions.ql b/.github/custom-queries/matlab/ Use of Deprecated Functions.ql new file mode 100644 index 00000000..3a636ebd --- /dev/null +++ b/.github/custom-queries/matlab/ Use of Deprecated Functions.ql @@ -0,0 +1,21 @@ +/** + * @name Deprecated function usage + * @description Detects the use of deprecated functions in MATLAB, which might introduce vulnerabilities or break in future releases. + * @kind problem + * @problem.severity warning + * @tags security, deprecated + */ +import javascript + +class DeprecatedFunctionUsage extends Expr { + DeprecatedFunctionUsage() { + this.getFile().getName().endsWith(".m") and + exists(Expr deprecatedCall | + deprecatedCall.getSource() = this and + deprecatedCall.toString().matches("(str2num|input|addpath)%") + ) + } +} + +from DeprecatedFunctionUsage deprecatedCall +select deprecatedCall, "Deprecated function usage detected. Consider updating to supported alternatives." diff --git a/.github/custom-queries/matlab/Hardcoded Credentials.ql b/.github/custom-queries/matlab/Hardcoded Credentials.ql new file mode 100644 index 00000000..be996d46 --- /dev/null +++ b/.github/custom-queries/matlab/Hardcoded Credentials.ql @@ -0,0 +1,22 @@ +/** + * @name Hardcoded credentials + * @description Detects potential hardcoded credentials, such as passwords or API keys, in MATLAB scripts. + * @kind problem + * @problem.severity critical + * @tags security, hardcoded-credentials + */ + +import javascript + +class MatlabHardcodedCredentials extends Expr { + MatlabHardcodedCredentials() { + this.getFile().getName().endsWith(".m") and + exists(Expr hardcoded | + hardcoded.getSource() = this and + hardcoded.toString().matches("(password|passwd|apiKey|secret|token)\\s*=\\s*['\"]\\w+['\"]") + ) + } +} + +from MatlabHardcodedCredentials hardcoded +select hardcoded, "Potential hardcoded credentials detected in MATLAB code." diff --git a/.github/custom-queries/matlab/Hardcoded IP Address.ql b/.github/custom-queries/matlab/Hardcoded IP Address.ql new file mode 100644 index 00000000..c893d68b --- /dev/null +++ b/.github/custom-queries/matlab/Hardcoded IP Address.ql @@ -0,0 +1,21 @@ +/** + * @name Hardcoded IP address + * @description Detects hardcoded IP addresses in the MATLAB code, which could indicate potential misconfigurations or security vulnerabilities. + * @kind problem + * @problem.severity medium + * @tags security, misconfiguration + */ +import javascript + +class HardcodedIP extends Expr { + HardcodedIP() { + this.getFile().getName().endsWith(".m") and + exists(Expr ipAddress | + ipAddress.getSource() = this and + ipAddress.toString().matches("(\\d{1,3}\\.){3}\\d{1,3}") + ) + } +} + +from HardcodedIP ipAddress +select ipAddress, "Hardcoded IP address detected, consider using configuration files instead." diff --git a/.github/custom-queries/matlab/Improper Use of pause Function.ql b/.github/custom-queries/matlab/Improper Use of pause Function.ql new file mode 100644 index 00000000..3254ebdc --- /dev/null +++ b/.github/custom-queries/matlab/Improper Use of pause Function.ql @@ -0,0 +1,23 @@ +/** + * @name Improper use of pause function + * @description Detects improper usage of the `pause` function, which can lead to inefficient code execution or resource misuse. + * @kind problem + * @problem.severity medium + * @tags security, resource-management + */ +import javascript + +class ImproperPauseUsage extends Expr { + ImproperPauseUsage() { + this.getFile().getName().endsWith(".m") and + exists(Expr pauseCall | + pauseCall.getSource() = this and + pauseCall.toString().matches("pause%") and + not exists(Expr timingCheck | + timingCheck.getSource() = pauseCall and timingCheck.toString().matches("(check|validate)%")) + ) + } +} + +from ImproperPauseUsage pauseCall +select pauseCall, "Improper use of the pause function detected, which could lead to resource misuse or inefficient code execution." diff --git a/.github/custom-queries/matlab/Improper Use of rmdir.ql b/.github/custom-queries/matlab/Improper Use of rmdir.ql new file mode 100644 index 00000000..3a96e0b1 --- /dev/null +++ b/.github/custom-queries/matlab/Improper Use of rmdir.ql @@ -0,0 +1,23 @@ +/** + * @name Improper rmdir usage + * @description Detects `rmdir` calls without error handling or validation. + * @kind problem + * @problem.severity high + * @tags security, resource-management + */ +import javascript + +class ImproperRmdir extends Expr { + ImproperRmdir() { + this.getFile().getName().endsWith(".m") and + exists(Expr rmdirCall | + rmdirCall.getSource() = this and + rmdirCall.toString().matches("rmdir%") and + not exists(Expr errorCheck | + errorCheck.getSource() = rmdirCall and errorCheck.toString().matches("(exist|isdir)%")) + ) + } +} + +from ImproperRmdir rmdirCall +select rmdirCall, "Improper use of rmdir without error handling or path validation." diff --git a/.github/custom-queries/matlab/Improper fclose() After fopen().ql b/.github/custom-queries/matlab/Improper fclose() After fopen().ql new file mode 100644 index 00000000..b6746d3a --- /dev/null +++ b/.github/custom-queries/matlab/Improper fclose() After fopen().ql @@ -0,0 +1,15 @@ +/** + * @name Missing fclose after fopen + * @description Detects cases where a file is opened but not closed, leading to resource leaks. + * @kind problem + * @problem.severity warning + * @tags security, resource-leak + */ +import javascript + +class MatlabMissingFclose extends Expr { + MatlabMissingFclose() { + this.getFile().getName().endsWith(".m") and + exists(Expr fopenCall | + fopenCall.getSource() = this and + fopenCall.toString(). diff --git a/.github/custom-queries/matlab/Insecure File Permission.ql b/.github/custom-queries/matlab/Insecure File Permission.ql new file mode 100644 index 00000000..1de6c701 --- /dev/null +++ b/.github/custom-queries/matlab/Insecure File Permission.ql @@ -0,0 +1,22 @@ +/** + * @name Insecure file permissions + * @description Detects insecure file permission changes through `chmod` or `chown` commands. + * @kind problem + * @problem.severity high + * @tags security, file-permissions + */ + +import javascript + +class MatlabInsecureFilePermissions extends Expr { + MatlabInsecureFilePermissions() { + this.getFile().getName().endsWith(".m") and + exists(Expr permCall | + permCall.getSource() = this and + permCall.toString().matches("(chmod|chown)%") + ) + } +} + +from MatlabInsecureFilePermissions permCall +select permCall, "Insecure file permission changes detected, review chmod/chown usage." \ No newline at end of file diff --git a/.github/custom-queries/matlab/Insecure Random Number Generation.ql b/.github/custom-queries/matlab/Insecure Random Number Generation.ql new file mode 100644 index 00000000..771ed308 --- /dev/null +++ b/.github/custom-queries/matlab/Insecure Random Number Generation.ql @@ -0,0 +1,22 @@ +/** + * @name Insecure random number generation + * @description Detects usage of non-cryptographically secure random number generators like `rand` and `randi`. + * @kind problem + * @problem.severity warning + * @tags security, crypto + */ + +import javascript + +class MatlabInsecureRandUsage extends Expr { + MatlabInsecureRandUsage() { + this.getFile().getName().endsWith(".m") and + exists(Expr randCall | + randCall.getSource() = this and + randCall.toString().matches("rand%") + ) + } +} + +from MatlabInsecureRandUsage randCall +select randCall, "Insecure random number generator used (rand or randi), consider using a secure alternative." diff --git a/.github/custom-queries/matlab/Insecure Usage of save Function.ql b/.github/custom-queries/matlab/Insecure Usage of save Function.ql new file mode 100644 index 00000000..956f0909 --- /dev/null +++ b/.github/custom-queries/matlab/Insecure Usage of save Function.ql @@ -0,0 +1,22 @@ +/** + * @name Insecure save function usage + * @description Detects insecure usage of the `save` function without specifying version or compression, leading to data risks. + * @kind problem + * @problem.severity warning + * @tags security, data-integrity + */ +import javascript + +class InsecureSaveFunction extends Expr { + InsecureSaveFunction() { + this.getFile().getName().endsWith(".m") and + exists(Expr saveCall | + saveCall.getSource() = this and + saveCall.toString().matches("save%") and + not saveCall.toString().matches("-v7\\.3%") + ) + } +} + +from InsecureSaveFunction saveCall +select saveCall, "Insecure save function usage detected, consider using '-v7.3' for better data integrity." diff --git a/.github/custom-queries/matlab/Insecure Use of eval Function.ql b/.github/custom-queries/matlab/Insecure Use of eval Function.ql new file mode 100644 index 00000000..ff7a4b07 --- /dev/null +++ b/.github/custom-queries/matlab/Insecure Use of eval Function.ql @@ -0,0 +1,22 @@ +/** + * @name Insecure use of eval + * @description Detects insecure usage of the `eval` function, which can lead to code injection vulnerabilities. + * @kind problem + * @problem.severity critical + * @tags security, code-injection + */ + +import javascript + +class MatlabInsecureEvalUsage extends Expr { + MatlabInsecureEvalUsage() { + this.getFile().getName().endsWith(".m") and + exists(Expr evalCall | + evalCall.getSource() = this and + evalCall.toString().matches("eval%") + ) + } +} + +from MatlabInsecureEvalUsage evalCall +select evalCall, "Insecure use of eval function, consider alternatives or validate input." diff --git a/.github/custom-queries/matlab/Insecure Use of urlread or webread Without TLS.ql b/.github/custom-queries/matlab/Insecure Use of urlread or webread Without TLS.ql new file mode 100644 index 00000000..584e1cbd --- /dev/null +++ b/.github/custom-queries/matlab/Insecure Use of urlread or webread Without TLS.ql @@ -0,0 +1,22 @@ +/** + * @name Insecure URL access without TLS + * @description Detects `urlread` or `webread` function usage for URLs that don't enforce HTTPS, which can lead to insecure communication. + * @kind problem + * @problem.severity high + * @tags security, communication + */ +import javascript + +class InsecureURLAccess extends Expr { + InsecureURLAccess() { + this.getFile().getName().endsWith(".m") and + exists(Expr urlReadCall | + urlReadCall.getSource() = this and + urlReadCall.toString().matches("(urlread|webread)%") and + not urlReadCall.toString().matches("https%") + ) + } +} + +from InsecureURLAccess urlReadCall +select urlReadCall, "Insecure URL access detected, consider enforcing HTTPS." diff --git a/.github/custom-queries/matlab/Insecure load Function.ql b/.github/custom-queries/matlab/Insecure load Function.ql new file mode 100644 index 00000000..cd0a2511 --- /dev/null +++ b/.github/custom-queries/matlab/Insecure load Function.ql @@ -0,0 +1,22 @@ +/** + * @name Insecure use of load function + * @description Detects use of the `load` function without specifying the file format, which can lead to security risks. + * @kind problem + * @problem.severity medium + * @tags security, data-integrity + */ +import javascript + +class InsecureLoadUsage extends Expr { + InsecureLoadUsage() { + this.getFile().getName().endsWith(".m") and + exists(Expr loadCall | + loadCall.getSource() = this and + loadCall.toString().matches("load%") and + not loadCall.toString().matches("-ascii|-mat") + ) + } +} + +from InsecureLoadUsage loadCall +select loadCall, "Insecure use of the load function detected. Specify the file format to ensure data integrity." diff --git a/.github/custom-queries/matlab/Potential Buffer Overflow via fscanf.ql b/.github/custom-queries/matlab/Potential Buffer Overflow via fscanf.ql new file mode 100644 index 00000000..65fec298 --- /dev/null +++ b/.github/custom-queries/matlab/Potential Buffer Overflow via fscanf.ql @@ -0,0 +1,24 @@ +/** + * @name Potential buffer overflow in fscanf + * @description Detects potential buffer overflow vulnerabilities when using `fscanf` without checking input size. + * @kind problem + * @problem.severity critical + * @tags security, buffer-overflow + */ +import javascript + +class BufferOverflowFscanf extends Expr { + BufferOverflowFscanf() { + this.getFile().getName().endsWith(".m") and + exists(Expr fscanfCall | + fscanfCall.getSource() = this and + fscanfCall.toString().matches("fscanf%") and + not exists(Expr sizeCheck | + sizeCheck.getSource() = fscanfCall and + sizeCheck.toString().matches("(size|length)%")) + ) + } +} + +from BufferOverflowFscanf fscanfCall +select fscanfCall, "Potential buffer overflow detected in fscanf usage without input size validation." diff --git a/.github/custom-queries/matlab/Unchecked System() command.ql b/.github/custom-queries/matlab/Unchecked System() command.ql new file mode 100644 index 00000000..1c3880d4 --- /dev/null +++ b/.github/custom-queries/matlab/Unchecked System() command.ql @@ -0,0 +1,24 @@ +/** + * @name Unchecked system command execution + * @description Detects `system()` function usage with untrusted inputs, which can lead to command injection vulnerabilities. + * @kind problem + * @problem.severity critical + * @tags security, command-injection + */ +import javascript + +class UncheckedSystemCommand extends Expr { + UncheckedSystemCommand() { + this.getFile().getName().endsWith(".m") and + exists(Expr systemCall | + systemCall.getSource() = this and + systemCall.toString().matches("system%") and + not exists(Expr validation | + validation.getSource() = systemCall and + validation.toString().matches("(validate|sanitize)%")) + ) + } +} + +from UncheckedSystemCommand systemCall +select systemCall, "Unchecked system command execution detected. Ensure input is properly validated or sanitized." diff --git a/.github/custom-queries/matlab/Uninitialized Variables.ql b/.github/custom-queries/matlab/Uninitialized Variables.ql new file mode 100644 index 00000000..779c15b8 --- /dev/null +++ b/.github/custom-queries/matlab/Uninitialized Variables.ql @@ -0,0 +1,25 @@ +/** + * @name Uninitialized variable in MATLAB + * @description Find variables used without being initialized. + * @kind problem + * @problem.severity warning + * @tags reliability + */ + +import javascript + +// Find a variable usage before its assignment +class MatlabVariableUsage extends Expr { + MatlabVariableUsage() { + this.getFile().getName().endsWith(".m") and + exists(Expr usage | + usage = this and + not exists(Expr init | + init.getSource() = usage and + init.getFile().getName().endsWith(".m")) + ) + } +} + +from MatlabVariableUsage usage +select usage, "Possible uninitialized variable usage in MATLAB" diff --git a/.github/custom-queries/matlab/Unsafe Use of system Command.ql b/.github/custom-queries/matlab/Unsafe Use of system Command.ql new file mode 100644 index 00000000..6b3b1c52 --- /dev/null +++ b/.github/custom-queries/matlab/Unsafe Use of system Command.ql @@ -0,0 +1,25 @@ +/** + * @name Insecure use of system command + * @description Detects unvalidated input passed to the `system` function, which can lead to command injection. + * @kind problem + * @problem.severity critical + * @tags security, command-injection + */ + +import javascript + +class MatlabSystemCommand extends Expr { + MatlabSystemCommand() { + this.getFile().getName().endsWith(".m") and + exists(Expr sysCall | + sysCall.getSource() = this and + sysCall.toString().matches("system%") and + not exists(Expr inputValidation | + inputValidation.getSource() = sysCall and + inputValidation.toString().matches("validate%")) + ) + } +} + +from MatlabSystemCommand sysCall +select sysCall, "Potentially unsafe system command execution without input validation." diff --git a/.github/custom-queries/matlab/Unsafe fopen Usage.ql b/.github/custom-queries/matlab/Unsafe fopen Usage.ql new file mode 100644 index 00000000..ecb4176f --- /dev/null +++ b/.github/custom-queries/matlab/Unsafe fopen Usage.ql @@ -0,0 +1,25 @@ +/** + * @name Unsafe fopen usage + * @description Detects `fopen` calls without error handling or proper file permissions. + * @kind problem + * @problem.severity warning + * @tags security, file-handling + */ + +import javascript + +class MatlabUnsafeFopenUsage extends Expr { + MatlabUnsafeFopenUsage() { + this.getFile().getName().endsWith(".m") and + exists(Expr fopenCall | + fopenCall.getSource() = this and + fopenCall.toString().matches("fopen%") and + not exists(Expr fcloseCall | + fcloseCall.getSource() = fopenCall and + fcloseCall.toString().matches("fclose%")) + ) + } +} + +from MatlabUnsafeFopenUsage fopenCall +select fopenCall, "File opened with fopen but no fclose or error handling detected." diff --git a/.github/custom-queries/matlab/Unsanitized User Input.ql b/.github/custom-queries/matlab/Unsanitized User Input.ql new file mode 100644 index 00000000..80b28995 --- /dev/null +++ b/.github/custom-queries/matlab/Unsanitized User Input.ql @@ -0,0 +1,24 @@ +/** + * @name Unsanitized user input in plotting functions + * @description Detects unsanitized or unvalidated user input passed to plotting functions, which can lead to vulnerabilities. + * @kind problem + * @problem.severity medium + * @tags security, input-validation + */ +import javascript + +class UnsanitizedInputInPlot extends Expr { + UnsanitizedInputInPlot() { + this.getFile().getName().endsWith(".m") and + exists(Expr plotCall | + plotCall.getSource() = this and + plotCall.toString().matches("(plot|scatter|bar|hist)%") and + not exists(Expr inputValidation | + inputValidation.getSource() = plotCall and + inputValidation.toString().matches("(validate|sanitize)%")) + ) + } +} + +from UnsanitizedInputInPlot plotCall +select plotCall, "Unsanitized user input detected in plotting function. Ensure input is properly validated or sanitized." diff --git a/.github/custom-queries/matlab/Untrusted Input.ql b/.github/custom-queries/matlab/Untrusted Input.ql new file mode 100644 index 00000000..d23572f0 --- /dev/null +++ b/.github/custom-queries/matlab/Untrusted Input.ql @@ -0,0 +1,23 @@ +/** + * @name Untrusted input in eval + * @description Detects `eval` function usage with untrusted or unsanitized input, leading to potential code injection. + * @kind problem + * @problem.severity critical + * @tags security, code-injection + */ +import javascript + +class EvalUntrustedInput extends Expr { + EvalUntrustedInput() { + this.getFile().getName().endsWith(".m") and + exists(Expr evalCall | + evalCall.getSource() = this and + evalCall.toString().matches("eval%") and + not exists(Expr inputValidation | + inputValidation.getSource() = evalCall and inputValidation.toString().matches("(validate|sanitiz)%")) + ) + } +} + +from EvalUntrustedInput evalCall +select evalCall, "Potential code injection via untrusted input passed to eval function." diff --git a/.github/custom-queries/matlab/Unvalidated User Input in File Operations.ql b/.github/custom-queries/matlab/Unvalidated User Input in File Operations.ql new file mode 100644 index 00000000..bc751500 --- /dev/null +++ b/.github/custom-queries/matlab/Unvalidated User Input in File Operations.ql @@ -0,0 +1,23 @@ +/** + * @name Unvalidated input in file operations + * @description Detects unvalidated user input used in file operations, leading to potential file injection or manipulation. + * @kind problem + * @problem.severity critical + * @tags security, input-validation + */ +import javascript + +class UnvalidatedInputFileOp extends Expr { + UnvalidatedInputFileOp() { + this.getFile().getName().endsWith(".m") and + exists(Expr fileOp | + fileOp.getSource() = this and + fileOp.toString().matches("(fopen|fwrite|fclose)%") and + not exists(Expr inputValidation | + inputValidation.getSource() = fileOp and inputValidation.toString().matches("(validate|sanitiz)%")) + ) + } +} + +from UnvalidatedInputFileOp fileOp +select fileOp, "Unvalidated input passed to file operations like fopen or fwrite, leading to security risks." diff --git a/.github/custom-queries/matlab/Use of Weak Cryptographic functions.ql b/.github/custom-queries/matlab/Use of Weak Cryptographic functions.ql new file mode 100644 index 00000000..136d9129 --- /dev/null +++ b/.github/custom-queries/matlab/Use of Weak Cryptographic functions.ql @@ -0,0 +1,21 @@ +/** + * @name Weak cryptographic functions + * @description Detects usage of weak or deprecated cryptographic functions such as MD5. + * @kind problem + * @problem.severity high + * @tags security, cryptography + */ +import javascript + +class WeakCryptography extends Expr { + WeakCryptography() { + this.getFile().getName().endsWith(".m") and + exists(Expr cryptoCall | + cryptoCall.getSource() = this and + cryptoCall.toString().matches("(md5|sha1)%") + ) + } +} + +from WeakCryptography cryptoCall +select cryptoCall, "Weak cryptographic function detected (md5 or sha1), consider stronger alternatives." diff --git a/.github/custom-queries/matlab/analyze_code.m b/.github/custom-queries/matlab/analyze_code.m new file mode 100644 index 00000000..b96fe4fe --- /dev/null +++ b/.github/custom-queries/matlab/analyze_code.m @@ -0,0 +1,150 @@ +% Add the current working directory and subdirectories to the path +addpath(genpath(pwd)); + +% Find all .m files in the current directory and subdirectories +files = dir('**/*.m'); + +% Initialize results +results = {}; + +% Loop through each file and perform analysis +for k = 1:length(files) + filePath = fullfile(files(k).folder, files(k).name); + fid = fopen(filePath, 'r'); + + if fid == -1 + disp(['Could not open file: ', filePath]); + continue; + end + + code = fread(fid, '*char')'; % Read file contents + fclose(fid); + + % Initialize issues for the current file + issues = {}; + + % Check for improper input handling in mathematical operations + if contains(code, '+') || contains(code, '-') || contains(code, '*') || contains(code, '/') || ... + contains(code, '^') || contains(code, 'sqrt') || contains(code, 'log') + if ~contains(code, 'validate') && ~contains(code, 'sanitize') + issues{end+1} = 'Improper input handling in mathematical operations detected.'; + end + end + + % Check for improper use of cd command + if contains(code, 'cd') + if ~contains(code, 'exist') && ~contains(code, 'isdir') + issues{end+1} = 'Improper use of cd command without validating the directory path.'; + end + end + + % Check for unsafe mkdir usage + if contains(code, 'mkdir') + if ~contains(code, 'exist') && ~contains(code, 'isdir') + issues{end+1} = 'Unsafe use of mkdir without checking for directory existence or permissions.'; + end + end + + % Check for deprecated functions usage + if contains(code, 'str2num') || contains(code, 'input') || contains(code, 'addpath') + issues{end+1} = 'Deprecated function usage detected. Consider updating to supported alternatives.'; + end + + % Additional Checks + + % 1. Check for hard-coded credentials + if contains(code, 'password') || contains(code, 'passwd') || contains(code, 'apiKey') || ... + contains(code, 'secret') || contains(code, 'token') + if ~contains(code, 'validate') && ~contains(code, 'sanitize') + issues{end+1} = 'Hard-coded credentials detected. Avoid hard-coding sensitive information.'; + end + end + + % 2. Check for hard-coded IP addresses + if contains(code, '(\d{1,3}\.){3}\d{1,3}') % Regular expression for matching IP addresses + issues{end+1} = 'Hard-coded IP address detected. Consider using a configuration file or environment variables.'; + end + + % 3. Check for improper use of pause function + if contains(code, 'pause') + if ~contains(code, 'check') && ~contains(code, 'validate') + issues{end+1} = 'Improper use of pause function detected without timing checks.'; + end + end + + % 4. Check for improper use of rmdir + if contains(code, 'rmdir') + if ~contains(code, 'exist') && ~contains(code, 'isdir') + issues{end+1} = 'Improper use of rmdir without validating the directory path.'; + end + end + + % 5. Check for missing fclose after fopen + if contains(code, 'fopen') + if ~contains(code, 'fclose') + issues{end+1} = 'Missing fclose after fopen. Ensure to close files to prevent resource leaks.'; + end + end + + % 6. Check for insecure file permissions + if contains(code, 'chmod') || contains(code, 'chown') + issues{end+1} = 'Insecure file permissions command detected. Review file permission handling.'; + end + + % 7. Check for insecure random number generation + if contains(code, 'rand') + issues{end+1} = 'Insecure random number generation detected. Consider using a cryptographically secure alternative.'; + end + + % 8. Check for insecure save function usage + if contains(code, 'save') && ~contains(code, '-v7.3') + issues{end+1} = 'Insecure save function usage detected. Consider using the -v7.3 option for saving files.'; + end + + % 9. Check for insecure use of eval + if contains(code, 'eval') + issues{end+1} = 'Potentially unsafe use of eval detected. Avoid using eval for executing arbitrary code.'; + end + + % 10. Check for unclosed figures + if contains(code, 'figure') && ~contains(code, 'close') + issues{end+1} = 'Figures created but not closed. Ensure to close figures to free up system resources.'; + end + + % 11. Check for lack of error handling + if contains(code, 'try') && ~contains(code, 'catch') + issues{end+1} = 'Try without catch. Ensure proper error handling is implemented.'; + end + + % 12. Check for usage of global variables + if contains(code, 'global') + issues{end+1} = 'Use of global variables detected. Minimize the use of global variables for better encapsulation.'; + end + + % 13. Check for comments not matching code + if contains(code, '%') + % Check for comment length versus code length + lines = strsplit(code, '\n'); + for line = lines + if length(line{1}) < 20 && contains(line{1}, '%') % Short comments + issues{end+1} = 'Comments should provide sufficient context; consider expanding short comments.'; + end + end + end + + % 14. Check for excessively long lines + lines = strsplit(code, '\n'); + for i = 1:length(lines) + if length(lines{i}) > 80 + issues{end+1} = sprintf('Line %d exceeds 80 characters. Consider breaking it into multiple lines.', i); + end + end + + % Store file path and issues found in results + if ~isempty(issues) + results{end+1} = {filePath, issues}; + end +end + +% Save results to .mat file +save('code-analysis-results.mat', 'results'); diff --git a/.github/custom-queries/matlab/convert_to_sarif.m b/.github/custom-queries/matlab/convert_to_sarif.m new file mode 100644 index 00000000..b2618616 --- /dev/null +++ b/.github/custom-queries/matlab/convert_to_sarif.m @@ -0,0 +1,46 @@ +% Load the results from the .mat file +load('code-analysis-results.mat', 'results'); + +% Initialize SARIF structure +sarif.version = "2.1.0"; +sarif.runs = struct([]); + +% Initialize run object +run.tool.driver.name = "Octave Static Code Analysis for MATLAB"; +run.tool.driver.version = "1.0"; +run.results = []; + +% Populate SARIF results +for i = 1:length(results) + filePath = results{i}{1}; + issues = results{i}{2}; + + % Loop over each issue found in the file + for j = 1:length(issues) + % Create SARIF result entry for each issue + sarifResult = struct(); + sarifResult.ruleId = "MATLABIssue"; % Identifier for the issue type + sarifResult.level = "warning"; + sarifResult.message = struct('text', issues{j}); + + % Specify the location + sarifResult.locations = struct([]); + sarifResult.locations(1).physicalLocation.artifactLocation.uri = filePath; + sarifResult.locations(1).physicalLocation.region.startLine = 1; % Set startLine if available + + % Add result to the SARIF run + run.results = [run.results, sarifResult]; + end +end + +% Add the populated run to SARIF +sarif.runs = [sarif.runs, run]; + +% Save SARIF output to a JSON file +jsonText = jsonencode(sarif); +fid = fopen('code-analysis-results.sarif', 'w'); +if fid == -1 + error('Could not create SARIF file'); +end +fwrite(fid, jsonText, 'char'); +fclose(fid); diff --git a/.github/custom-queries/matlab/convert_to_sarif.py b/.github/custom-queries/matlab/convert_to_sarif.py new file mode 100644 index 00000000..fc1ea0d2 --- /dev/null +++ b/.github/custom-queries/matlab/convert_to_sarif.py @@ -0,0 +1,53 @@ +import scipy.io +import json + +# Load the .mat file +data = scipy.io.loadmat('code-analysis-results.mat') +results = data.get('results', []) + +# SARIF template +sarif = { + "version": "2.1.0", + "runs": [ + { + "tool": { + "driver": { + "name": "MATLAB Code Analysis", + "informationUri": "https://github.com/username/repo", + "rules": [ + { + "id": "MATLAB001", + "name": "MATLAB Code Issue", + "shortDescription": {"text": "Identified MATLAB Code Issue"}, + "fullDescription": {"text": "This issue was identified in the MATLAB code."}, + "defaultConfiguration": {"level": "warning"} + } + ] + } + }, + "results": [] + } + ] +} + +# Convert each entry in the results to SARIF format +for item in results: + file_path = item[0][0] + issues = item[1][0] + for issue in issues: + sarif_issue = { + "ruleId": "MATLAB001", + "message": {"text": issue[0]}, + "locations": [ + { + "physicalLocation": { + "artifactLocation": {"uri": file_path}, + } + } + ] + } + sarif["runs"][0]["results"].append(sarif_issue) + +# Write to SARIF file +with open('code-analysis-results.sarif', 'w') as f: + json.dump(sarif, f, indent=2) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..4dfc7882 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,94 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL Advanced" + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + schedule: + - cron: '32 10 * * 2' + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners (GitHub.com only) + # Consider using larger runners or machines with greater resources for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + # only required for workflows in private repositories + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + include: + - language: c-cpp + build-mode: autobuild + - language: python + build-mode: none + # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' + # Use `c-cpp` to analyze code written in C, C++ or both + # Use 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, + # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. + # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how + # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + # If the analyze step fails for one of the languages you are analyzing with + # "We were unable to automatically build your code", modify the matrix above + # to set the build mode to "manual" for that language. Then modify this step + # to build your code. + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + - if: matrix.build-mode == 'manual' + shell: bash + run: | + echo 'If you are using a "manual" build mode for one or more of the' \ + 'languages you are analyzing, replace this with the commands to build' \ + 'your code, for example:' + echo ' make bootstrap' + echo ' make release' + exit 1 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/matlab-scan.yml b/.github/workflows/matlab-scan.yml new file mode 100644 index 00000000..4f351ff7 --- /dev/null +++ b/.github/workflows/matlab-scan.yml @@ -0,0 +1,96 @@ +name: "Octave Static Code Analysis for MATLAB" + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + workflow_dispatch: + +jobs: + analyze: + name: Analyze MATLAB Code with Octave + runs-on: ubuntu-latest + + steps: + # Step 1: Checkout repository + - name: Checkout repository + uses: actions/checkout@v3 + + # Step 2: Install Octave + - name: Install Octave + run: | + sudo apt-get update + sudo apt-get install -y octave + + # Step 3: Check for .m files in the repository + - name: Find .m files + id: find_files + run: | + m_files=$(find . -name "*.m") + if [ -z "$m_files" ]; then + echo "No .m files found!" + exit 1 + else + echo "$m_files" + fi + + # Step 4: Create MATLAB analysis script + - name: Create MATLAB analysis script + run: | + mkdir -p .github/custom-queries/matlab + echo "% Add current directory and subdirectories to path" > .github/custom-queries/matlab/analyze_code.m + echo "addpath(genpath(pwd));" >> .github/custom-queries/matlab/analyze_code.m + echo "% Find all .m files" >> .github/custom-queries/matlab/analyze_code.m + echo "files = dir('**/*.m');" >> .github/custom-queries/matlab/analyze_code.m + echo "% Initialize analysis results" >> .github/custom-queries/matlab/analyze_code.m + echo "results = {};" >> .github/custom-queries/matlab/analyze_code.m + echo "% Analyze each file" >> .github/custom-queries/matlab/analyze_code.m + echo "for k = 1:length(files)" >> .github/custom-queries/matlab/analyze_code.m + echo " filePath = fullfile(files(k).folder, files(k).name);" >> .github/custom-queries/matlab/analyze_code.m + echo " fid = fopen(filePath, 'r');" >> .github/custom-queries/matlab/analyze_code.m + echo " code = fread(fid, '*char')';" >> .github/custom-queries/matlab/analyze_code.m + echo " fclose(fid);" >> .github/custom-queries/matlab/analyze_code.m + echo " % Add any custom analysis logic here" >> .github/custom-queries/matlab/analyze_code.m + echo " issues = {};" >> .github/custom-queries/matlab/analyze_code.m + echo " if ~isempty(issues)" >> .github/custom-queries/matlab/analyze_code.m + echo " results{end+1} = {filePath, issues};" >> .github/custom-queries/matlab/analyze_code.m + echo " end" >> .github/custom-queries/matlab/analyze_code.m + echo "end" >> .github/custom-queries/matlab/analyze_code.m + echo "% Save the analysis results to a .mat file" >> .github/custom-queries/matlab/analyze_code.m + echo "save('code-analysis-results.mat', 'results');" >> .github/custom-queries/matlab/analyze_code.m + + # Step 5: Run the static code analysis using Octave + - name: Run MATLAB code analysis with Octave + run: | + octave --no-gui .github/custom-queries/matlab/analyze_code.m + + # Step 6: Verify the contents of the .mat file + - name: Verify .mat file contents + run: | + octave --eval "load('code-analysis-results.mat'); whos" + + # Step 7: Create display results script to show output + - name: Create display results script + run: | + echo "% Load and display .mat file contents" > display_results.m + echo "try" >> display_results.m + echo " load('code-analysis-results.mat');" >> display_results.m + echo " if exist('results', 'var')" >> display_results.m + echo " if isempty(results)" >> display_results.m + echo " disp('Code analysis completed: No vulnerabilities or issues found.');" >> display_results.m + echo " else" >> display_results.m + echo " disp('Analysis Results:');" >> display_results.m + echo " disp(results);" >> display_results.m + echo " end" >> display_results.m + echo " else" >> display_results.m + echo " disp('Error: Variable ''results'' not found in the .mat file.');" >> display_results.m + echo " end" >> display_results.m + echo "catch" >> display_results.m + echo " disp('Error loading the .mat file or executing the script.');" >> display_results.m + echo "end" >> display_results.m + + # Step 8: Run display results script + - name: Run display results script + run: | + octave --no-gui display_results.m