Skip to content

Commit

Permalink
Finish 1.0.0-beta
Browse files Browse the repository at this point in the history
  • Loading branch information
sarus committed Mar 16, 2018
2 parents aacf1b5 + ec56ac3 commit 441d662
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 54 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ Minimum threat score necessary to display a matching entry (does not apply to ma

Minimum risk level necessary to display a matching entry (only applies to malware entities).

## Installation Instructions

Installation instructions for integrations are provided on the [PolarityIO GitHub Page](https://polarityio.github.io/).

## Polarity

Expand Down
16 changes: 8 additions & 8 deletions config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,23 @@ module.exports = {
},
request: {
// Provide the path to your certFile. Leave an empty string to ignore this option.
// Relative paths are relative to the STAXX integration's root directory
// Relative paths are relative to the x-force-exchange integration's root directory
cert: '',
// Provide the path to your private key. Leave an empty string to ignore this option.
// Relative paths are relative to the STAXX integration's root directory
// Relative paths are relative to the x-force-exchange integration's root directory
key: '',
// Provide the key passphrase if required. Leave an empty string to ignore this option.
// Relative paths are relative to the STAXX integration's root directory
// Relative paths are relative to the x-force-exchange integration's root directory
passphrase: '',
// Provide the Certificate Authority. Leave an empty string to ignore this option.
// Relative paths are relative to the STAXX integration's root directory
// Relative paths are relative to the x-force-exchange integration's root directory
ca: '',
// An HTTP proxy to be used. Supports proxy Auth with Basic Auth, identical to support for
// the url parameter (by embedding the auth info in the uri)
proxy: '',
/**
* If set to false, the integeration will ignore SSL errors. This will allow the integration to connect
* to STAXX servers without valid SSL certificates. Please note that we do NOT recommending setting this
* to the x-force-exchange without valid SSL certificates. Please note that we do NOT recommending setting this
* to false in a production environment.
*/
rejectUnauthorized: true
Expand All @@ -90,7 +90,7 @@ module.exports = {
// the directory you specify is writable by the `polarityd:polarityd` user and group.

//directoryPath: '/var/log/polarity-integrations',
level: 'trace', //trace, debug, info, warn, error, fatal
level: 'info', //trace, debug, info, warn, error, fatal
},
/**
* Options that are displayed to the user/admin in the Polarity integration user-interface. Should be structured
Expand Down Expand Up @@ -130,7 +130,7 @@ module.exports = {
{
key: "minimumScore",
name: "Minimum Score",
description: "Minimum threat score necessary to display a matching entry (does not apply to malware entities).",
description: "Minimum risk score necessary to display a matching entry (does not apply to malware entities).",
default: 0,
type: "number",
userCanEdit: false,
Expand All @@ -139,7 +139,7 @@ module.exports = {
{
key: "minimumRisk",
name: "Minimum Malware Risk",
description: "Minimum risk level necessary to display a matching entry (only applies to malware entities).",
description: 'Minimum risk level necessary to display a matching entry (only applies to malware entities). Valid values are "low", "medium", and "high"',
default: "medium",
type: "text",
userCanEdit: false,
Expand Down
99 changes: 63 additions & 36 deletions integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ let Transformer = require('./transformer');

let transformer;
let Logger;
let requestOptions = {
json: true
};
let requestWithDefaults;


const risk = {
'high': 3,
Expand All @@ -16,31 +15,33 @@ const risk = {
'': 0
};

const DATA_TYPE_ERROR = 'if this error occures it means you added data ' +
const DATA_TYPE_ERROR = 'if this error occurs it means you added data ' +
'types in config.js without updating the code in integration.js';

function getRequestOptions(options) {
let opts = JSON.parse(JSON.stringify(requestOptions));
opts.auth = {
user: options.apikey,
password: options.password
};

return opts;
}

function doLookup(entities, options, callback) {
Logger.trace({ entities: entities, options: options }, 'Entities received');
Logger.trace({entities: entities, options: options}, 'Entities received');

let results = [];
let minimumScore = options.minimumScore;
let minimumRisk = options.minimumRisk;

Logger.trace({ minimumScore: minimumScore, minimumRisk: minimumRisk });
Logger.trace({minimumScore: minimumScore, minimumRisk: minimumRisk});

async.each(entities, (entity, done) => {
Logger.trace({ entity: entity }, 'Looking up entity in x-force exchange');
let requestOptions = getRequestOptions(options);
Logger.trace({entity: entity}, 'Looking up entity in x-force exchange');

// x-force only seems to like URLs that start with http or https
if(entity.isURL && !_isValidUrl(entity.value)){
done(null);
return;
}

let requestOptions = {
auth: {
user: options.apikey,
password: options.password
}
};

if (entity.isIP) {
requestOptions.url = options.host + '/ipr/' + entity.value;
Expand All @@ -49,38 +50,51 @@ function doLookup(entities, options, callback) {
} else if (entity.isHash) {
requestOptions.url = options.host + '/malware/' + entity.value;
} else {
Logger.error({ entity: entity }, DATA_TYPE_ERROR);
Logger.error({entity: entity}, DATA_TYPE_ERROR);
throw new Error(DATA_TYPE_ERROR);
}

request(requestOptions, function (err, resp, body) {
Logger.trace({ error: err, body: body }, 'Results of lookup');
requestWithDefaults(requestOptions, function (err, resp, body) {
Logger.trace({error: err, body: body}, 'Results of lookup');

if (err) {
done(err);
done({
detail: 'Error executing HTTPS request',
debug: err
});
return;
}

if (resp.statusCode !== 200) {
if (resp.statusCode === 404) {
Logger.trace({ id: entity.value }, 'Entity not in x-force exhange');
Logger.trace({id: entity.value}, 'Entity not in x-force exhange');
results.push({
entity: entity,
data: null
});
done();
} else if (resp.statusCode === 400) {
Logger.error({error: body}, 'Bad Request');
done({
detail: 'Unexpected HTTP Status Code Received',
debug: body,
entityValue: entity.value
});
} else {
Logger.error({ error: body }, 'Error looking up entity in x-force exchange');
done(body);
Logger.error({error: body}, 'Error looking up entity in x-force exchange');
done({
detail: 'Unexpected HTTP Status Code Received',
debug: body,
response: resp
});
}

return;
}

if (entity.isHash) {
let riskLevel = body.malware.risk;

Logger.trace({ risk: riskLevel, minimumRisk: minimumRisk }, 'Checking minimum score');
Logger.trace({risk: riskLevel, minimumRisk: minimumRisk}, 'Checking minimum score');

if (risk[riskLevel] < risk[minimumRisk]) {
done();
Expand All @@ -89,7 +103,7 @@ function doLookup(entities, options, callback) {
} else {
let score = body.score ? body.score : (body.result ? body.result.score : body.score);

Logger.trace({ score: score, minimumScore: minimumScore }, 'Checking minimum score');
Logger.trace({score: score, minimumScore: minimumScore}, 'Checking minimum score');

if (score < minimumScore) {
done();
Expand All @@ -105,45 +119,58 @@ function doLookup(entities, options, callback) {
}
};

Logger.trace({ result: result }, 'Result added to list');
Logger.trace({result: result}, 'Result added to list');

results.push(result);

done();
});
}, (err) => {
Logger.trace({ results: results }, 'All entity lookups completed, returning results to client');
Logger.trace({results: results}, 'All entity lookups completed, returning results to client');
callback(err, results);
});
}

// x-force only seems to accept URLs that start with http or https
function _isValidUrl(url){
if(url.startsWith('http') || url.startsWith('https')){
return true;
}
return false;
}

function startup(logger) {
Logger = logger;
transformer = new Transformer(logger);
let defaults = {};

if (typeof config.request.cert === 'string' && config.request.cert.length > 0) {
requestOptions.cert = fs.readFileSync(config.request.cert);
defaults.cert = fs.readFileSync(config.request.cert);
}

if (typeof config.request.key === 'string' && config.request.key.length > 0) {
requestOptions.key = fs.readFileSync(config.request.key);
defaults.key = fs.readFileSync(config.request.key);
}

if (typeof config.request.passphrase === 'string' && config.request.passphrase.length > 0) {
requestOptions.passphrase = config.request.passphrase;
defaults.passphrase = config.request.passphrase;
}

if (typeof config.request.ca === 'string' && config.request.ca.length > 0) {
requestOptions.ca = fs.readFileSync(config.request.ca);
defaults.ca = fs.readFileSync(config.request.ca);
}

if (typeof config.request.proxy === 'string' && config.request.proxy.length > 0) {
requestOptions.proxy = config.request.proxy;
defaults.proxy = config.request.proxy;
}

if (typeof config.request.rejectUnauthorized === 'boolean') {
requestOptions.rejectUnauthorized = config.request.rejectUnauthorized;
defaults.rejectUnauthorized = config.request.rejectUnauthorized;
}

defaults.json = true;

requestWithDefaults = request.defaults(defaults);
}

function validateStringOption(errors, options, optionName, errMessage) {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"license": "MIT",
"author": "Polarity",
"dependencies": {
"request": "^2.75",
"async": "2.1.4"
"request": "^2.85",
"async": "2.6.0"
},
"devDependencies": {
"chai": "~3.5",
Expand Down
9 changes: 3 additions & 6 deletions templates/x-force-exchange-block.hbs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
<div class="details-container">
<div class="item">
<p>
<a href="{{details.link}}">View in X-Force Exchange</a>
</p>
{{#each details.titledProperties as |prop|}}
<p>
{{prop.key}}:
<b>{{prop.value}}</b>
</p>
{{/each}}

<p>
<a href="{{details.link}}">View in X-Force Exchange</a>
</p>

{{#each details.headerLists as |list|}}
<h5>
<i class="bts bt-fw bt-label h5"></i> {{list.header}}
Expand All @@ -30,7 +28,6 @@
</span>
{{/each}}
</div>

<div style="clear:both; margin-bottom: 5px;"></div>
</div>
</div>
4 changes: 2 additions & 2 deletions transformer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ module.exports = class Transformer {
this.logger.trace({ ip: entity.value, body: body }, 'Transforming body to result');

if (entity.isIP) {
details.addTitledProperty('Score', body.score);
details.addSummary(body.score)
details.addTitledProperty('Risk Score', body.score);
details.addSummary(body.score);
details.addTitledProperty('Reason', body.reason);

if (body.geo) {
Expand Down

0 comments on commit 441d662

Please sign in to comment.