@flamesshield/rules-engine
Version:
Independent rules engine for security analysis of Firebase
165 lines • 5.54 kB
JavaScript
/**
* Generate SARIF (Static Analysis Results Interchange Format) output
* Based on SARIF v2.1.0 specification
*/
export function generateSARIF(analysisResult) {
const triggeredResults = analysisResult.results.filter(r => r.triggered);
const sarif = {
$schema: "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
version: "2.1.0",
runs: [
{
tool: {
driver: {
name: "FireShield Security Analysis",
version: "1.0.0",
informationUri: "https://fireshield.dev",
organization: "FireShield",
shortDescription: {
text: "Firebase Security Analysis Tool"
},
fullDescription: {
text: "Comprehensive security analysis for Firebase projects using configurable rules"
},
rules: generateSarifRules(analysisResult.results)
}
},
results: generateSarifResults(triggeredResults),
invocations: [
{
executionSuccessful: true,
startTimeUtc: analysisResult.timestamp,
endTimeUtc: new Date().toISOString(),
machine: "rules-engine",
account: "system",
processId: 1,
workingDirectory: {
uri: `firebase:///projects/${analysisResult.project_id}`
}
}
],
artifacts: [
{
location: {
uri: `firebase:///projects/${analysisResult.project_id}/configuration`
},
description: {
text: "Firebase project configuration and resources"
}
}
],
columnKind: "utf16CodeUnits"
}
]
};
return sarif;
}
/**
* Generate SARIF rules section
*/
function generateSarifRules(results) {
const uniqueRules = new Map();
for (const result of results) {
if (!uniqueRules.has(result.rule_id)) {
uniqueRules.set(result.rule_id, {
id: result.rule_id,
name: result.rule_name,
shortDescription: {
text: result.rule_name
},
fullDescription: {
text: result.message
},
defaultConfiguration: {
level: mapSeverityToLevel(result.severity)
},
properties: {
category: result.category,
severity: result.severity,
tags: [
"firebase",
"security",
result.category.toLowerCase().replace(/\s+/g, '-')
]
}
});
}
}
return Array.from(uniqueRules.values());
}
/**
* Generate SARIF results section
*/
function generateSarifResults(triggeredResults) {
return triggeredResults.map((result, index) => ({
ruleId: result.rule_id,
ruleIndex: index,
level: mapSeverityToLevel(result.severity),
message: {
text: result.message,
id: "default"
},
locations: [
{
physicalLocation: {
artifactLocation: {
uri: `firebase:///projects/configuration`,
uriBaseId: "PROJECTROOT"
},
region: {
startLine: 1,
startColumn: 1,
endLine: 1,
endColumn: 1
}
},
logicalLocations: [
{
name: result.category,
kind: "namespace"
}
]
}
],
fingerprints: {
"fireShield/v1": generateFingerprint(result)
},
properties: {
category: result.category,
severity: result.severity,
event_params: result.event_params,
execution_time: new Date().toISOString()
}
}));
}
/**
* Map our severity levels to SARIF levels
*/
function mapSeverityToLevel(severity) {
switch (severity.toLowerCase()) {
case 'critical':
case 'high':
return 'error';
case 'medium':
return 'warning';
case 'low':
return 'note';
default:
return 'note';
}
}
/**
* Generate a fingerprint for the result to help with deduplication
*/
function generateFingerprint(result) {
const source = `${result.rule_id}:${result.category}:${result.message}`;
// Simple hash function for fingerprinting
let hash = 0;
for (let i = 0; i < source.length; i++) {
const char = source.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32-bit integer
}
return Math.abs(hash).toString(16);
}
//# sourceMappingURL=index.js.map