Our take on Javascript modules
We belive that if you can read Javascript, so you can write Vidoc modules. Yes, it is that simple.
Features
- An embedded JavaScript engine. (BETA) Real Javascript, not string embedded in YAML.
- Multiple Protocol support. HTTP, DNS, WebSockets, gRPC…
- Speed. Javascript is only used for scripting, the rest is written in Go.
- Typescript support. Write your modules with type safety.
Multi protocol module
Example of module that checks if S3 bucket is writable.
import { http, dns, report } from '@vidoc/modules'
export const metadata = {
id: 'multi-protocol',
name: 'Multi Protocol',
description: 'Check s3 bucket misconfigurations',
severity: 'medium',
};
const Module = async function(target) {
const cnameRecord = await dns.resolve(target, {
type: 'CNAME'
});
if(!cnameRecord.value.includes('s3.aws')) {
return;
}
const response = await http.put(target, {
path: '/test213213213',
body: 'test',
});
if(response.status === 200) {
report.issue(target, 'S3 bucket is writable');
}
}
export default Module
Example of module that extracts urls from HTTP response.
import { http, html, report } from '@vidoc/modules';
export const metadata = {
id: 'extract-all-javascript-files',
name: 'Extract all Javascript files',
description: 'Extract all Javascript files from target',
severity: 'informative',
};
const Module = async (target) => {
const response = await http.get(target);
const doc = html.parse(response.body);
const scripts = doc.findAll('script');
const scriptSources = scripts.map((script) => {
return script.attr('src');
});
report.metadata(target, scriptSources);
}
export default Module
Fuzzing
Example of module that fuzzes HTTP requests.
import { http, match, report } from '../vidoc'
export const metadata = {
id: 'detect-exposed-settings-file',
name: 'Detect exposed settings file',
description: 'Detect exposed settings file',
severity: 'critical',
};
const Module = async (target) => {
const template = http
.newTemplate()
.method('GET')
.path([
'/settings.php.bak',
'/settings.php.dist',
'/settings.php.old',
]);
const responses = await http.send(target, {
template
});
responses.forEach((response) => {
if (response.status === 200 && response.body.includes('DB_NAME')) {
report.issue(target, 'Settings file is exposed');
}
});
}
export default Module