Skip to content
This repository has been archived by the owner on Aug 10, 2024. It is now read-only.

Commit

Permalink
Add AzWebAppHttpsEvent plugin
Browse files Browse the repository at this point in the history
The plugin `AzWebAppHttpsEvent` identifies an Azure web app with HTTPS
only traffic disabled. This plugin works on the web apps config
properties found in the `ext` bucket of `web_app_config` records.

Enabling HTTPS-only traffic will redirect all non-secure HTTP request to
HTTPS.HTTPS uses the SSL/TLS protocol to provide a secure connection.
  • Loading branch information
mitprasoon committed Mar 2, 2020
1 parent 36c4179 commit 2899c49
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 0 deletions.
1 change: 1 addition & 0 deletions cloudmarker/clouds/azwebapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ def _process_app_config(app_index, app, app_config,
'ext': {
'cloud_type': 'azure',
'record_type': 'web_app_config',
'https_only': app.get('https_only'),
'min_tls_version': app_config.get('min_tls_version'),
'subscription_id': sub.get('subscription_id'),
'subscription_name': sub.get('display_name'),
Expand Down
99 changes: 99 additions & 0 deletions cloudmarker/events/azwebapphttpsevent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"""Microsoft web app HTTPS event.
This module defines the :class:`AzWebAppHttpsEvent` class that identifies
a web app with HTTPS only traffic disabled. This plugin works on the web
apps config properties found in the ``ext`` bucket of ``web_app_config``
records.
"""


import logging

from cloudmarker import util

_log = logging.getLogger(__name__)


class AzWebAppHttpsEvent:
"""Azure web app HTTPS event plugin."""

def __init__(self):
"""Create an instance of :class:`AzWebAppHttpsEvent`."""

def eval(self, record):
"""Evaluate Azure web app to check for HTTPS only config.
Arguments:
record (dict): A web app record.
Yields:
dict: An event record representing a web app with HTTPS
only traffic disabled.
"""
com = record.get('com', {})
if com is None:
return

if com.get('cloud_type') != 'azure':
return

ext = record.get('ext', {})
if ext is None:
return

if ext.get('record_type') != 'web_app_config':
return

if ext.get('https_only'):
return

yield from _get_azure_web_app_https_event(com, ext)

def done(self):
"""Perform cleanup work.
Currently, this method does nothing. This may change in future.
"""


def _get_azure_web_app_https_event(com, ext):
"""Generate Web App HTTPS event.
Arguments:
com (dict): Azure web app record `com` bucket.
ext (dict): Azure web app record `ext` bucket.
Returns:
dict: An event record representing web apps not using
HTTPS only traffic.
"""
friendly_cloud_type = util.friendly_string(com.get('cloud_type'))
reference = com.get('reference')
description = (
'{} web app {} has HTTPS only traffic disabled.'
.format(friendly_cloud_type, reference)
)
recommendation = (
'Check {} web app {} and enable HTTPS only traffic.'
.format(friendly_cloud_type, reference)
)

event_record = {
# Preserve the extended properties from the web app
# record because they provide useful context to
# locate the web app that led to the event.
'ext': util.merge_dicts(ext, {
'record_type': 'web_app_https_event'
}),
'com': {
'cloud_type': com.get('cloud_type'),
'record_type': 'web_app_https_event',
'reference': reference,
'description': description,
'recommendation': recommendation,
}
}
_log.info('Generating web_app_https_event; %r', event_record)
yield event_record
68 changes: 68 additions & 0 deletions cloudmarker/test/test_azwebapphttpsevent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""Tests for AzWebAppHttpsEvent plugin."""


import copy
import unittest

from cloudmarker.events import azwebapphttpsevent

base_record = {
'ext': {
'record_type': 'web_app_config',
'cloud_type': 'azure',
'https_only': True
},
'com': {
'cloud_type': 'azure'
}
}


class AzWebAppHttpsEventTest(unittest.TestCase):
"""Tests for AzWebAppHttpsEvent plugin."""

def test_com_bucket_missing(self):
record = copy.deepcopy(base_record)
record['com'] = None
plugin = azwebapphttpsevent.AzWebAppHttpsEvent()
events = list(plugin.eval(record))
self.assertEqual(events, [])

def test_cloud_type_non_azure(self):
record = copy.deepcopy(base_record)
record['com']['cloud_type'] = 'non_azure'
plugin = azwebapphttpsevent.AzWebAppHttpsEvent()
events = list(plugin.eval(record))
self.assertEqual(events, [])

def test_ext_bucket_missing(self):
record = copy.deepcopy(base_record)
record['ext'] = None
plugin = azwebapphttpsevent.AzWebAppHttpsEvent()
events = list(plugin.eval(record))
self.assertEqual(events, [])

def test_record_type_non_web_app_config(self):
record = copy.deepcopy(base_record)
record['ext']['record_type'] = 'non_web_app_config'
plugin = azwebapphttpsevent.AzWebAppHttpsEvent()
events = list(plugin.eval(record))
self.assertEqual(events, [])

def test_https_only(self):
record = copy.deepcopy(base_record)
record['ext']['https_only'] = True
plugin = azwebapphttpsevent.AzWebAppHttpsEvent()
events = list(plugin.eval(record))
self.assertEqual(events, [])

def test_not_https_only(self):
record = copy.deepcopy(base_record)
record['ext']['https_only'] = False
plugin = azwebapphttpsevent.AzWebAppHttpsEvent()
events = list(plugin.eval(record))
self.assertEqual(len(events), 1)
self.assertEqual(events[0]['ext']['record_type'],
'web_app_https_event')
self.assertEqual(events[0]['com']['record_type'],
'web_app_https_event')
4 changes: 4 additions & 0 deletions pylama.ini
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,7 @@ ignore = R0201

# R0201 Method could be a function [pylint]

[pylama:cloudmarker/events/azwebapphttpsevent.py]
ignore = R0201

# R0201 Method could be a function [pylint]

0 comments on commit 2899c49

Please sign in to comment.