Skip to content

Commit

Permalink
Merge pull request #2 from rapid7/abuseipdb
Browse files Browse the repository at this point in the history
AbuseIPDB 3.0.1: Improved error handling
  • Loading branch information
jschipp-r7 authored Jun 5, 2019
2 parents 197e004 + 9ea6ab7 commit d004233
Show file tree
Hide file tree
Showing 19 changed files with 131 additions and 206 deletions.
23 changes: 15 additions & 8 deletions abuseipdb/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
FROM komand/python-pypy3-plugin:2
FROM komand/python-3-37-slim-plugin:3
# Refer to the following documentation for available SDK parent images: https://komand.github.io/python/sdk.html#version

LABEL organization=komand
LABEL sdk=python
LABEL type=plugin

ENV SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt
ENV SSL_CERT_DIR /etc/ssl/certs
ENV REQUESTS_CA_BUNDLE /etc/ssl/certs/ca-certificates.crt
# Add any custom package dependencies here
# NOTE: Add pip packages to requirements.txt

ADD ./plugin.spec.yaml /plugin.spec.yaml
ADD . /python/src
# End package dependencies

# Add source code
WORKDIR /python/src
# Add any package dependencies here
ADD ./plugin.spec.yaml /plugin.spec.yaml
ADD . /python/src

# End package dependencies
# Install pip dependencies
RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

# Install plugin
RUN python setup.py build && python setup.py install

# User to run plugin code. The two supported users are: root, nobody
USER nobody

ENTRYPOINT ["/usr/local/bin/komand_abuseipdb"]
2 changes: 1 addition & 1 deletion abuseipdb/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ export: image

# Make will not run a target if a file of the same name exists unless setting phony targets
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
.PHONY: default tarball image regenerate
.PHONY: default tarball image regenerate
2 changes: 1 addition & 1 deletion abuseipdb/bin/komand_abuseipdb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ from komand_abuseipdb import connection, actions, triggers

Name = 'AbuseIPDB'
Vendor = 'rapid7'
Version = '3.0.0'
Version = '3.0.1'
Description = 'AbuseIPDB is a free service which allows you to look up IP reports, or report an abusive IP'


Expand Down
1 change: 1 addition & 0 deletions abuseipdb/help.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ There's a rate limit on the free API service. The following error messags `429 C
* 1.0.0 - Initial plugin
* 2.0.0 - Add `found` output to Check IP action | Support new credential type
* 3.0.0 - Support new credential_secret_key type
* 3.0.1 - Improve error handling in the Check IP, Check CIDR, and Report IP actions | Update to use the `komand/python-3-37-slim-plugin` Docker image to reduce plugin size | Run plugin as least privileged user | Add connection test

## Workflows

Expand Down
36 changes: 6 additions & 30 deletions abuseipdb/komand_abuseipdb/actions/check_cidr/action.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import komand
from .schema import CheckCidrInput, CheckCidrOutput
# Custom imports below
from komand.exceptions import PluginException
import json
import requests
import logging
logging.getLogger('requests').setLevel(logging.WARNING)
Expand All @@ -27,6 +29,9 @@ def run(self, params={}):
r = requests.get(url)
# Not using r.raise_for_status() since we get useful JSON information on an API 4**
out = r.json()
except json.decoder.JSONDecodeError:
raise PluginException(cause='Received an unexpected response from AbuseIPDB.',
assistance="(non-JSON or no response was received). Response was: %s" % r.text)
except Exception as e:
self.logger.error(e)
raise
Expand All @@ -37,36 +42,7 @@ def run(self, params={}):
if isinstance(error, dict):
if error['id']:
msg = '{}: {}: {}'.format(error.get('id'), error.get('title'), error.get('detail'))
self.logger.error(msg)
return error
except KeyError:
# All good, no error because 'id' key is not present
self.logger.info('No errors')

return out

def test(self):
try:
url = '{base}/{endpoint}/json?key={key}&network=207.126.144.0/20&days=30'.format(
base=self.connection.base,
endpoint='check-block',
key=self.connection.api_key,
)
r = requests.get(url)
# Not using r.raise_for_status() since we get useful JSON information on an API 4**
out = r.json()
except Exception as e:
self.logger.error(e)
raise

try:
if isinstance(out, list):
error = out[0]
if isinstance(error, dict):
if error['id']:
msg = '{}: {}: {}'.format(error.get('id'), error.get('title'), error.get('detail'))
self.logger.error(msg)
return error
raise PluginException(cause='Received an error response from AbuseIPDB.', assistance=msg)
except KeyError:
# All good, no error because 'id' key is not present
self.logger.info('No errors')
Expand Down
4 changes: 4 additions & 0 deletions abuseipdb/komand_abuseipdb/actions/check_cidr/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import json


class Component:
DESCRIPTION = "Look up a CIDR address in the database"


class Input:
CIDR = "cidr"
DAYS = "days"
Expand Down
39 changes: 6 additions & 33 deletions abuseipdb/komand_abuseipdb/actions/check_ip/action.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import komand
from .schema import CheckIpInput, CheckIpOutput
# Custom imports below
from komand.exceptions import PluginException
import json
import requests
import logging
logging.getLogger('requests').setLevel(logging.WARNING)
Expand Down Expand Up @@ -33,6 +35,9 @@ def run(self, params={}):
r = requests.get(url)
# Not using r.raise_for_status() since we get useful JSON information on an API 4**
out = r.json()
except json.decoder.JSONDecodeError:
raise PluginException(cause='Received an unexpected response from AbuseIPDB.',
assistance="(non-JSON or no response was received). Response was: %s" % r.text)
except Exception as e:
self.logger.error(e)
raise
Expand All @@ -50,8 +55,7 @@ def run(self, params={}):
# If the id key is present, an error has occurred
if error['id']:
msg = '{}: {}: {}'.format(error.get('id'), error.get('title'), error.get('detail'))
self.logger.error(msg)
return error
raise PluginException(cause='Received an error response from AbuseIPDB.', assistance=msg)
# UnboundLocalError is raised if variable error is not set
# Error will not be set if out[0] doesn't exist per the catching of the IndexError exception above
except UnboundLocalError:
Expand All @@ -67,34 +71,3 @@ def run(self, params={}):
found = False

return { 'list': out, 'found': found }

def test(self):
try:
# https://www.abuseipdb.com/check/[IP]/json?key=[API_KEY]&days=[DAYS][&verbose]
url = '{base}/{endpoint}/{ip}/json?key={key}&days={days}'.format(
base=self.connection.base,
endpoint='check',
ip='8.8.8.8',
key=self.connection.api_key,
days='30'
)
r = requests.get(url)
# Not using r.raise_for_status() since we get useful JSON information on an API 4**
out = r.json()
except Exception as e:
self.logger.error(e)
raise

try:
if isinstance(out, list):
error = out[0]
if isinstance(error, dict):
if error['id']:
msg = '{}: {}: {}'.format(error.get('id'), error.get('title'), error.get('detail'))
self.logger.error(msg)
return error
except KeyError:
# All good, no error because 'id' key is not present
self.logger.info('No errors')

return { 'list': out, 'found': True }
4 changes: 4 additions & 0 deletions abuseipdb/komand_abuseipdb/actions/check_ip/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import json


class Component:
DESCRIPTION = "Look up an IP address in the database"


class Input:
ADDRESS = "address"
DAYS = "days"
Expand Down
39 changes: 3 additions & 36 deletions abuseipdb/komand_abuseipdb/actions/report_ip/action.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import komand
from .schema import ReportIpInput, ReportIpOutput
# Custom imports below
from komand.exceptions import PluginException
import json
import requests
import logging
logging.getLogger('requests').setLevel(logging.WARNING)
Expand Down Expand Up @@ -30,7 +32,6 @@ def run(self, params={}):
if comment:
if len(comment) > 0:
# Comment provided
self.logger.info('Adding comment')
url = '{}&comment={}'.format(url, comment)

r = requests.get(url)
Expand All @@ -41,46 +42,12 @@ def run(self, params={}):
raise

try:
self.logger.info(out)
if isinstance(out, list):
error = out[0]
if isinstance(error, dict):
if error['id']:
msg = '{}: {}: {}'.format(error.get('id'), error.get('title'), error.get('detail'))
self.logger.error(msg)
return error
except KeyError:
# All good, no error because 'id' key is not present
self.logger.info('No errors')

return out

def test(self):
try:
url = '{base}/{endpoint}/json?key={key}&category={category}&ip={ip}'.format(
base=self.connection.base,
endpoint='report',
key=self.connection.api_key,
category=10,
# Should return an API error without raising an exception as we don't want to taint the database with false reporting
ip='1.2.3.4',
)
r = requests.get(url)
# Not using r.raise_for_status() since we get useful JSON information on an API 4**
out = r.json()
except Exception as e:
self.logger.error(e)
raise

try:
self.logger.info(out)
if isinstance(out, list):
error = out[0]
if isinstance(error, dict):
if error['id']:
msg = '{}: {}: {}'.format(error.get('id'), error.get('title'), error.get('detail'))
self.logger.error(msg)
return error
raise PluginException(cause='Received an error response from AbuseIPDB.', assistance=msg)
except KeyError:
# All good, no error because 'id' key is not present
self.logger.info('No errors')
Expand Down
4 changes: 4 additions & 0 deletions abuseipdb/komand_abuseipdb/actions/report_ip/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import json


class Component:
DESCRIPTION = "Report an abusive IP address"


class Input:
ADDRESS = "address"
CATEGORIES = "categories"
Expand Down
19 changes: 19 additions & 0 deletions abuseipdb/komand_abuseipdb/connection/connection.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import komand
from .schema import ConnectionSchema
# Custom imports below
from komand.exceptions import ConnectionTestException
import json
import requests


class Connection(komand.Connection):
Expand All @@ -13,3 +16,19 @@ def connect(self, params):
self.base = 'https://www.abuseipdb.com'

self.logger.info('Connect: Connecting to %s...' % self.base)

def test(self):
# Use private IP Addresses for testing the API (e.g. 127.0.0.1) from https://www.abuseipdb.com/api
url = 'https://www.abuseipdb.com/check/127.0.0.1/json'
try:
r = requests.get(url)
json_ = r.json()
except json.decoder.JSONDecodeError:
raise ConnectionTestException(cause='Received an unexpected response from AbuseIPDB.',
assistance="(non-JSON or no response was received). Response was: %s" % r.text)
except Exception as e:
self.logger.error(e)
raise

#return { 'list': out, 'found': True }
return json_
4 changes: 2 additions & 2 deletions abuseipdb/plugin.spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: abuseipdb
title: AbuseIPDB
description: AbuseIPDB is a free service which allows you to look up IP reports, or
report an abusive IP
version: 3.0.0
version: 3.0.1
vendor: rapid7
status: ["unsupported"]
status: ["supported"]
tags:
- ip
- intelligence
Expand Down
2 changes: 1 addition & 1 deletion abuseipdb/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@


setup(name='abuseipdb-rapid7-plugin',
version='3.0.0',
version='3.0.1',
description='AbuseIPDB is a free service which allows you to look up IP reports, or report an abusive IP',
author='rapid7',
author_email='',
Expand Down
25 changes: 10 additions & 15 deletions abuseipdb/tests/check_cidr.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
{
"body": {
"action": "check_cidr",
"meta": {},
"input": {
"cidr": "207.126.144.0/20",
"days": "30"
"body": {
"action": "check_cidr",
"input": {
"cidr": "207.126.144.0/20",
"days": "30"
},
"meta": {}
},
"connection": {
"credentials": {
"secretKey": ""
}
}
},
"type": "action_start",
"version": "v1"
}
"type": "action_start",
"version": "v1"
}
25 changes: 10 additions & 15 deletions abuseipdb/tests/check_cidr_error.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
{
"body": {
"action": "check_cidr",
"meta": {},
"input": {
"cidr": "1/20",
"days": "30"
"body": {
"action": "check_cidr",
"input": {
"cidr": "1/20",
"days": "30"
},
"meta": {}
},
"connection": {
"credentials": {
"secretKey": ""
}
}
},
"type": "action_start",
"version": "v1"
}
"type": "action_start",
"version": "v1"
}
Loading

0 comments on commit d004233

Please sign in to comment.