diff --git a/package.json b/package.json index 500412f84..f52fc1c58 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "scripts": { "test": "jest", "generate_rule": "node scripts/generate_rule.js", - "bulk-update": "node scripts/bulk_update.js" + "bulk-update": "node scripts/bulk_update.js", + "validate-rule-urls": "node scripts/validate_rule_urls.js" }, "devDependencies": { "jest": "^29.6.1", diff --git a/rules/go/gosec/crypto/weak_tls_version.yml b/rules/go/gosec/crypto/weak_tls_version.yml index 4bf7db405..374dce661 100644 --- a/rules/go/gosec/crypto/weak_tls_version.yml +++ b/rules/go/gosec/crypto/weak_tls_version.yml @@ -68,7 +68,7 @@ metadata: ## Resources - [IETF's Deprecation of TLS 1.0 and 1.1](https://tools.ietf.org/html/rfc8996) - - [OWASP TLS Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/TLS_Security_Cheat_Sheet.html) + - [OWASP TLS Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Security_Cheat_Sheet.html) - [Go `crypto/tls` package documentation](https://pkg.go.dev/crypto/tls) cwe_id: diff --git a/rules/go/gosec/filesystem/tempfile.yml b/rules/go/gosec/filesystem/tempfile.yml index de7e2dc69..f1dcdefb1 100644 --- a/rules/go/gosec/filesystem/tempfile.yml +++ b/rules/go/gosec/filesystem/tempfile.yml @@ -75,8 +75,6 @@ metadata: ## Resources - [Go Documentation: os.CreateTemp](https://pkg.go.dev/os#CreateTemp) - - [Secure Coding Guidelines for File I/O](https://wiki.sei.cmu.edu/confluence/display/seccode/TOCTOU+Race+Conditions) - - [OWASP Guide to File System Security](https://owasp.org/www-community/controls/Path_Traversal) cwe_id: - 378 id: go_gosec_filesystem_tempfile diff --git a/rules/go/gosec/filesystem/ziparchive.yml b/rules/go/gosec/filesystem/ziparchive.yml index 7fa13e553..f46359fb9 100644 --- a/rules/go/gosec/filesystem/ziparchive.yml +++ b/rules/go/gosec/filesystem/ziparchive.yml @@ -135,7 +135,6 @@ metadata: ## Resources - - [OWASP Cheat Sheet: Zip Slip Vulnerability](https://cheatsheetseries.owasp.org/cheatsheets/Path_Traversal_Cheat_Sheet.html) - [Go Documentation: archive/zip package](https://pkg.go.dev/archive/zip) cwe_id: diff --git a/rules/go/gosec/leak/pprof_endpoint.yml b/rules/go/gosec/leak/pprof_endpoint.yml index 233e2f0cd..10ae281dc 100644 --- a/rules/go/gosec/leak/pprof_endpoint.yml +++ b/rules/go/gosec/leak/pprof_endpoint.yml @@ -55,7 +55,7 @@ metadata: - [Go net/http/pprof Package Documentation](https://pkg.go.dev/net/http/pprof) - [Go Build Constraints Documentation](https://pkg.go.dev/go/build#hdr-Build_Constraints) - - [OWASP Security by Design Principles](https://owasp.org/www-project-security-by-design/) + - [OWASP Secure Product Design Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secure_Product_Design_Cheat_Sheet.html) cwe_id: - 200 id: go_gosec_leak_pprof_endpoint diff --git a/rules/go/lang/observable_timing.yml b/rules/go/lang/observable_timing.yml index 6ab6bb8e4..0d19c329e 100644 --- a/rules/go/lang/observable_timing.yml +++ b/rules/go/lang/observable_timing.yml @@ -41,7 +41,7 @@ metadata: ## Resources - [CWE-208: Observable Timing Discrepancy](https://cwe.mitre.org/data/definitions/208.html) - - [OWASP Guide to Cryptography](https://owasp.org/www-project-cheat-sheets/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html) + - [OWASP Guide to Cryptography](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html) cwe_id: - 208 diff --git a/rules/java/lang/observable_timing.yml b/rules/java/lang/observable_timing.yml index 04437bcee..8e9ee412a 100644 --- a/rules/java/lang/observable_timing.yml +++ b/rules/java/lang/observable_timing.yml @@ -43,7 +43,7 @@ metadata: ## Resources - [CWE-208: Observable Timing Discrepancy](https://cwe.mitre.org/data/definitions/208.html) - - [OWASP Guide to Cryptography](https://owasp.org/www-project-cheat-sheets/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html) + - [OWASP Guide to Cryptography](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html) cwe_id: - 208 id: java_lang_observable_timing diff --git a/rules/javascript/lang/observable_timing.yml b/rules/javascript/lang/observable_timing.yml index 20034ef78..b43acc149 100644 --- a/rules/javascript/lang/observable_timing.yml +++ b/rules/javascript/lang/observable_timing.yml @@ -137,7 +137,7 @@ metadata: ## Resources - [CWE-208: Observable Timing Discrepancy](https://cwe.mitre.org/data/definitions/208.html) - - [OWASP Guide to Cryptography](https://owasp.org/www-project-cheat-sheets/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html) + - [OWASP Guide to Cryptography](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html) - [MDN Web Docs on SubtleCrypto API](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) cwe_id: diff --git a/scripts/validate_rule_urls.js b/scripts/validate_rule_urls.js new file mode 100644 index 000000000..dad0ec37c --- /dev/null +++ b/scripts/validate_rule_urls.js @@ -0,0 +1,84 @@ +const fs = require('fs'); +const path = require('path'); +const fetch = require('cross-fetch'); +const { Command } = require('commander'); +const YAML = require('yaml'); + +const program = new Command(); + +const RULES_DIR_PATH = "./rules" + +async function main() { + program.name('validate-rule-urls') + .description('Check validity of URLs in rule descriptions') + .version('1.0.0', '-v, --version') + .action(async function(){ + validateUrls() + }); + + await program.parseAsync(); +} + +async function validateUrls() { + const yamlFiles = getYamlFiles() + yamlFiles.forEach(async (yamlFile) => { + if (yamlFile.path.includes("shared")) return; + + description = yamlFile.data.contents.getIn(["metadata", "remediation_message"]) + urlsFromDescription = extractUrls(description) + urlsFromDescription.forEach(async (url) => { + // try to visit + try { + const response = await fetch(url); + if (!response.ok) { + console.log(`Invalid url: ${url} at ${yamlFile.path}`) + } + } catch (error) { + console.log(`Error fetching: ${url} at ${yamlFile.path}`) + } + }) + }) +} + +function extractUrls(description) { + const regex = /(?:https?|ftp):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?/gi; + const matches = []; + let match; + + // Find all matches in the input string + while ((match = regex.exec(description)) !== null) { + matches.push(match[0]); + } + + return matches; +} + +function getYamlFiles() { + const yamlFiles = []; + const stack = [RULES_DIR_PATH]; + + while (stack.length > 0) { + const currentDir = stack.pop(); + const files = fs.readdirSync(currentDir); + + files.forEach((file) => { + const filePath = path.join(currentDir, file); + const stat = fs.statSync(filePath); + + if (stat.isDirectory()) { + stack.push(filePath); // Add subdirectory to the stack + } else if (path.extname(file) === '.yaml' || path.extname(file) === '.yml') { + const yamlContent = fs.readFileSync(filePath, 'utf8'); + const yamlData = YAML.parseDocument(yamlContent); + yamlFiles.push({ path: filePath, data: yamlData }); + } + }); + } + + return yamlFiles; +} + +main().catch(err => { + console.error(err); + process.exit(1); +}); \ No newline at end of file