Verified Commit 738d005e authored by Thomas Rientjes's avatar Thomas Rientjes
Browse files

Update library audit tool

parent 4662b3c4
......@@ -5,6 +5,7 @@
.gitignore
.idea
.jpmignore
data/_audit/.eslintrc
data/_audit/node_modules
data/_audit/report.txt
test
{
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"array-bracket-newline": "error",
"array-bracket-spacing": "error",
"arrow-body-style": "error",
"arrow-parens": "error",
"arrow-spacing": "error",
"block-spacing": "error",
"brace-style": "error",
"camelcase": "error",
"comma-spacing": "error",
"comma-style": "error",
"computed-property-spacing": "error",
"consistent-this": "error",
"curly": "error",
"eol-last": "error",
"eqeqeq": "error",
"func-call-spacing": "error",
"function-paren-newline": "error",
"generator-star-spacing": "error",
"indent": [
"error",
4
],
"key-spacing": "error",
"keyword-spacing": "error",
"linebreak-style": [
"error",
"unix"
],
"new-cap": "error",
"new-parens": "error",
"no-array-constructor": "error",
"no-bitwise": "error",
"no-confusing-arrow": "error",
"no-console": "off",
"no-continue": "error",
"no-duplicate-imports": "error",
"no-eval": "error",
"no-extend-native": "error",
"no-implicit-coercion": "error",
"no-implied-eval": "error",
"no-invalid-this": "error",
"no-iterator": "error",
"no-label-var": "error",
"no-labels": "error",
"no-lone-blocks": "error",
"no-loop-func": "error",
"no-multi-spaces": "error",
"no-multi-str": "error",
"no-multiple-empty-lines": [
"error", {
"max": 1,
"maxEOF": 1,
"maxBOF": 0
}
],
"no-negated-condition": "error",
"no-new": "error",
"no-new-func": "error",
"no-new-object": "error",
"no-new-wrappers": "error",
"no-octal-escape": "error",
"no-proto": "error",
"no-return-assign": "error",
"no-return-await": "error",
"no-script-url": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-shadow-restricted-names": "error",
"no-tabs": "error",
"no-ternary": "error",
"no-trailing-spaces": "error",
"no-undef-init": "error",
"no-unmodified-loop-condition": "error",
"no-unused-expressions": "error",
"no-use-before-define": "error",
"no-useless-call": "error",
"no-useless-concat": "error",
"no-useless-constructor": "error",
"no-useless-rename": "error",
"no-useless-return": "error",
"no-void": "error",
"no-warning-comments": "warn",
"no-whitespace-before-property": "error",
"no-with": "error",
"object-curly-spacing": "error",
"object-shorthand": [
"error",
"consistent-as-needed"
],
"operator-assignment": "error",
"operator-linebreak": "error",
"prefer-numeric-literals": "error",
"prefer-promise-reject-errors": "error",
"prefer-rest-params": "error",
"prefer-spread": "error",
"prefer-template": "error",
"quote-props": "error",
"quotes": [
"error",
"single"
],
"require-await": "error",
"rest-spread-spacing": "error",
"semi": "error",
"semi-spacing": "error",
"semi-style": "error",
"space-before-blocks": "error",
"space-before-function-paren": "error",
"space-in-parens": "error",
"space-infix-ops": "error",
"space-unary-ops": "error",
"spaced-comment": "error",
"strict": [
"error",
"global"
],
"switch-colon-spacing": "error",
"symbol-description": "error",
"template-curly-spacing": "error",
"template-tag-spacing": "error",
"unicode-bom": "error",
"wrap-regex": "error",
"yield-star-spacing": "error",
"yoda": "error"
}
}
INTRODUCTION
Introduction
------------
This script (first introduced in Decentraleyes v1.1.5) should make reviewing this extension a lot easier than it used to be. It's open source and open for scrutiny, and it automatically compares the bundled libraries (resources) to their original sources (after removing any source mapping URLs).
This audit script allows any user and extension reviewer to verify the integrity of the bundled resources. It automatically, and transparently, compares all bundled libraries to their original sources.
FOR NON-LINUX USERS
-------------------
This usage guide is tailored to Linux based operating systems. If you're on a different type of system, the easiest direct solution might be to launch a free Linux box with Node.js pre-installed on Red Hat OpenShift. You can then SSH into it (after adding your own machine's public key to your account).
Having said that, every terminal command in the usage guide below comes with a description, so it should not be too hard to get this done on practically any type of configuration.
USAGE INSTRUCTIONS
Usage Instructions (Unix)
------------------
1. Make sure you have Node.js installed on your machine (or install it).
1. Make sure you have Node.js installed on your machine.
2. Open up a terminal and 'cd' into this directory.
Description: Navigate to this directory.
2. Open up a terminal and ```cd``` into this directory.
3. Execute 'npm install' to fetch any dependencies.
3. Execute ```npm install``` to fetch any dependencies.
4. Run the audit script by executing 'node run'.
Description: Run the script through Node.js and view the output.
4. Run the audit script by executing ```node run```.
Note: If you'd like to store the report, run 'node run > report.txt'.
Note description: It's possible to write the console output to a file.
**Note:** If you'd like to save the report, run ```node run > report.txt```.
\ No newline at end of file
{
"name": "decentraleyes-audit",
"version": "1.5.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"source-map-url": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
}
}
}
{
"name": "decentraleyes-audit",
"version": "1.4.0",
"version": "1.5.0",
"author": "Thomas Rientjes",
"license": "MPL-2.0",
"description": "Library audit tool for Decentraleyes.",
......
......@@ -15,12 +15,11 @@
* Imports
*/
var fileSystem, crypto, http, path, sourceMappingURL;
var fileSystem, crypto, https, sourceMappingURL;
fileSystem = require('fs');
crypto = require('crypto');
https = require('https');
path = require('path');
sourceMappingURL = require('source-map-url');
......@@ -31,21 +30,18 @@ sourceMappingURL = require('source-map-url');
var localResourceLocation = '../resources';
var localResourceLocationLength = localResourceLocation.length;
var localResourcePaths = [];
var comparedResourceAmount = 0;
var resourceAmount = 0;
/**
* Functions
*/
function _fetchLocalResourcePaths(folderPath) {
function _fetchLocalResourcePaths (folderPath) {
fileSystem.readdirSync(folderPath).forEach(function (resourceName) {
if (resourceName === '_audit') {
return localResourcePaths;
}
var resourcePath = folderPath + '/' + resourceName;
var resourcePath = `${folderPath}/${resourceName}`;
var resourceStatistics = fileSystem.statSync(resourcePath);
if (resourceStatistics && resourceStatistics.isDirectory()) {
......@@ -59,7 +55,7 @@ function _fetchLocalResourcePaths(folderPath) {
return localResourcePaths;
}
function _getLocalResourceContents(fileLocation, callback) {
function _getLocalResourceContents (fileLocation, callback) {
fileSystem.exists(fileLocation, function (exists) {
......@@ -75,7 +71,7 @@ function _getLocalResourceContents(fileLocation, callback) {
var localFileContents = buffer.toString('utf8', 0, buffer.length);
fileSystem.close(fileDescriptor);
fileSystem.close(fileDescriptor, function () {});
callback(localFileContents);
});
});
......@@ -85,16 +81,16 @@ function _getLocalResourceContents(fileLocation, callback) {
});
}
function _getRemoteResourceContents(remoteResourceRoute, callback) {
function _getRemoteResourceContents (remoteResourceRoute, callback) {
var resourceURL = 'https://ajax.googleapis.com/ajax/libs/' + remoteResourceRoute;
var resourceURL = `https://ajax.googleapis.com/ajax/libs/${remoteResourceRoute}`;
https.get(resourceURL, function (response) {
var resourceContents = '';
response.on('data', function (chunk) {
resourceContents = resourceContents + chunk;
resourceContents += chunk;
});
response.on('end', function () {
......@@ -105,20 +101,20 @@ function _getRemoteResourceContents(remoteResourceRoute, callback) {
} else {
resourceURL = 'https://cdnjs.cloudflare.com/ajax/libs/' + remoteResourceRoute;
resourceURL = `https://cdnjs.cloudflare.com/ajax/libs/${remoteResourceRoute}`;
https.get(resourceURL, function (response) {
resourceContents = '';
response.on('data', function (chunk) {
resourceContents = resourceContents + chunk;
resourceContents += chunk;
});
response.on('end', function () {
if (response.statusCode !== 200) {
throw 'Error: Resource ' + remoteResourceRoute + ' could not be fetched.';
throw `Error: Resource ${remoteResourceRoute} could not be fetched.`;
}
callback(resourceContents, resourceURL);
......@@ -133,7 +129,7 @@ function _getRemoteResourceContents(remoteResourceRoute, callback) {
});
}
function _hashFileContents(fileContents) {
function _hashFileContents (fileContents) {
var hash;
......@@ -146,7 +142,27 @@ function _hashFileContents(fileContents) {
return hash.read();
}
function _compareResources(localResourceContents, remoteResourceContents, URL) {
function _showCompletedMessage () {
console.log();
console.log(' *** FILE INTEGRITY CHECKS COMPLETED');
console.log(` *** ${resourceAmount}/${resourceAmount} RESOURCES WERE ANALYZED`);
console.log();
}
function _incrementComparedResourceAmount () {
comparedResourceAmount++;
if (comparedResourceAmount === resourceAmount) {
setTimeout(function () {
_showCompletedMessage();
}, 500);
}
}
function _compareResources (localResourceContents, remoteResourceContents, URL) {
var hasSourceMappingURL = sourceMappingURL.existsIn(remoteResourceContents);
var sourceMappingNotice = '[ ] REMOTE RESOURCE HAD SOURCE MAPPING URL';
......@@ -156,14 +172,11 @@ function _compareResources(localResourceContents, remoteResourceContents, URL) {
sourceMappingNotice = '[X] REMOTE RESOURCE HAD SOURCE MAPPING URL';
}
// Remove the syntax invalidation character from the local contents.
localResourceContents = localResourceContents.substring(1);
var localResourceHash = _hashFileContents(localResourceContents);
var remoteResourceHash = _hashFileContents(remoteResourceContents);
console.log('RESOURCE HASH (SHA512): ' + localResourceHash);
console.log('RESOURCE HASH (SHA512): ' + remoteResourceHash);
console.log(`RESOURCE HASH (SHA512): ${localResourceHash}`);
console.log(`RESOURCE HASH (SHA512): ${remoteResourceHash}`);
var fileHashesMatch = (localResourceHash === remoteResourceHash);
......@@ -176,14 +189,8 @@ function _compareResources(localResourceContents, remoteResourceContents, URL) {
console.log();
console.log('[X] LOCAL AND REMOTE RESOURCE HASHES MATCH');
console.log(sourceMappingNotice);
}
function _showCompletedMessage() {
console.log();
console.log(' *** FILE INTEGRITY CHECKS COMPLETED');
console.log(' *** ' + resourceAmount + '/' + resourceAmount + ' RESOURCES WERE ANALYZED');
console.log();
_incrementComparedResourceAmount();
}
/**
......@@ -197,7 +204,7 @@ resourceAmount = localResourcePaths.length;
* Script
*/
localResourcePaths.forEach(function (resourcePath, index) {
localResourcePaths.forEach(function (resourcePath) {
var resourceRoute = resourcePath.substr(localResourceLocationLength + 1);
resourceRoute = resourceRoute.substring(0, resourceRoute.length - 4);
......@@ -215,13 +222,6 @@ localResourcePaths.forEach(function (resourcePath, index) {
console.log();
console.log('------------------------------------------');
if (index === resourceAmount - 1) {
setTimeout(function () {
_showCompletedMessage();
}, 500);
}
});
});
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment