Refactored ScoutSuiteDataParser.js to improve the readability of scoutsuite data extraction process

temp
This commit is contained in:
VakarisZ 2021-01-13 11:03:13 +02:00
parent 7e07489807
commit 7b60d4d2e6
2 changed files with 99 additions and 63 deletions

View File

@ -17,8 +17,8 @@ export default function RuleDisplay(props) {
<p className={'checked-resources-title'}>Resources checked: </p> <p className={'checked-resources-title'}>Resources checked: </p>
<p>{props.rule.checked_items}</p> <p>{props.rule.checked_items}</p>
</div> </div>
{props.rule.references.length !== 0 ? getReferences() : ''} {getReferences()}
{props.rule.items.length !== 0 ? getResources() : ''} {getResources()}
</div>); </div>);
function getReferences() { function getReferences() {
@ -30,11 +30,13 @@ export default function RuleDisplay(props) {
rel="noopener noreferrer" rel="noopener noreferrer"
key={reference}>{reference}</a>) key={reference}>{reference}</a>)
}) })
return ( if (references.length) {
<div className={'reference-list'}> return (
<p className={'reference-list-title'}>References:</p> <div className={'reference-list'}>
{references} <p className={'reference-list-title'}>References:</p>
</div>) {references}
</div>)
}
} }
function getResources() { function getResources() {
@ -46,13 +48,15 @@ export default function RuleDisplay(props) {
resources.push(<ResourceDropdown resource_path={item} resources.push(<ResourceDropdown resource_path={item}
template_path={template_path} template_path={template_path}
scoutsuite_data={props.scoutsuite_data} scoutsuite_data={props.scoutsuite_data}
key={template_path+i}/>) key={template_path + i}/>)
}
if (resources.length) {
return (
<div className={'reference-list'}>
<p className={'reference-list-title'}>Flagged resources (<b>{props.rule.flagged_items}</b>):</p>
{resources}
</div>)
} }
return (
<div className={'reference-list'}>
<p className={'reference-list-title'}>Flagged resources (<b>{props.rule.flagged_items}</b>):</p>
{resources}
</div>)
} }
} }

View File

@ -3,72 +3,104 @@ export default class ScoutSuiteDataParser {
this.runResults = runResults this.runResults = runResults
} }
/* /**
itemPath contains path to a specific value e.g. s3.buckets.da1e7081077ce92.secure_transport_enabled" *
templatePath contains a template path for resource we would want to display e.g. s3.buckets.id * @param itemPath contains path to a specific value e.g. s3.buckets.da1e7081077ce92.secure_transport_enabled
* @param templatePath contains a template path for resource we would want to display e.g. s3.buckets.id
* @returns {*[]|*}
*/ */
getResourceValue(itemPath, templatePath) { getResourceValue(itemPath, templatePath) {
let resourcePath = this.fillTemplatePath(itemPath, templatePath); let resourcePath = this.fillTemplatePath(itemPath, templatePath);
return this.getValueAt(resourcePath); return this.getObjectValueByPath(resourcePath, this.runResults);
} }
fillTemplatePath(itemPath, templatePath) { fillTemplatePath(itemPath, templatePath) {
let itemPathArray = itemPath.split('.'); let itemPathArray = itemPath.split('.');
let templatePathArray = templatePath.split('.'); let templatePathArray = templatePath.split('.');
let resourcePathArray = templatePathArray.map((val, i) => {return val === 'id' ? itemPathArray[i] : val}) let resourcePathArray = templatePathArray.map((val, i) => {
return val === 'id' ? itemPathArray[i] : val
})
return resourcePathArray.join('.'); return resourcePathArray.join('.');
} }
getValueAt(path) { /**
return this.getValueAtRecursive(path, this.runResults) * Retrieves value from ScoutSuite data object based on path, provided in the rule
* @param path E.g. a.id.c.id.e
* @param source E.g. {a: {b: {c: {d: {e: [{result1: 'result1'}, {result2: 'result2'}]}}}}}
* @returns {*[]|*} E.g. ['result1', 'result2']
*/
getObjectValueByPath(path, source) {
let key;
while (path) {
key = this.getNextKeyInPath(path);
source = this.getValueForKey(key, path, source);
path = this.trimFirstKey(path);
}
return source;
} }
getValueAtRecursive(path, source) { getNextKeyInPath(path) {
let value = source; if (path.indexOf('.') !== -1) {
let current_path = path; return path.substr(0, path.indexOf('.'));
let key; } else {
// iterate over each path elements return path;
while (current_path) { }
// check if there are more elements to the path }
if (current_path.indexOf('.') != -1) {
key = current_path.substr(0, current_path.indexOf('.'));
}
// last element
else {
key = current_path;
}
try { /**
// path containing an ".id" * Returns value from object, based on path and current key
if (key == 'id') { * @param key E.g. "a"
let v = []; * @param path E.g. "a.b.c"
let w; * @param source E.g. {a: {b: {c: 'result'}}}
for (let k in value) { * @returns {[]|*} E.g. {b: {c: 'result'}}
// process recursively */
w = this.getValueAtRecursive(k + current_path.substr(current_path.indexOf('.'), current_path.length), value); getValueForKey(key, path, source) {
v = v.concat( if (key === 'id') {
Object.values(w) // get values from array, otherwise it will be an array of key/values return this.getValueByReplacingUnknownKey(path, source);
); } else {
} return source[key];
return v; }
} }
// simple path, just return element in value
else {
value = value[key];
}
} catch (err) {
console.log('Error: ' + err)
}
// check if there are more elements to process /**
if (current_path.indexOf('.') != -1) { * Gets value from object if first key in path doesn't match source object
current_path = current_path.substr(current_path.indexOf('.') + 1, current_path.length); * @param path unknown.b.c
} * @param source {a: {b: {c: [{result:'result'}]}}}
// otherwise we're done * @returns {[]} 'result'
else { */
current_path = false; getValueByReplacingUnknownKey(path, source) {
} let value = [];
for (let key in source) {
value = this.getObjectValueByPath(this.replaceFirstKey(path, key), source);
value = value.concat(Object.values(value));
} }
return value; return value;
} }
/**
* Replaces first key in path
* @param path E.g. "one.two.three"
* @param replacement E.g. "four"
* @returns string E.g. "four.two.three"
*/
replaceFirstKey(path, replacement) {
return replacement + path.substr(path.indexOf('.'), path.length);
}
/**
* Trims the first key from dot separated path.
* @param path E.g. "one.two.three"
* @returns {string|boolean} E.g. "two.three"
*/
trimFirstKey(path) {
if (path.indexOf('.') !== -1) {
return path.substr(path.indexOf('.') + 1, path.length);
} else {
return false;
}
}
} }