diff --git a/README.md b/README.md
index 36eb40939..6f63c5651 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
Bearer CLI is a static application security testing (SAST) tool that scans your source code and analyzes your data flows to discover, filter and prioritize security and privacy risks.
- Currently supporting: JavaScript/TypeScript (GA), Ruby (GA), Java (Beta), PHP (Beta), Go (Alpha), Python (Alpha) - Learn more
+ Currently supporting: JavaScript/TypeScript (GA), Ruby (GA), Java (Beta), PHP (Beta), Go (Beta), Python (Alpha) - Learn more
@@ -259,17 +259,17 @@ Bearer CLI currently supports:
GA |
- JavaScript/TypeScript, Ruby |
+ JavaScript/TypeScript, Ruby |
Beta |
- Java, PHP |
+ Java, PHP |
Alpha |
- Go, Python |
+ Go, Python |
-
+
[Learn more](https://docs.bearer.com/reference/supported-languages/) about language support.
diff --git a/docs/.eleventy.js b/docs/.eleventy.js
index 1553593ff..c478660b0 100644
--- a/docs/.eleventy.js
+++ b/docs/.eleventy.js
@@ -51,10 +51,10 @@ module.exports = function (eleventyConfig) {
return now
})
eleventyConfig.addShortcode("sectionLinks", function (sectionName) {
- const section = nav.find(item => item.name == sectionName)
+ const section = nav.find((item) => item.name == sectionName)
let out = ""
- if(section){
- section.items.forEach(item => {
+ if (section) {
+ section.items.forEach((item) => {
out += `- [${item.name}](${item.url})\n`
})
}
@@ -63,19 +63,24 @@ module.exports = function (eleventyConfig) {
})
// {% yamlExample "ci/gitlab/basic" %}
- eleventyConfig.addShortcode('yamlExample', function (exampleName) {
- const example = fs.readFileSync(`./_data/examples/${exampleName}.yaml`, 'utf8')
- return '```yaml\n' + example + '\n```';
- });
+ eleventyConfig.addShortcode("yamlExample", function (exampleName) {
+ const example = fs.readFileSync(
+ `./_data/examples/${exampleName}.yaml`,
+ "utf8"
+ )
+ return "```yaml\n" + example + "\n```"
+ })
- eleventyConfig.addShortcode('githubAction', function(data){
+ eleventyConfig.addShortcode("githubAction", function (data) {
out = "| Option | Description | Default |\n"
out += "| - | - | - |\n"
- Object.keys(data).sort().forEach(key => {
- const item = data[key]
- const default_val = item.default ? "`"+item.default+"`" : ""
- out += `| **${key}** | ${item.description} | ${default_val} |\n`
- });
+ Object.keys(data)
+ .sort()
+ .forEach((key) => {
+ const item = data[key]
+ const default_val = item.default ? "`" + item.default + "`" : ""
+ out += `| **${key}** | ${item.description} | ${default_val} |\n`
+ })
return out
})
@@ -178,8 +183,7 @@ module.exports = function (eleventyConfig) {
const target = parent.split(path.sep).slice(1, -1)
const check = child.split(path.sep).slice(1, -1)
// handles individual rule pages highlighting "rule" in side nav
- const isRule =
- target.includes("rules") && check[check.length - 2] === "rules"
+ const isRule = target.includes("rules")
if (child === parent || isRule) {
return true
} else {
diff --git a/docs/_data/rules.js b/docs/_data/rules.js
index b9eaede57..f2f9d0002 100644
--- a/docs/_data/rules.js
+++ b/docs/_data/rules.js
@@ -1,31 +1,33 @@
-const { readFile, readdir } = require("node:fs/promises");
-const { statSync } = require("fs");
-const EleventyFetch = require("@11ty/eleventy-fetch");
-const path = require("path");
-const yaml = require("js-yaml");
-const cweList = require("./cweList.json");
-const gitly = require("gitly");
-const source = "bearer/bearer-rules";
-const rulesPath = "_tmp/rules-data";
-const excludeDirectories = [".github", "scripts"];
+const { readFile, readdir } = require("node:fs/promises")
+const { statSync } = require("fs")
+const EleventyFetch = require("@11ty/eleventy-fetch")
+const path = require("path")
+const yaml = require("js-yaml")
+const cweList = require("./cweList.json")
+const gitly = require("gitly")
+const source = "bearer/bearer-rules"
+const rulesPath = "_tmp/rules-data"
+const excludeDirectories = [".github", "scripts"]
let counts = {
languages: {},
-};
+}
function updateCounts(lang, framework = null, id = null) {
if (framework !== null) {
if (counts.languages[lang].frameworks[framework]) {
- counts.languages[lang].frameworks[framework].count++;
- counts.languages[lang].frameworks[framework].rules.push(id);
+ counts.languages[lang].frameworks[framework].count++
+ counts.languages[lang].frameworks[framework].rules.push(id)
+ } else if (framework === "gosec") {
+ newFramework(lang, framework)
} else if (framework !== "lang") {
- newFramework(lang, framework);
+ newFramework(lang, framework)
} else if (framework === "lang") {
- counts.languages[lang].baseRules.push(id);
+ counts.languages[lang].baseRules.push(id)
}
- counts.languages[lang].count++;
+ counts.languages[lang].count++
} else {
- newLang(lang);
+ newLang(lang)
}
}
@@ -34,7 +36,7 @@ function newFramework(lang, name) {
name,
count: 1,
rules: [],
- };
+ }
}
function newLang(name) {
@@ -43,16 +45,16 @@ function newLang(name) {
count: 0,
baseRules: [],
frameworks: {},
- };
+ }
}
function isDirectory(dir) {
- const result = statSync(dir);
- return result.isDirectory();
+ const result = statSync(dir)
+ return result.isDirectory()
}
async function fetchRelease() {
- let latest = {};
+ let latest = {}
try {
latest = await EleventyFetch(
`https://api.github.com/repos/${source}/releases/latest`,
@@ -60,76 +62,102 @@ async function fetchRelease() {
duration: "60m",
type: "json",
}
- );
+ )
} catch (e) {
- console.error(e);
+ console.error(e)
}
try {
- let src = await gitly.download(`${source}#${latest.tag_name}`);
- await gitly.extract(src, rulesPath);
+ let src = await gitly.download(`${source}#${latest.tag_name}`)
+ await gitly.extract(src, rulesPath)
} catch (e) {
- throw console.error(e);
+ throw console.error(e)
}
}
async function fetchData(location) {
- let rules = [];
+ let rules = []
try {
- const dirs = await readdir(location);
+ const dirs = await readdir(location)
// ex: looping through rules [ruby, gitleaks, sql]
dirs.forEach(async (dir) => {
- const dirPath = path.join(location, dir);
+ const dirPath = path.join(location, dir)
if (isDirectory(dirPath) && !excludeDirectories.includes(dir)) {
- const subDirs = await readdir(dirPath);
- updateCounts(dir);
+ const subDirs = await readdir(dirPath)
+ updateCounts(dir)
// ex. looping through rules/ruby [lang, rails]
subDirs.forEach(async (subDir) => {
- const subDirPath = path.join(dirPath, subDir);
- if (isDirectory(subDirPath) && subDir !== "shared") {
- const files = await readdir(subDirPath);
+ const subDirPath = path.join(dirPath, subDir)
+ if (
+ isDirectory(subDirPath) &&
+ subDir !== "shared" &&
+ subDir !== "gosec"
+ ) {
+ const files = await readdir(subDirPath)
const children = await fetchAllFiles(
subDirPath,
path.join(dir, subDir),
files
- );
- rules.push(...children);
+ )
+ rules.push(...children)
+ } else if (isDirectory(subDirPath) && subDir === "gosec") {
+ const groupDirs = await readdir(subDirPath)
+
+ groupDirs.forEach(async (groupDir) => {
+ const groupDirPath = path.join(dirPath, subDir, groupDir)
+ if (isDirectory(groupDirPath)) {
+ const files = await readdir(groupDirPath)
+ const children = await fetchAllFiles(
+ groupDirPath,
+ path.join(dir, subDir, groupDir),
+ files
+ )
+ rules.push(...children)
+ }
+ })
}
- });
+ })
}
- });
- return { counts, rules };
+ })
+ return { counts, rules }
} catch (err) {
- throw err;
+ throw err
}
}
async function fetchAllFiles(directory, breadcrumb, files) {
let result = await Promise.all(
files.reduce((all, file) => {
- const location = path.join(directory, file);
+ const location = path.join(directory, file)
if (path.extname(location) === ".yml") {
- return [...all, fetchFile(path.join(directory, file), breadcrumb)];
+ return [...all, fetchFile(path.join(directory, file), breadcrumb)]
} else {
- return all;
+ return all
}
}, [])
- );
- return result;
+ )
+ return result
}
async function fetchFile(location, breadcrumb) {
return readFile(location, { encoding: "utf8" }).then((file) => {
- let out = yaml.load(file);
- let owasps = new Set();
- let subdir = breadcrumb.split("/");
- let framework = subdir[subdir.length - 1];
- updateCounts(subdir[subdir.length - 2], framework, out.metadata.id);
+ let out = yaml.load(file)
+ let owasps = new Set()
+ let subdir = breadcrumb.split("/")
+ let groupId = subdir[subdir.length - 2]
+ let framework = subdir[subdir.length - 1]
+ let lang = subdir[subdir.length - 2]
+ if (groupId === "gosec") {
+ framework = groupId
+ lang = subdir[subdir.length - 3]
+ }
+
+ updateCounts(lang, framework, out.metadata.id)
if (out.metadata.cwe_id) {
out.metadata.cwe_id.forEach((i) => {
- if (cweList[i].owasp) {
- owasps.add(cweList[i].owasp.id);
+ if (cweList[i] && cweList[i].owasp) {
+ owasps.add(cweList[i].owasp.id)
}
- });
+ })
}
return {
name: path.basename(location, ".yml"),
@@ -137,11 +165,11 @@ async function fetchFile(location, breadcrumb) {
owasp_ids: [...owasps].sort(),
framework,
...out,
- };
- });
+ }
+ })
}
module.exports = async function () {
- await fetchRelease();
- return await fetchData(path.join(rulesPath, "rules"));
-};
+ await fetchRelease()
+ return await fetchData(path.join(rulesPath, "rules"))
+}