├── .coveragerc ├── .dockerignore ├── .gitignore ├── .travis.yml ├── .venv ├── AUTHORS ├── Dockerfile ├── LICENSE ├── OSSMETADATA ├── README.md ├── config-default.py ├── dart ├── .gitignore ├── lib │ ├── component │ │ ├── account_pattern_audit_score_view_component │ │ │ ├── account_pattern_audit_score_view_component.dart │ │ │ └── account_pattern_audit_score_view_component.html │ │ ├── account_view_component │ │ │ ├── account_view_component.dart │ │ │ └── account_view_component.html │ │ ├── auditscore_view_component │ │ │ ├── auditscore_view_component.dart │ │ │ └── auditscore_view_component.html │ │ ├── compare_item_revisions │ │ │ ├── compare_item_revisions.dart │ │ │ └── compare_item_revisions.html │ │ ├── dashboard_component │ │ │ ├── dashboard_component.dart │ │ │ └── dashboard_component.html │ │ ├── ignore_entry_component │ │ │ ├── ignore_entry_component.dart │ │ │ └── ignore_entry_component.html │ │ ├── issue_table_component │ │ │ ├── issue_table_component.dart │ │ │ └── issue_table_component.html │ │ ├── item_table_component │ │ │ ├── item_table_component.dart │ │ │ └── item_table_component.html │ │ ├── itemdetails │ │ │ ├── itemdetails.html │ │ │ └── itemdetails_component.dart │ │ ├── justified_table_component │ │ │ ├── justified_table_component.dart │ │ │ └── justified_table_component.html │ │ ├── modal_justify_issues │ │ │ ├── modal_justify_issues.dart │ │ │ └── modal_justify_issues.html │ │ ├── paginated_table │ │ │ └── paginated_table.dart │ │ ├── revision │ │ │ ├── revision_component.dart │ │ │ └── revision_component.html │ │ ├── revision_table_component │ │ │ ├── revision_table_component.dart │ │ │ └── revision_table_component.html │ │ ├── search_bar_component │ │ │ ├── search_bar_component.dart │ │ │ └── search_bar_component.html │ │ ├── search_page_component │ │ │ ├── search_page_component.dart │ │ │ └── search_page_component.html │ │ ├── settings │ │ │ ├── audit_score_component │ │ │ │ ├── audit_score_component.dart │ │ │ │ └── audit_score_component.html │ │ │ ├── auditor_settings_component │ │ │ │ ├── auditor_settings_component.dart │ │ │ │ └── auditor_settings_component.html │ │ │ ├── ignore_list_component │ │ │ │ ├── ignore_list_component.dart │ │ │ │ └── ignore_list_component.html │ │ │ ├── network_whitelist_component │ │ │ │ ├── network_whitelist_component.dart │ │ │ │ └── network_whitelist_component.html │ │ │ ├── user_role_component │ │ │ │ ├── user_role_component.dart │ │ │ │ └── user_role_component.html │ │ │ └── watcher_config_component │ │ │ │ ├── watcher_config_component.dart │ │ │ │ └── watcher_config_component.html │ │ ├── settings_component │ │ │ ├── settings_component.dart │ │ │ └── settings_component.html │ │ ├── signout_component │ │ │ ├── signout_component.dart │ │ │ └── signout_component.html │ │ ├── username_component │ │ │ ├── username_component.dart │ │ │ └── username_component.html │ │ └── whitelist_view_component │ │ │ ├── whitelist_view_component.dart │ │ │ └── whitelist_view_component.html │ ├── interceptor │ │ └── global_http_interceptor.dart │ ├── model │ │ ├── Account.dart │ │ ├── AccountBulkUpdate.dart │ │ ├── AccountPatternAuditScore.dart │ │ ├── CloudTrail.dart │ │ ├── Issue.dart │ │ ├── Item.dart │ │ ├── ItemComment.dart │ │ ├── ItemLink.dart │ │ ├── Revision.dart │ │ ├── RevisionComment.dart │ │ ├── Role.dart │ │ ├── User.dart │ │ ├── UserSetting.dart │ │ ├── account_config.dart │ │ ├── auditorsetting.dart │ │ ├── auditscore.dart │ │ ├── custom_field_config.dart │ │ ├── hammock_config.dart │ │ ├── ignore_entry.dart │ │ ├── network_whitelist_entry.dart │ │ ├── techmethods.dart │ │ └── watcher_config.dart │ ├── routing │ │ └── securitymonkey_router.dart │ ├── security_monkey.dart │ ├── service │ │ ├── justification_service.dart │ │ ├── messages.dart │ │ └── username_service.dart │ └── util │ │ ├── constants.dart │ │ ├── json_diff.dart │ │ └── utils.dart ├── pubspec.lock ├── pubspec.yaml └── web │ ├── css │ ├── bootstrap-theme.css │ ├── bootstrap-theme.css.map │ ├── bootstrap-theme.min.css │ ├── bootstrap.css │ ├── bootstrap.css.map │ ├── bootstrap.min.css │ ├── main.css │ └── signin.css │ ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff │ ├── ico │ ├── favicon-1.ico │ ├── favicon-2.ico │ └── favicon-3.ico │ ├── images │ ├── close.png │ ├── option_panel.png │ ├── option_panel_blah.png │ ├── securitymonkey.png │ ├── securitymonkey1.png │ └── securitymonkeyHead.png │ ├── js │ ├── bootstrap.js │ ├── bootstrap.min.js │ ├── searchpage.js │ ├── sso.js │ └── styleswitcher.js │ ├── main.dart │ ├── select2-3.4.5 │ ├── LICENSE │ ├── select2-bootstrap.css │ ├── select2-spinner.gif │ ├── select2.css │ ├── select2.jquery.json │ ├── select2.min.js │ ├── select2.png │ └── select2x2.png │ ├── ui.html │ └── views │ ├── account.html │ ├── accountpatternauditscore.html │ ├── auditscore.html │ ├── compare_item_revisions.html │ ├── create_account.html │ ├── create_auditscore.html │ ├── create_ignoreentry.html │ ├── create_whitelist.html │ ├── dashboard.html │ ├── error.html │ ├── ignoreentry.html │ ├── itemdetailsview.html │ ├── searchpage.html │ ├── settings.html │ ├── signout.html │ └── whitelist.html ├── data └── aws_accounts.json ├── docker-compose.init.yml ├── docker-compose.shell.yml ├── docker-compose.yml ├── docker ├── README.md ├── api-init.sh ├── api-start.sh ├── celeryconfig.py ├── nginx │ ├── Dockerfile │ ├── conf.d │ │ └── securitymonkey.conf │ ├── nginx.conf │ └── start-nginx.sh ├── scheduler-start.sh └── worker-start.sh ├── docs ├── api │ ├── index.md │ ├── security_monkey.auditors.md │ ├── security_monkey.common.md │ ├── security_monkey.common.utils.md │ ├── security_monkey.md │ ├── security_monkey.tests.md │ ├── security_monkey.views.md │ └── security_monkey.watchers.md ├── architecture.md ├── autostarting.md ├── changelog.md ├── contributing.md ├── dev_setup_osx.md ├── dev_setup_ubuntu.md ├── dev_setup_windows.md ├── development.md ├── docker.md ├── elasticache_directions.md ├── github_setup.md ├── iam_aws.md ├── iam_gcp.md ├── iam_openstack.md ├── images │ ├── SES_LIMITED.png │ ├── Security_Monkey.png │ ├── add_user_to_service_account.png │ ├── aws_rds.png │ ├── check_score_with_pattern.png │ ├── colored_JSON.png │ ├── create_inline_policy.png │ ├── create_instance_profile.png │ ├── create_pattern_check_score.png │ ├── create_role.png │ ├── create_service_account.png │ ├── created_check_score.png │ ├── disable_check.png │ ├── edit_trust_relationship.png │ ├── empty_create_account_page.png │ ├── empty_settings_page.png │ ├── filtered_search_1.png │ ├── github_scopes.png │ ├── issues_page.png │ ├── item_with_issue.png │ ├── justified_issue.png │ ├── linked_issue.png │ ├── new_cache.png │ ├── new_security_group.png │ ├── override_check_score.png │ ├── override_sg_egress.png │ ├── rds_sg.png │ ├── resized_launch_instance_with_role.png │ ├── resized_launched_sm.png │ ├── resized_login_page-1.png │ ├── resized_register-page-1.png │ ├── resized_role_confirmation.png │ ├── resized_select_ec2_instance.png │ ├── resized_settings_link.png │ ├── resized_ubuntu.png │ ├── revision_comments.png │ ├── search_for_instance_profile.png │ ├── search_results.png │ ├── security_group_devel.png │ ├── security_monkey_roles.png │ ├── securitygroup_details.png │ ├── select_custom_policy.png │ ├── select_role_type.png │ ├── select_roles.png │ ├── ses_elastic_ip.png │ ├── ses_sm_setting.png │ ├── ses_verify_domain.png │ ├── ses_verify_domain_pending.png │ ├── skip_attach_policy.png │ ├── sm_create_role.png │ ├── sm_iam_diagram.png │ ├── sm_iam_diagram.svg │ ├── sm_instance_diagram.png │ └── sm_instance_diagram.svg ├── installation │ ├── 01-launch-instance.md │ ├── 02-create-db.md │ ├── 03-install-sm.md │ ├── 04-accounts.md │ ├── 05-ssl.md │ ├── 06-nginx.md │ └── 07-load-data.md ├── instance_launch_aws.md ├── instance_launch_gcp.md ├── instance_launch_openstack.md ├── issue_template.md ├── jirasync.md ├── misc.md ├── nginx_install.md ├── options.md ├── plugins.md ├── postgres_aws.md ├── postgres_gcp.md ├── quickstart.md ├── troubleshooting.md ├── tuneworkers.md ├── update.md └── userguide.md ├── env-config ├── config-docker.py ├── config-local.py └── config.py ├── env_tests └── test_dart.sh ├── manage.py ├── manage_api.py ├── migrations ├── README ├── alembic.ini ├── env.py ├── script.py.mako └── versions │ ├── 00c1dabdbe85_lengthen_account_name.py │ ├── 0ae4ef82b244_.py │ ├── 11f081cf54e2_.py │ ├── 1583a48cb978_.py │ ├── 15e39d43395f_.py │ ├── 1727fb4309d8_.py │ ├── 1a863bd1acb1_.py │ ├── 1c847ae1209a_.py │ ├── 2705e6e13a8f_.py │ ├── 2ce75615b24d_.py │ ├── 2ea41f4610fd_.py │ ├── 331ca47ce8ad_.py │ ├── 4ac52090a637_.py │ ├── 51170afa2b48_custom_role_name.py │ ├── 538eeb160af6_.py │ ├── 55725cc4bf25_.py │ ├── 57f648d4b597_.py │ ├── 595e27f36454_.py │ ├── 5bd631a1b748_.py │ ├── 61a6fd4b4500_.py │ ├── 6245d75fa12_exceptions_table.py │ ├── 67ea2aac5ea0_.py │ ├── 6b9d673d8e30_added_index_for_itemrevision_created.py │ ├── 6d2354fb841c_.py │ ├── 7c54b06e227b_.py │ ├── 908b0085d28d_.py │ ├── a9fe9c93ed75_.py │ ├── ad23a56abf25_.py │ ├── ae5c0a6aebb3_.py │ ├── b8ccf5b8089b_.py │ ├── bfb550a500ab_.py │ ├── c01df2202a9_.py │ ├── c93f246859f7_.py │ ├── c9dd06c919ac_.py │ ├── d08d0b37788a_.py │ ├── daee17da2abd_.py │ ├── e0a6af364a3f_.py │ ├── ea2739ecd874_.py │ └── fb592c81e71_.py ├── nginx └── security_monkey.conf ├── requirements.txt ├── scripts ├── secmonkey_auto_install.sh └── secmonkey_role_setup.py ├── secmonkey.env ├── security_monkey ├── __init__.py ├── account_manager.py ├── account_managers │ ├── __init__.py │ ├── aws_account.py │ ├── custom │ │ ├── __init__.py │ │ ├── sample_active_directory.py │ │ ├── sample_db_extended_aws.py │ │ └── sample_extended_aws.py │ ├── gcp_account.py │ ├── github_account.py │ └── openstack_account.py ├── alerter.py ├── alerters │ ├── __init__.py │ ├── custom_alerter.py │ └── slack_alerter.py ├── auditor.py ├── auditors │ ├── __init__.py │ ├── acm.py │ ├── cloudtrail.py │ ├── custom │ │ └── __init__.py │ ├── ebs_snapshot.py │ ├── ec2_image.py │ ├── elasticsearch_service.py │ ├── elb.py │ ├── elbv2.py │ ├── gcp │ │ ├── __init__.py │ │ ├── gce │ │ │ ├── __init__.py │ │ │ ├── firewall.py │ │ │ └── network.py │ │ ├── gcs │ │ │ ├── __init__.py │ │ │ └── bucket.py │ │ ├── iam │ │ │ ├── __init__.py │ │ │ └── serviceaccount.py │ │ └── util.py │ ├── github │ │ ├── __init__.py │ │ ├── org.py │ │ ├── repo.py │ │ └── team.py │ ├── glacier.py │ ├── iam │ │ ├── __init__.py │ │ ├── iam_group.py │ │ ├── iam_policy.py │ │ ├── iam_role.py │ │ ├── iam_ssl.py │ │ ├── iam_user.py │ │ └── managed_policy.py │ ├── kms.py │ ├── lambda_function.py │ ├── openstack │ │ ├── __init__.py │ │ ├── openstack_object_container.py │ │ └── openstack_security_group.py │ ├── rds │ │ ├── __init__.py │ │ ├── rds_db_cluster.py │ │ ├── rds_db_instance.py │ │ ├── rds_security_group.py │ │ └── rds_snapshot.py │ ├── redshift.py │ ├── resource_policy_auditor.py │ ├── route53.py │ ├── s3.py │ ├── security_group.py │ ├── ses.py │ ├── sns.py │ ├── sqs.py │ └── vpc │ │ ├── vpc.py │ │ └── vpn.py ├── auth │ ├── __init__.py │ ├── models.py │ └── modules.py ├── backup.py ├── celeryconfig.py ├── cloudaux_batched_watcher.py ├── cloudaux_watcher.py ├── common │ ├── PolicyDiff.py │ ├── __init__.py │ ├── audit_issue_cleanup.py │ ├── gcp │ │ ├── __init__.py │ │ ├── config.py │ │ ├── error.py │ │ └── util.py │ ├── github │ │ ├── __init__.py │ │ └── util.py │ ├── jinja.py │ ├── route53.py │ ├── s3_canonical.py │ ├── sts_connect.py │ └── utils.py ├── constants.py ├── datastore.py ├── datastore_utils.py ├── decorators.py ├── exceptions.py ├── export │ └── __init__.py ├── jirasync.py ├── manage.py ├── migrations │ └── env.py ├── monitors.py ├── reporter.py ├── sso │ ├── __init__.py │ ├── header_auth.py │ ├── service.py │ └── views.py ├── task_scheduler │ ├── __init__.py │ ├── beat.py │ ├── tasks.py │ └── util.py ├── templates │ ├── csrf_error.json │ ├── jinja_audit_email.html │ ├── jinja_change_email.html │ ├── jinja_change_item.html │ └── security │ │ ├── _macros.html │ │ ├── forgot_password.html │ │ ├── login_user.html │ │ ├── register_user.html │ │ ├── reset_password.html │ │ └── send_confirmation.html ├── tests │ ├── __init__.py │ ├── auditors │ │ ├── __init__.py │ │ ├── gcp │ │ │ ├── __init__.py │ │ │ ├── gce │ │ │ │ ├── test_firewall.py │ │ │ │ └── test_network.py │ │ │ ├── gcs │ │ │ │ └── test_bucket.py │ │ │ └── iam │ │ │ │ └── test_serviceaccount.py │ │ ├── github │ │ │ ├── __init__.py │ │ │ ├── test_org_auditor.py │ │ │ ├── test_repo_auditor.py │ │ │ └── test_team_auditor.py │ │ ├── openstack │ │ │ ├── __init__.py │ │ │ └── test_openstack_security_group.py │ │ ├── rds │ │ │ ├── __init__.py │ │ │ ├── test_rds_db_cluster.py │ │ │ ├── test_rds_db_instance.py │ │ │ └── test_rds_snapshot.py │ │ ├── test_elasticsearch_service.py │ │ ├── test_elb.py │ │ ├── test_elbv2.py │ │ ├── test_iam.py │ │ ├── test_kms.py │ │ ├── test_managed_policy.py │ │ ├── test_resource_policy_auditor.py │ │ ├── test_s3.py │ │ ├── test_security_group.py │ │ └── test_sns.py │ ├── core │ │ ├── __init__.py │ │ ├── monitor_mock.py │ │ ├── test_audit_issue_cleanup.py │ │ ├── test_auditor.py │ │ ├── test_backup.py │ │ ├── test_change_finder.py │ │ ├── test_datastore_utils.py │ │ ├── test_exception_logging.py │ │ ├── test_monitors.py │ │ ├── test_policydiff.py │ │ ├── test_sso_service.py │ │ └── test_watcher.py │ ├── interface │ │ ├── __init__.py │ │ └── test_manager.py │ ├── not_used │ │ ├── github │ │ │ ├── __init__.py │ │ │ ├── test_org.py │ │ │ ├── test_repo.py │ │ │ └── test_team.py │ │ ├── openstack │ │ │ ├── __init__.py │ │ │ ├── compute │ │ │ │ ├── __init__.py │ │ │ │ └── test_instance.py │ │ │ ├── network │ │ │ │ ├── __init__.py │ │ │ │ ├── test_floating_ip.py │ │ │ │ ├── test_network.py │ │ │ │ ├── test_port.py │ │ │ │ ├── test_router.py │ │ │ │ ├── test_security_group.py │ │ │ │ └── test_subnet.py │ │ │ └── object_store │ │ │ │ ├── __init__.py │ │ │ │ └── test_object_container.py │ │ └── watchers │ │ │ └── test_lambda_function.py │ ├── scheduling │ │ ├── __init__.py │ │ └── test_celery_scheduler.py │ ├── sso │ │ ├── test_header_auth.py │ │ └── test_okta.py │ ├── utilities │ │ ├── __init__.py │ │ ├── templates │ │ │ └── github_creds │ │ ├── test_account_utils.py │ │ ├── test_github_utils.py │ │ ├── test_s3_canonical.py │ │ ├── test_sync_network.py │ │ └── test_user_utils.py │ ├── views │ │ ├── __init__.py │ │ ├── test_view_item.py │ │ └── test_view_watcher_config.py │ └── watchers │ │ ├── __init__.py │ │ ├── ec2 │ │ ├── __init__.py │ │ ├── test_ebs_snapshot.py │ │ ├── test_ebs_volume.py │ │ ├── test_ec2_image.py │ │ └── test_ec2_instance.py │ │ ├── rds │ │ ├── __init__.py │ │ ├── test_rds_db_instance.py │ │ ├── test_rds_security_group.py │ │ └── test_rds_subnet_group.py │ │ ├── test_iam_role.py │ │ ├── test_route53.py │ │ ├── test_s3.py │ │ └── vpc │ │ ├── __init__.py │ │ ├── test_dhcp.py │ │ ├── test_networkacl.py │ │ ├── test_peering.py │ │ ├── test_route_table.py │ │ └── test_subnet.py ├── views │ ├── __init__.py │ ├── account.py │ ├── account_bulk_update.py │ ├── account_config.py │ ├── account_pattern_audit_score.py │ ├── audit_scores.py │ ├── auditor_settings.py │ ├── distinct.py │ ├── ignore_list.py │ ├── item.py │ ├── item_comment.py │ ├── item_issue.py │ ├── item_issue_justification.py │ ├── logout.py │ ├── revision.py │ ├── revision_comment.py │ ├── tech_methods.py │ ├── user_settings.py │ ├── users.py │ ├── watcher_config.py │ └── whitelist.py ├── watcher.py └── watchers │ ├── __init__.py │ ├── acm.py │ ├── cloud_trail.py │ ├── config.py │ ├── config_recorder.py │ ├── custom │ └── __init__.py │ ├── direct_connect │ ├── __init__.py │ ├── connection.py │ └── virtual_gateway.py │ ├── ec2 │ ├── __init__.py │ ├── ebs_snapshot.py │ ├── ebs_volume.py │ ├── ec2_image.py │ └── ec2_instance.py │ ├── elastic_ip.py │ ├── elasticsearch_service.py │ ├── elb.py │ ├── elbv2.py │ ├── eni.py │ ├── gcp │ ├── __init__.py │ ├── gce │ │ ├── __init__.py │ │ ├── firewall.py │ │ └── network.py │ ├── gcs │ │ ├── __init__.py │ │ └── bucket.py │ └── iam │ │ ├── __init__.py │ │ └── serviceaccount.py │ ├── github │ ├── __init__.py │ ├── org.py │ ├── repo.py │ └── team.py │ ├── glacier.py │ ├── iam │ ├── __init__.py │ ├── iam_group.py │ ├── iam_role.py │ ├── iam_ssl.py │ ├── iam_user.py │ ├── managed_policy.py │ └── saml_provider.py │ ├── keypair.py │ ├── kms.py │ ├── lambda_function.py │ ├── openstack │ ├── __init__.py │ ├── compute │ │ ├── __init__.py │ │ └── openstack_instance.py │ ├── network │ │ ├── __init__.py │ │ ├── openstack_floating_ip.py │ │ ├── openstack_network.py │ │ ├── openstack_port.py │ │ ├── openstack_router.py │ │ ├── openstack_security_group.py │ │ └── openstack_subnet.py │ ├── object_store │ │ ├── __init__.py │ │ └── openstack_object_container.py │ └── openstack_watcher.py │ ├── rds │ ├── __init__.py │ ├── rds_cluster_snapshot.py │ ├── rds_db_cluster.py │ ├── rds_db_instance.py │ ├── rds_security_group.py │ ├── rds_snapshot.py │ └── rds_subnet_group.py │ ├── redshift.py │ ├── route53.py │ ├── route53domains.py │ ├── s3.py │ ├── security_group.py │ ├── ses.py │ ├── sns.py │ ├── sqs.py │ └── vpc │ ├── __init__.py │ ├── dhcp.py │ ├── endpoint.py │ ├── flow_log.py │ ├── nat_gateway.py │ ├── networkacl.py │ ├── peering.py │ ├── route_table.py │ ├── subnet.py │ ├── vpc.py │ └── vpn.py ├── setup.py └── supervisor ├── security_monkey_scheduler.conf ├── security_monkey_ui.conf └── security_monkey_workers.conf /.coveragerc: -------------------------------------------------------------------------------- 1 | [report] 2 | include = security_monkey/*.py 3 | 4 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | secmonkey.env 3 | boto.cfg 4 | .travis.yml 5 | #docs 6 | supervisor 7 | config-default.py 8 | generate-docs.py 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | .*.swp 3 | 4 | # C extensions 5 | *.so 6 | 7 | # Packages 8 | *.egg 9 | *.egg-info 10 | .python-eggs 11 | dist 12 | build 13 | _build 14 | eggs 15 | parts 16 | bin 17 | var 18 | sdist 19 | develop-eggs 20 | .installed.cfg 21 | lib64 22 | __pycache__ 23 | 24 | # Installer logs 25 | pip-log.txt 26 | 27 | # Unit test / coverage reports 28 | .coverage 29 | .tox 30 | nosetests.xml 31 | 32 | # Translations 33 | *.mo 34 | 35 | # Mr Developer 36 | .mr.developer.cfg 37 | .project 38 | .pydevproject 39 | 40 | # breadcrumbs 41 | .DS_Store 42 | 43 | # I think my vim python-mode started adding these everywhere. 44 | .ropeproject 45 | 46 | *.log 47 | *.log.* 48 | 49 | dart/.pub 50 | dart/.packages 51 | dart/web/ico/packages 52 | security_monkey/static 53 | dart/lib/util/constants.dart 54 | devlog/ 55 | venv/ 56 | venv 57 | .idea/ 58 | dart/.idea 59 | dart/.packages 60 | dart/web/ico/packages 61 | boto.cfg 62 | secmonkey.env 63 | *.crt 64 | *.key 65 | postgres-data/ 66 | docker-compose.override.yml 67 | .cache/ 68 | dart/pubspec.lock 69 | celerybeat-schedule 70 | celerybeat.pid 71 | -------------------------------------------------------------------------------- /.venv: -------------------------------------------------------------------------------- 1 | securitymonkey 2 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | - Patrick Kelley 2 | - Kevin Glisson 3 | - Roy Rapoport 4 | - Travis McPeak 5 | -------------------------------------------------------------------------------- /OSSMETADATA: -------------------------------------------------------------------------------- 1 | osslifecycle=active 2 | -------------------------------------------------------------------------------- /config-default.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Netflix, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /dart/.gitignore: -------------------------------------------------------------------------------- 1 | # Don’t commit the following directories created by pub. 2 | build/ 3 | packages/ 4 | 5 | # Or the files created by dart2js. 6 | *.dart.js 7 | *.dart.precompiled.js 8 | *.js_ 9 | *.js.deps 10 | *.js.map 11 | 12 | # Include when developing application packages. 13 | pubspec.lock 14 | 15 | # DS_Store is always annoying. 16 | .DS_Store 17 | -------------------------------------------------------------------------------- /dart/lib/component/modal_justify_issues/modal_justify_issues.html: -------------------------------------------------------------------------------- 1 | 5 | 39 | 42 | -------------------------------------------------------------------------------- /dart/lib/component/search_page_component/search_page_component.dart: -------------------------------------------------------------------------------- 1 | part of security_monkey; 2 | 3 | /// Because a Search-Page contains a Search-Bar, 4 | /// and a Search-Bar uses JavaScript and is not shadow-dom Compatible, 5 | /// the Search-Page cannot use shadow-dom. 6 | @Component( 7 | selector: 'search-page', 8 | templateUrl: 'packages/security_monkey/component/search_page_component/search_page_component.html', 9 | useShadowDom: false) 10 | class SearchPageComponent { 11 | RouteProvider routeProvider; 12 | String current_result_type; 13 | 14 | SearchPageComponent(this.routeProvider) { 15 | this.current_result_type = this.routeProvider.route.parent.name; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /dart/lib/component/search_page_component/search_page_component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 |

Enter a search on the left.

13 |
14 |
15 | -------------------------------------------------------------------------------- /dart/lib/component/settings/audit_score_component/audit_score_component.dart: -------------------------------------------------------------------------------- 1 | part of security_monkey; 2 | 3 | @Component( 4 | selector: 'audit-score-cmp', 5 | templateUrl: 'packages/security_monkey/component/settings/audit_score_component/audit_score_component.html', 6 | useShadowDom: false 7 | ) 8 | 9 | class AuditScoreListComponent extends PaginatedTable { 10 | UsernameService us; 11 | Router router; 12 | List auditscores; 13 | ObjectStore store; 14 | 15 | get isLoaded => super.is_loaded; 16 | get isError => super.is_error; 17 | 18 | AuditScoreListComponent(this.router, this.store, this.us) { 19 | list(); 20 | } 21 | 22 | void list() { 23 | super.is_loaded = false; 24 | store.list(AuditScore, params: { 25 | "count": ipp_as_int, 26 | "page": currentPage, 27 | }).then((auditscores) { 28 | super.setPaginationData(auditscores.meta); 29 | this.auditscores = auditscores; 30 | super.is_loaded = true; 31 | }); 32 | } 33 | 34 | void createAuditScore() { 35 | router.go('createauditscore', {}); 36 | } 37 | 38 | void deleteAuditScoreList(auditscoreitem) { 39 | store.delete(auditscoreitem).then( (_) { 40 | store.list(AuditScore).then( (auditscoreitems) { 41 | this.auditscores = auditscoreitems; 42 | }); 43 | }); 44 | list(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dart/lib/component/settings/auditor_settings_component/auditor_settings_component.dart: -------------------------------------------------------------------------------- 1 | part of security_monkey; 2 | 3 | @Component( 4 | selector: 'auditor-settings-cmp', 5 | templateUrl: 'packages/security_monkey/component/settings/auditor_settings_component/auditor_settings_component.html', 6 | useShadowDom: false 7 | ) 8 | class AuditorSettingsComponent extends PaginatedTable { 9 | UsernameService us; 10 | Router router; 11 | List auditorlist; 12 | ObjectStore store; 13 | final Http _http; 14 | 15 | get isLoaded => super.is_loaded; 16 | get isError => super.is_error; 17 | 18 | String url_encode(input) => param_to_url(input); 19 | 20 | void toggleAuditorEnable(auditor) { 21 | auditor.disabled = !auditor.disabled; 22 | store.update(auditor); 23 | } 24 | 25 | AuditorSettingsComponent(this.router, this.store, this._http, this.us) { 26 | list(); 27 | } 28 | 29 | void list() { 30 | super.is_loaded = false; 31 | store.list(AuditorSetting, params: { 32 | "count": ipp_as_int, 33 | "page": currentPage, 34 | "order_by": sorting_column, 35 | "order_dir": order_dir() 36 | }).then((auditor_settings) { 37 | super.setPaginationData(auditor_settings.meta); 38 | this.auditorlist = auditor_settings; 39 | super.is_loaded = true; 40 | }); 41 | } 42 | } -------------------------------------------------------------------------------- /dart/lib/component/settings/ignore_list_component/ignore_list_component.dart: -------------------------------------------------------------------------------- 1 | part of security_monkey; 2 | 3 | @Component( 4 | selector: 'ignorelist-cmp', 5 | templateUrl: 'packages/security_monkey/component/settings/ignore_list_component/ignore_list_component.html', 6 | //cssUrl: const ['/css/bootstrap.min.css'] 7 | useShadowDom: false 8 | ) 9 | class IgnoreListComponent extends PaginatedTable { 10 | UsernameService us; 11 | Router router; 12 | List ignorelist; 13 | ObjectStore store; 14 | 15 | IgnoreListComponent(this.router, this.store, this.us) { 16 | ignorelist = new List(); 17 | list(); 18 | } 19 | 20 | get signed_in => us.signed_in; 21 | 22 | void list() { 23 | store.list(IgnoreEntry, params: { 24 | "count": ipp_as_int, 25 | "page": currentPage 26 | }).then((ignorelist) { 27 | super.setPaginationData(ignorelist.meta); 28 | this.ignorelist = ignorelist; 29 | super.is_loaded = true; 30 | }); 31 | } 32 | 33 | void createIgnoreEntry() { 34 | router.go('createignoreentry', {}); 35 | } 36 | 37 | void deleteIgnoreList(ignoreitem) { 38 | store.delete(ignoreitem).then( (_) { 39 | store.list(IgnoreEntry).then( (ignoreitems) { 40 | this.ignorelist = ignoreitems; 41 | }); 42 | }); 43 | } 44 | 45 | String url_encode(input) => param_to_url(input); 46 | 47 | get isLoaded => super.is_loaded; 48 | get isError => super.is_error; 49 | } 50 | -------------------------------------------------------------------------------- /dart/lib/component/settings/network_whitelist_component/network_whitelist_component.dart: -------------------------------------------------------------------------------- 1 | part of security_monkey; 2 | 3 | @Component( 4 | selector: 'whitelist-cmp', 5 | templateUrl: 'packages/security_monkey/component/settings/network_whitelist_component/network_whitelist_component.html', 6 | //cssUrl: const ['/css/bootstrap.min.css'] 7 | useShadowDom: false 8 | ) 9 | class NetworkWhitelistComponent extends PaginatedTable { 10 | UsernameService us; 11 | Router router; 12 | List cidrs; 13 | ObjectStore store; 14 | 15 | NetworkWhitelistComponent(this.router, this.store, this.us) { 16 | cidrs = new List(); 17 | list(); 18 | } 19 | 20 | get signed_in => us.signed_in; 21 | 22 | void list() { 23 | store.list(NetworkWhitelistEntry, params: { 24 | "count": ipp_as_int, 25 | "page": currentPage 26 | }).then((cidrs) { 27 | super.setPaginationData(cidrs.meta); 28 | this.cidrs = cidrs; 29 | super.is_loaded = true; 30 | }); 31 | } 32 | 33 | void createWhitelist() { 34 | router.go('createwhitelist', {}); 35 | } 36 | 37 | void deleteWhitelist(NetworkWhitelistEntry cidr){ 38 | store.delete(cidr).then( (_) { 39 | store.list(NetworkWhitelistEntry).then( (cidrs) { 40 | this.cidrs = cidrs; 41 | }); 42 | }); 43 | } 44 | 45 | String url_encode(input) => param_to_url(input); 46 | 47 | get isLoaded => super.is_loaded; 48 | get isError => super.is_error; 49 | } 50 | -------------------------------------------------------------------------------- /dart/lib/component/settings/watcher_config_component/watcher_config_component.dart: -------------------------------------------------------------------------------- 1 | part of security_monkey; 2 | 3 | @Component( 4 | selector: 'watcher-config-cmp', 5 | templateUrl: 'packages/security_monkey/component/settings/watcher_config_component/watcher_config_component.html', 6 | useShadowDom: false 7 | ) 8 | 9 | class WatcherConfigComponent extends PaginatedTable { 10 | UsernameService us; 11 | ObjectStore store; 12 | List configs; 13 | 14 | WatcherConfigComponent(this.store) { 15 | this.store = store; 16 | this.list(); 17 | } 18 | 19 | void list() { 20 | configs = new List(); 21 | store.list(WatcherConfig, params: { 22 | "count": ipp_as_int, 23 | "page": currentPage 24 | }).then((config_response) { 25 | super.setPaginationData(config_response.meta); 26 | this.configs = config_response; 27 | super.is_loaded = true; 28 | }); 29 | } 30 | 31 | void updateSetting(WatcherConfig config) { 32 | this.store.update(config).then((_) { 33 | list(); 34 | }); 35 | } 36 | 37 | get isLoaded => super.is_loaded; 38 | get isError => super.is_error; 39 | } 40 | -------------------------------------------------------------------------------- /dart/lib/component/signout_component/signout_component.dart: -------------------------------------------------------------------------------- 1 | part of security_monkey; 2 | 3 | @Component( 4 | selector: 'signout', 5 | templateUrl: 'packages/security_monkey/component/signout_component/signout_component.html', 6 | exportExpressions: const ["complete"], 7 | //cssUrl: const ['/css/bootstrap.min.css'], 8 | useShadowDom: false 9 | ) 10 | class SignoutComponent implements ScopeAware { 11 | final Http _http; 12 | bool _complete = false; 13 | bool error = false; 14 | bool loading = true; 15 | Scope scope; 16 | 17 | set complete(val) { 18 | if (val) { 19 | scope.rootScope.broadcast("username-change", ""); 20 | } 21 | _complete = val; 22 | } 23 | 24 | get complete => _complete; 25 | 26 | SignoutComponent(this._http) { 27 | String url = '$API_HOST/logout'; 28 | print("Signing Out..."); 29 | _http.get(url, withCredentials: true).then((HttpResponse response) { 30 | print("Sign Out Complete"); 31 | complete = true; 32 | loading = false; 33 | 34 | }).catchError((error) { 35 | print("Error Signing Out $error"); 36 | error = true; 37 | loading = false; 38 | }); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /dart/lib/component/signout_component/signout_component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 7 |
8 |
9 |
10 | 13 |
14 |

To continue using Security Monkey, please proceed to the Login page.

15 |
16 |
17 |
18 | 21 |
22 |
23 |
24 | 25 |
-------------------------------------------------------------------------------- /dart/lib/component/username_component/username_component.dart: -------------------------------------------------------------------------------- 1 | part of security_monkey; 2 | 3 | @Component( 4 | selector: 'username', 5 | templateUrl: 'packages/security_monkey/component/username_component/username_component.html', 6 | useShadowDom: false) 7 | class UsernameComponent { 8 | UsernameService us; 9 | UsernameComponent(this.us); 10 | 11 | get name => this.us.name; 12 | get signed_in => this.us.signed_in; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /dart/lib/component/username_component/username_component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dart/lib/model/Account.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.account; 2 | 3 | import 'dart:convert'; 4 | 5 | class Account { 6 | int id; 7 | String name; 8 | String identifier; 9 | String notes; 10 | bool _active; 11 | bool _third_party; 12 | String account_type; 13 | Map custom_field_values = new Map(); 14 | 15 | Account(); 16 | 17 | get active => _active; 18 | get third_party => _third_party; 19 | 20 | set active(active) { 21 | if (active) { 22 | _third_party = false; 23 | } 24 | _active = active; 25 | } 26 | 27 | set third_party(third_party) { 28 | if (third_party) { 29 | _active = false; 30 | } 31 | _third_party = third_party; 32 | } 33 | 34 | Account.fromMap(Map data) { 35 | id = data['id']; 36 | active = data['active']; 37 | third_party = data['third_party']; 38 | name = data['name']; 39 | identifier = data['identifier']; 40 | notes = data['notes']; 41 | account_type = data['account_type']; 42 | 43 | if (data.containsKey('custom_fields')) { 44 | for (var field in data['custom_fields']) { 45 | custom_field_values[field['name']] = field['value']; 46 | } 47 | } 48 | } 49 | 50 | String toJson() { 51 | Map objmap = { 52 | "id": id, 53 | "active": active, 54 | "third_party": third_party, 55 | "name": name, 56 | "identifier": identifier, 57 | "notes": notes, 58 | "account_type": account_type, 59 | "custom_fields": custom_field_values 60 | }; 61 | return JSON.encode(objmap); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /dart/lib/model/AccountBulkUpdate.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.account_bulk_update; 2 | 3 | import 'Account.dart'; 4 | import 'dart:convert'; 5 | 6 | class AccountBulkUpdate { 7 | Map accounts_map = new Map(); 8 | 9 | AccountBulkUpdate(); 10 | 11 | AccountBulkUpdate.fromAccountList(List accounts) { 12 | for (var account in accounts) { 13 | this.accounts_map[account.name] = account.active; 14 | } 15 | } 16 | 17 | String toJson() { 18 | return JSON.encode(this.accounts_map); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /dart/lib/model/AccountPatternAuditScore.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.account_pattern_audit_score; 2 | 3 | class AccountPatternAuditScore { 4 | int id; 5 | String account_type; 6 | String account_field; 7 | String account_pattern; 8 | int score; 9 | int itemauditscores_id; 10 | 11 | AccountPatternAuditScore(); 12 | 13 | AccountPatternAuditScore.fromMap(Map data) { 14 | id = data["id"]; 15 | account_type = data["account_type"]; 16 | account_field = data["account_field"]; 17 | account_pattern = data["account_pattern"]; 18 | score = data["score"]; 19 | itemauditscores_id = data["itemauditscores_id"]; 20 | } 21 | 22 | String toJson() { 23 | Map objmap = { 24 | "id": id, 25 | "account_type": account_type, 26 | "account_field": account_field, 27 | "account_pattern": account_pattern, 28 | "score": score, 29 | "itemauditscores_id": itemauditscores_id 30 | }; 31 | return JSON.encode(objmap); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /dart/lib/model/Issue.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.model_issue; 2 | 3 | import 'Item.dart'; 4 | import 'ItemLink.dart'; 5 | import 'package:security_monkey/util/utils.dart' show localDateFromAPIDate; 6 | 7 | class Issue { 8 | int id; 9 | int score; 10 | String issue; 11 | String notes; 12 | bool fixed; 13 | bool justified; 14 | String justified_user; 15 | String justification; 16 | //String justified_date; 17 | DateTime justified_date; 18 | int item_id; 19 | bool selected_for_justification; 20 | 21 | Item item; 22 | List item_links = new List(); 23 | 24 | Issue.fromMap(Map data) { 25 | id = data['id']; 26 | score = data['score']; 27 | issue = data['issue']; 28 | notes = data['notes']; 29 | fixed = data['fixed']; 30 | justified = data['justified']; 31 | justified_user = data['justified_user']; 32 | justification = data['justification']; 33 | if (data['justified_date'] != null) { 34 | justified_date = localDateFromAPIDate(data['justified_date']); 35 | } 36 | item_id = data['item_id']; 37 | selected_for_justification = false; 38 | 39 | item = new Item.fromMap({ 40 | "item": data 41 | }); 42 | 43 | for (var item_link in data['item_links']) { 44 | ItemLink linkObj = new ItemLink.fromMap(item_link); 45 | item_links.add(linkObj); 46 | } 47 | } 48 | 49 | get has_sub_item => this.item_links.length != 0; 50 | 51 | get get_links => '{{item_links.first.name}}'; 52 | } 53 | -------------------------------------------------------------------------------- /dart/lib/model/ItemComment.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.item_comment; 2 | 3 | import 'package:security_monkey/util/utils.dart' show localDateFromAPIDate; 4 | 5 | /// { 6 | /// "date_created": "2014-05-07 16:25:50", 7 | /// "id": 2, 8 | /// "revision_id": 2405, 9 | /// "text": "second comment", 10 | /// "user": "user@example.com" 11 | /// } 12 | 13 | 14 | class ItemComment { 15 | int id; 16 | int item_id; 17 | String text; 18 | String user; 19 | DateTime date_created; 20 | 21 | ItemComment(); 22 | 23 | ItemComment.fromMap(Map data) { 24 | id = data['id']; 25 | item_id = data['item_id']; 26 | text = data['text']; 27 | user = data['user']; 28 | date_created = localDateFromAPIDate(data['date_created']); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dart/lib/model/ItemLink.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.item_link; 2 | 3 | class ItemLink { 4 | int id; 5 | String name; 6 | 7 | ItemLink.fromMap(Map data) { 8 | id = data['id']; 9 | name = data['name']; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /dart/lib/model/RevisionComment.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.revision_comment; 2 | 3 | import 'package:security_monkey/util/utils.dart' show localDateFromAPIDate; 4 | 5 | /// Format from API: 6 | /// { 7 | /// "date_created": "2014-05-07 16:25:50", 8 | /// "id": 2, 9 | /// "revision_id": 2405, 10 | /// "text": "second comment", 11 | /// "user": "user@example.com" 12 | /// } 13 | 14 | class RevisionComment { 15 | int id; 16 | int revision_id; 17 | String text; 18 | String user; 19 | DateTime date_created; 20 | 21 | RevisionComment(); 22 | 23 | RevisionComment.fromMap(Map data) { 24 | id = data['id']; 25 | revision_id = data['revision_id']; 26 | text = data['text']; 27 | user = data['user']; 28 | date_created = localDateFromAPIDate(data['date_created']); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dart/lib/model/Role.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.role; 2 | 3 | import 'dart:convert'; 4 | 5 | class Role implements Comparable{ 6 | String id; 7 | 8 | Role(String id){ 9 | this.id = id; 10 | } 11 | 12 | Role.fromMap(Map data) { 13 | id = data['name']; 14 | } 15 | 16 | String toJson() { 17 | Map objmap = { 18 | "name": id 19 | }; 20 | return JSON.encode(objmap); 21 | } 22 | 23 | bool operator ==(r) => r is Role && this.id == r.id; 24 | 25 | int compareTo(Role r){ 26 | return this.id.compareTo(r.id); 27 | } 28 | } -------------------------------------------------------------------------------- /dart/lib/model/User.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.user; 2 | 3 | import 'Role.dart'; 4 | import 'dart:convert'; 5 | import 'package:security_monkey/util/utils.dart' show localDateFromAPIDate; 6 | 7 | class User{ 8 | int id; 9 | String email; 10 | bool active; 11 | Role role; 12 | DateTime confirmed_at; 13 | int login_count; 14 | DateTime last_login_at; 15 | DateTime current_login_at; 16 | String last_login_ip; 17 | String current_login_ip; 18 | bool daily_audit_email; 19 | String change_reports; 20 | 21 | 22 | User.fromMap(Map data) { 23 | id = data['id']; 24 | email = data['email']; 25 | active = data['active']; 26 | 27 | if(data['role'] != null){ 28 | role = new Role(data['role']); 29 | }else{ 30 | role = new Role("anonymous"); 31 | } 32 | 33 | if(data['confirmed_at'] != null) { 34 | confirmed_at = localDateFromAPIDate(data['confirmed_at']); 35 | } 36 | login_count = data['login_count']; 37 | if(data['last_login_at'] != null) { 38 | last_login_at = localDateFromAPIDate(data['last_login_at']); 39 | } 40 | if(data['current_login_at']) { 41 | current_login_at = localDateFromAPIDate(data['current_login_at']); 42 | } 43 | last_login_ip = data['last_login_ip']; 44 | current_login_ip = data['current_login_ip']; 45 | daily_audit_email = data['daily_audit_email']; 46 | change_reports = data['change_reports']; 47 | } 48 | 49 | get role_id => role.id; 50 | 51 | String toJson() { 52 | Map objmap = { 53 | "id": id, 54 | "active": active, 55 | "email": email, 56 | "role": role.id 57 | }; 58 | return JSON.encode(objmap); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /dart/lib/model/UserSetting.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.user_setting; 2 | 3 | import 'Account.dart'; 4 | import 'dart:convert'; 5 | 6 | class UserSetting { 7 | 8 | List accounts = new List(); 9 | bool daily_audit_email = false; 10 | String change_report_setting = "NONE"; 11 | int id; 12 | 13 | get account_ids => accounts.map((account) => account.id).toList(); 14 | 15 | UserSetting.fromMap(Map setting) { 16 | 17 | print("UserSetting Constructor Received $setting"); 18 | if (setting.containsKey("settings")) { 19 | setting = setting["settings"][0]; 20 | } 21 | 22 | 23 | daily_audit_email = setting['daily_audit_email']; 24 | change_report_setting = setting['change_reports']; 25 | for (var account_id in setting['accounts']) { 26 | Account account = new Account() 27 | ..id = account_id; 28 | accounts.add(account); 29 | } 30 | } 31 | 32 | String toJson() { 33 | Map objmap = { 34 | "accounts": account_ids, 35 | "daily_audit_email": daily_audit_email, 36 | "change_report_setting": change_report_setting 37 | }; 38 | return JSON.encode(objmap); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /dart/lib/model/account_config.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.account_config; 2 | 3 | import 'custom_field_config.dart'; 4 | 5 | class AccountConfig { 6 | List account_types = new List(); 7 | Map identifier_labels = new Map(); 8 | Map identifier_tool_tips = new Map(); 9 | Map> fields = new Map>(); 10 | 11 | AccountConfig(); 12 | 13 | AccountConfig.fromMap(Map data) { 14 | if (data.containsKey('custom_configs')) { 15 | var acc_configs = data['custom_configs']; 16 | acc_configs.forEach((k,v) => this._addToLists(k, v)); 17 | } 18 | } 19 | 20 | void _addToLists(account_type, values) { 21 | this.account_types.add(account_type); 22 | this.identifier_labels[account_type] = values['identifier_label']; 23 | this.identifier_tool_tips[account_type] = values['identifier_tool_tip']; 24 | 25 | var list = new List(); 26 | var field_config = values['fields']; 27 | for (var field in field_config) { 28 | list.add(new CustomFieldConfig.fromMap(field)); 29 | } 30 | this.fields[account_type] = list; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dart/lib/model/auditorsetting.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.auditorsetting; 2 | 3 | class AuditorSetting { 4 | String account; 5 | String technology; 6 | String issue; 7 | int count; 8 | bool disabled; 9 | int id; 10 | 11 | AuditorSetting(); 12 | 13 | AuditorSetting.fromMap(Map data) { 14 | account = data["account"]; 15 | issue = data["issue"]; 16 | count = data["count"]; 17 | technology = data["technology"]; 18 | disabled = data["disabled"]; 19 | id = data["id"]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dart/lib/model/auditscore.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.auditscore; 2 | 3 | class AuditScore { 4 | String method; 5 | String technology; 6 | int score; 7 | int id; 8 | bool disabled; 9 | 10 | List account_pattern_scores = new List(); 11 | 12 | AuditScore(); 13 | 14 | AuditScore.fromMap(Map data) { 15 | method = data["method"]; 16 | score = data["score"]; 17 | technology = data["technology"]; 18 | id = data["id"]; 19 | disabled = data["disabled"]; 20 | account_pattern_scores = data["account_pattern_scores"]; 21 | } 22 | 23 | String toJson() { 24 | Map objmap = { 25 | "id": id, 26 | "method": method, 27 | "technology": technology, 28 | "notes": notes, 29 | "disabled": disabled 30 | }; 31 | return JSON.encode(objmap); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /dart/lib/model/custom_field_config.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.custom_field_config; 2 | 3 | class CustomFieldConfig { 4 | String name; 5 | String label; 6 | bool editable; 7 | String tool_tip; 8 | bool password; 9 | List allowed_values; 10 | 11 | CustomFieldConfig.fromMap(Map data) { 12 | name = data['name']; 13 | label = data['label']; 14 | editable = data['editable']; 15 | tool_tip = data['tool_tip']; 16 | password = data['password']; 17 | allowed_values = data['allowed_values']; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /dart/lib/model/ignore_entry.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.ignore_entry; 2 | 3 | class IgnoreEntry { 4 | int id; 5 | String prefix; 6 | String notes; 7 | String technology; 8 | 9 | IgnoreEntry(); 10 | 11 | IgnoreEntry.fromMap(Map data) { 12 | id = data["id"]; 13 | prefix = data["prefix"]; 14 | notes = data["notes"]; 15 | technology = data["technology"]; 16 | } 17 | } -------------------------------------------------------------------------------- /dart/lib/model/network_whitelist_entry.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.network_whitelist_entry; 2 | 3 | import 'dart:convert'; 4 | 5 | class NetworkWhitelistEntry { 6 | int id; 7 | String name; 8 | String cidr; 9 | String notes; 10 | 11 | NetworkWhitelistEntry(); 12 | 13 | NetworkWhitelistEntry.fromMap(Map data) { 14 | id = data["id"]; 15 | name = data["name"]; 16 | notes = data["notes"]; 17 | cidr = data["cidr"]; 18 | } 19 | 20 | String toJson() { 21 | Map objmap = { 22 | "id": id, 23 | "name": name, 24 | "cidr": cidr, 25 | "notes": notes 26 | }; 27 | return JSON.encode(objmap); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /dart/lib/model/techmethods.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.techmethods; 2 | 3 | class TechMethods { 4 | List technologies = new List(); 5 | Map> methods = new Map>(); 6 | 7 | TechMethods(); 8 | 9 | TechMethods.fromMap(Map data) { 10 | if (data.containsKey('tech_methods')) { 11 | var tech_methods = data['tech_methods']; 12 | tech_methods.forEach((k,v) => this._addToLists(k, v)); 13 | } 14 | } 15 | 16 | void _addToLists(k, v) { 17 | technologies.add(k); 18 | methods[k] = v; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /dart/lib/model/watcher_config.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.watcher_config; 2 | 3 | class WatcherConfig { 4 | int id; 5 | String index; 6 | String interval; 7 | bool active; 8 | bool remove_items; 9 | bool changed; 10 | 11 | WatcherConfig(); 12 | 13 | WatcherConfig.fromMap(Map data) { 14 | id = data["id"]; 15 | index = data["index"]; 16 | interval = data["interval"]; 17 | active = data["active"]; 18 | remove_items = false; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /dart/lib/service/messages.dart: -------------------------------------------------------------------------------- 1 | part of security_monkey; 2 | 3 | @Injectable() 4 | class Messages { 5 | RootScope rootScope; 6 | 7 | Messages(this.rootScope); 8 | 9 | void alert(String message) { 10 | rootScope.rootScope.broadcast("globalAlert", message); 11 | } 12 | 13 | void username_change(String username) { 14 | rootScope.rootScope.broadcast("username-change", username); 15 | } 16 | 17 | void roles_change(List roles) { 18 | rootScope.rootScope.broadcast("roles-change", roles); 19 | } 20 | 21 | void auth_url_change(String url) { 22 | rootScope.rootScope.broadcast("authurl-change", url); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dart/lib/util/constants.dart: -------------------------------------------------------------------------------- 1 | library security_monkey.constants; 2 | 3 | /** 4 | ** REMOTE_AUTH: 5 | ** FALSE - When the API 403's, just redirect to /login. 6 | ** Nginx should proxy the request through to the python login page. 7 | ** TRUE - When the API 403's, redirect the browser to whatever URL is provided by the API. 8 | ** This is useful for third party authentication like SAML. 9 | **/ 10 | 11 | // LOCAL DEV 12 | //final String API_HOST = 'http://127.0.0.1:5000/api/1'; 13 | //final bool REMOTE_AUTH = true; 14 | 15 | // Same Box 16 | final String API_HOST = '/api/1'; 17 | final bool REMOTE_AUTH = false; 18 | 19 | // Also update a few places in /web/js/searchpage.js 20 | 21 | -------------------------------------------------------------------------------- /dart/lib/util/utils.dart: -------------------------------------------------------------------------------- 1 | // Note: This does not handle dates using hourly offset like '2012-02-27T14+00:00' 2 | // Assume dates from API are ZULU. Append 'z' if needed. 3 | DateTime localDateFromAPIDate(String apiDate) { 4 | if (apiDate.endsWith('z')||apiDate.endsWith('Z')) { 5 | return DateTime.parse(apiDate).toLocal(); 6 | } 7 | return DateTime.parse(apiDate+"z").toLocal(); 8 | } -------------------------------------------------------------------------------- /dart/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: security_monkey 2 | description: An AWS Policy Monitoring and Alerting Tool 3 | version: 1.1.1 4 | dependencies: 5 | angular: "^1.1.2+2" 6 | angular_ui: ">=0.6.8 <0.7.0" 7 | hammock: ">=0.4.0 <0.5.0" 8 | ng_infinite_scroll: ">=0.2.0 <0.3.0" 9 | web_components: ">=0.10.1 <0.11.0" 10 | browser: ">=0.10.0+2 <0.11.0" 11 | http_server: ">=0.9.5+1 <0.10.0" 12 | code_transformers: ">=0.2.5 <0.3.0" 13 | dart_to_js_script_rewriter: ">=0.0.2 <0.1.0" 14 | aws_policy_expander_minimizer: ">=0.0.5 <0.1.0" 15 | dev_dependencies: 16 | unittest: '0.11.0+2' 17 | transformers: 18 | - angular 19 | - dart_to_js_script_rewriter 20 | - $dart2js: 21 | csp: true 22 | checked: false 23 | minify: true 24 | verbose: true 25 | suppressWarnings: false 26 | suppressHints: false 27 | terse: false 28 | author: yes 29 | homepage: https://github.com/Netflix/security_monkey 30 | -------------------------------------------------------------------------------- /dart/web/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 70px; 3 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !important; 4 | } 5 | 6 | .ng-cloak { 7 | display: none !important; 8 | } 9 | 10 | .smhead { 11 | margin-top: 5px; margin-right: 5px; 12 | width: 30px; 13 | height: 30px; 14 | order: 1; 15 | } 16 | 17 | .smstanding { 18 | display: block; position: fixed; bottom: 0px; left: 30px; z-index: -100; opacity:0.25; 19 | } 20 | 21 | .full_width { 22 | width: 100% 23 | } 24 | 25 | .black { 26 | color: black; 27 | } 28 | 29 | .logo_container { 30 | display: flex !important; 31 | flex-direction: row; 32 | } 33 | 34 | .sm_logo_text { 35 | order: 2; 36 | } 37 | -------------------------------------------------------------------------------- /dart/web/css/signin.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 40px; 3 | padding-bottom: 40px; 4 | background-color: #eee; 5 | } 6 | 7 | .form-signin { 8 | max-width: 330px; 9 | padding: 15px; 10 | margin: 0 auto; 11 | } 12 | .form-signin .form-signin-heading, 13 | .form-signin .checkbox { 14 | margin-bottom: 10px; 15 | } 16 | .form-signin .checkbox { 17 | font-weight: normal; 18 | } 19 | .form-signin .form-control { 20 | position: relative; 21 | height: auto; 22 | -webkit-box-sizing: border-box; 23 | -moz-box-sizing: border-box; 24 | box-sizing: border-box; 25 | padding: 10px; 26 | font-size: 16px; 27 | } 28 | .form-signin .form-control:focus { 29 | z-index: 2; 30 | } 31 | .form-signin input[type="email"] { 32 | margin-bottom: -1px; 33 | border-bottom-right-radius: 0; 34 | border-bottom-left-radius: 0; 35 | } 36 | .form-signin input[type="password"] { 37 | margin-bottom: 10px; 38 | border-top-left-radius: 0; 39 | border-top-right-radius: 0; 40 | } 41 | 42 | .login-or { 43 | position: relative; 44 | font-size: 18px; 45 | color: #aaa; 46 | margin-top: 10px; 47 | margin-bottom: 10px; 48 | padding-top: 10px; 49 | padding-bottom: 10px; 50 | } 51 | 52 | .span-or { 53 | display: block; 54 | position: absolute; 55 | left: 50%; 56 | top: -2px; 57 | margin-left: -25px; 58 | background-color: #dfdfdf; 59 | width: 50px; 60 | text-align: center; 61 | } 62 | 63 | .hr-or { 64 | background-color: #cdcdcd; 65 | height: 1px; 66 | margin-top: 0px !important; 67 | margin-bottom: 0px !important; 68 | } -------------------------------------------------------------------------------- /dart/web/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /dart/web/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /dart/web/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /dart/web/ico/favicon-1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/ico/favicon-1.ico -------------------------------------------------------------------------------- /dart/web/ico/favicon-2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/ico/favicon-2.ico -------------------------------------------------------------------------------- /dart/web/ico/favicon-3.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/ico/favicon-3.ico -------------------------------------------------------------------------------- /dart/web/images/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/images/close.png -------------------------------------------------------------------------------- /dart/web/images/option_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/images/option_panel.png -------------------------------------------------------------------------------- /dart/web/images/option_panel_blah.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/images/option_panel_blah.png -------------------------------------------------------------------------------- /dart/web/images/securitymonkey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/images/securitymonkey.png -------------------------------------------------------------------------------- /dart/web/images/securitymonkey1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/images/securitymonkey1.png -------------------------------------------------------------------------------- /dart/web/images/securitymonkeyHead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/images/securitymonkeyHead.png -------------------------------------------------------------------------------- /dart/web/main.dart: -------------------------------------------------------------------------------- 1 | library security_monkey_main; 2 | 3 | import 'package:angular/application_factory.dart'; 4 | import 'package:logging/logging.dart'; 5 | import 'package:security_monkey/security_monkey.dart'; 6 | 7 | main() { 8 | Logger.root..level = Level.FINEST 9 | ..onRecord.listen((LogRecord rec) { 10 | print('${rec.level.name}: ${rec.time}: ${rec.message}'); 11 | }); 12 | final inj = applicationFactory() 13 | .addModule(new SecurityMonkeyModule()) 14 | .run(); 15 | GlobalHttpInterceptors.setUp(inj); 16 | } -------------------------------------------------------------------------------- /dart/web/select2-3.4.5/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012 Igor Vaynberg 2 | 3 | Version: @@ver@@ Timestamp: @@timestamp@@ 4 | 5 | This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU 6 | General Public License version 2 (the "GPL License"). You may choose either license to govern your 7 | use of this software only upon the condition that you accept all of the terms of either the Apache 8 | License or the GPL License. 9 | 10 | You may obtain a copy of the Apache License and the GPL License at: 11 | 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | http://www.gnu.org/licenses/gpl-2.0.html 14 | 15 | Unless required by applicable law or agreed to in writing, software distributed under the Apache License 16 | or the GPL Licesnse is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 17 | either express or implied. See the Apache License and the GPL License for the specific language governing 18 | permissions and limitations under the Apache License and the GPL License. -------------------------------------------------------------------------------- /dart/web/select2-3.4.5/select2-spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/select2-3.4.5/select2-spinner.gif -------------------------------------------------------------------------------- /dart/web/select2-3.4.5/select2.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "select2", 3 | "title": "Select2", 4 | "description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.", 5 | "keywords": [ 6 | "select", 7 | "autocomplete", 8 | "typeahead", 9 | "dropdown", 10 | "multiselect", 11 | "tag", 12 | "tagging" 13 | ], 14 | "version": "3.4.5", 15 | "author": { 16 | "name": "Igor Vaynberg", 17 | "url": "https://github.com/ivaynberg" 18 | }, 19 | "licenses": [ 20 | { 21 | "type": "Apache", 22 | "url": "http://www.apache.org/licenses/LICENSE-2.0" 23 | }, 24 | { 25 | "type": "GPL v2", 26 | "url": "http://www.gnu.org/licenses/gpl-2.0.html" 27 | } 28 | ], 29 | "bugs": "https://github.com/ivaynberg/select2/issues", 30 | "homepage": "http://ivaynberg.github.com/select2", 31 | "docs": "http://ivaynberg.github.com/select2/", 32 | "download": "https://github.com/ivaynberg/select2/tags", 33 | "dependencies": { 34 | "jquery": ">=1.7.1" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dart/web/select2-3.4.5/select2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/select2-3.4.5/select2.png -------------------------------------------------------------------------------- /dart/web/select2-3.4.5/select2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/dart/web/select2-3.4.5/select2x2.png -------------------------------------------------------------------------------- /dart/web/views/account.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dart/web/views/accountpatternauditscore.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /dart/web/views/auditscore.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /dart/web/views/compare_item_revisions.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dart/web/views/create_account.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dart/web/views/create_auditscore.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /dart/web/views/create_ignoreentry.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dart/web/views/create_whitelist.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dart/web/views/dashboard.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dart/web/views/error.html: -------------------------------------------------------------------------------- 1 |

Sorry. Exception.

-------------------------------------------------------------------------------- /dart/web/views/ignoreentry.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dart/web/views/itemdetailsview.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dart/web/views/searchpage.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dart/web/views/settings.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dart/web/views/signout.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dart/web/views/whitelist.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docker-compose.init.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | version: '3.2' 4 | services: 5 | postgres: 6 | container_name: secmonkey-db 7 | image: postgres:10.1 8 | 9 | init: 10 | container_name: init 11 | build: . 12 | image: secmonkey:latest 13 | working_dir: /usr/local/src/security_monkey 14 | volumes: 15 | - type: bind 16 | source: ./data/aws_accounts.json 17 | target: /usr/local/src/security_monkey/data/aws_accounts.json 18 | - type: bind 19 | source: ./docker 20 | target: /usr/local/src/security_monkey/docker 21 | - type: bind 22 | source: ./env-config/config-docker.py 23 | target: /usr/local/src/security_monkey/env-config/config-docker.py 24 | depends_on: 25 | - postgres 26 | env_file: secmonkey.env 27 | entrypoint: /usr/local/src/security_monkey/docker/api-init.sh 28 | -------------------------------------------------------------------------------- /docker-compose.shell.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | version: '2' 4 | services: 5 | data: 6 | stdin_open: true 7 | tty: true 8 | entrypoint: ["/bin/bash"] 9 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | Docker local development 2 | ======================== 3 | 4 | Project resources 5 | ----------------- 6 | 7 | - [Docker documentation](../docs/docker.md) 8 | - [Development documentation](../docs/development.md) 9 | - [OSX Development Setup](../docs/dev_setup_osx.md) 10 | - [Windows Development Setup](../docs/dev_setup_windows.md) 11 | - [Ubuntu Development Setup](../docs/dev_setup_ubuntu.md) 12 | 13 | -------------------------------------------------------------------------------- /docker/api-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # Wait the database 4 | sleep 10 5 | 6 | echo "Starting API init on $( date )" 7 | 8 | echo "Creating the user: ${SECURITY_MONKEY_POSTGRES_USER:-postgres} on ${SECURITY_MONKEY_POSTGRES_HOST:-postgres}:${SECURITY_MONKEY_POSTGRES_PORT:-5432}:" 9 | psql -h ${SECURITY_MONKEY_POSTGRES_HOST:-postgres} -p ${SECURITY_MONKEY_POSTGRES_PORT:-5432} \ 10 | -U ${SECURITY_MONKEY_POSTGRES_USER:-postgres} \ 11 | --command "ALTER USER ${SECURITY_MONKEY_POSTGRES_USER:-postgres} with PASSWORD '${SECURITY_MONKEY_POSTGRES_PASSWORD:-securitymonkeypassword}';" 12 | 13 | echo "Creating the ${SECURITY_MONKEY_POSTGRES_DATABASE:-secmonkey} on ${SECURITY_MONKEY_POSTGRES_HOST:-postgres}:${SECURITY_MONKEY_POSTGRES_PORT:-5432} with the ${SECURITY_MONKEY_POSTGRES_USER:-postgres}:" 14 | createdb -h ${SECURITY_MONKEY_POSTGRES_HOST:-postgres} -p ${SECURITY_MONKEY_POSTGRES_PORT:-5432} \ 15 | -U ${SECURITY_MONKEY_POSTGRES_USER:-postgres} \ 16 | -O ${SECURITY_MONKEY_POSTGRES_USER:-postgres} ${SECURITY_MONKEY_POSTGRES_DATABASE:-secmonkey} 17 | 18 | mkdir -p /var/log/security_monkey/ 19 | touch "/var/log/security_monkey/security_monkey-deploy.log" 20 | 21 | cd /usr/local/src/security_monkey 22 | monkey db upgrade 23 | 24 | # -------------ADD ADDITIONAL MONKEY COMMANDS TO EXECUTE HERE------------- 25 | 26 | cat < 8 | 9 | """ 10 | # Broker source: Place yours here: 11 | import os 12 | 13 | broker_url = 'redis://{}/{}'.format( 14 | os.getenv('SECURITY_MONKEY_REDIS_HOST', 'redis'), 15 | os.getenv('SECURITY_MONKEY_REDIS_DB', '0') 16 | ) 17 | 18 | # List of modules to import when the Celery worker starts. 19 | imports = ('security_monkey.task_scheduler.tasks',) 20 | 21 | # How many processes per worker instance? 22 | worker_concurrency = 10 23 | 24 | timezone = "UTC" 25 | enable_utc = True 26 | 27 | ########################### 28 | # IMPORTANT: This helps avoid memory leak issues - do not change this number! 29 | worker_max_tasks_per_child = 1 30 | ############################ 31 | -------------------------------------------------------------------------------- /docker/nginx/conf.d/securitymonkey.conf: -------------------------------------------------------------------------------- 1 | add_header X-Content-Type-Options "nosniff"; 2 | add_header X-XSS-Protection "1; mode=block"; 3 | add_header X-Frame-Options "SAMEORIGIN"; 4 | add_header Strict-Transport-Security "max-age=631138519"; 5 | add_header Content-Security-Policy "default-src 'self'; font-src 'self' https://fonts.gstatic.com; script-src 'self' https://ajax.googleapis.com; style-src 'self' https://fonts.googleapis.com;"; 6 | 7 | server { 8 | listen 0.0.0.0:80; 9 | listen 0.0.0.0:443 ssl; 10 | ssl_certificate /etc/nginx/ssl/server.crt; 11 | ssl_certificate_key /etc/nginx/ssl/server.key; 12 | access_log /var/log/security_monkey/security_monkey.access.log; 13 | error_log /var/log/security_monkey/security_monkey.error.log; 14 | 15 | location ~* ^/(reset|confirm|healthcheck|register|login|logout|api) { 16 | proxy_read_timeout 120; 17 | proxy_pass http://smapi:5000; 18 | proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; 19 | proxy_redirect off; 20 | proxy_buffering off; 21 | proxy_set_header Host $host; 22 | proxy_set_header X-Real-IP $remote_addr; 23 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 24 | } 25 | 26 | location /static { 27 | rewrite ^/static/(.*)$ /$1 break; 28 | root /usr/local/src/security_monkey/security_monkey/static; 29 | index ui.html; 30 | } 31 | 32 | location / { 33 | root /usr/local/src/security_monkey/security_monkey/static; 34 | index ui.html; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /docker/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | 2 | user nginx; 3 | worker_processes 1; 4 | daemon off; 5 | 6 | error_log /var/log/nginx/error.log warn; 7 | pid /var/run/nginx.pid; 8 | 9 | 10 | events { 11 | worker_connections 1024; 12 | } 13 | 14 | 15 | http { 16 | include /etc/nginx/mime.types; 17 | default_type application/octet-stream; 18 | 19 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 20 | '$status $body_bytes_sent "$http_referer" ' 21 | '"$http_user_agent" "$http_x_forwarded_for"'; 22 | 23 | access_log /var/log/nginx/access.log main; 24 | 25 | sendfile on; 26 | #tcp_nopush on; 27 | 28 | keepalive_timeout 65; 29 | 30 | #gzip on; 31 | 32 | include /etc/nginx/conf.d/*.conf; 33 | } 34 | -------------------------------------------------------------------------------- /docker/nginx/start-nginx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SECURITY_MONKEY_SSL_CERT=${SECURITY_MONKEY_SSL_CERT:-/etc/nginx/ssl/server.crt} 4 | SECURITY_MONKEY_SSL_KEY=${SECURITY_MONKEY_SSL_KEY:-/etc/nginx/ssl/server.key} 5 | 6 | # if no SSL, disable HTTPS (if not already disabled) 7 | if ([ ! -f "$SECURITY_MONKEY_SSL_CERT" ] || [ ! -f "$SECURITY_MONKEY_SSL_KEY" ]) && grep -E '^[^#]+ssl' /etc/nginx/conf.d/securitymonkey.conf; then 8 | echo "$(date) Error: Missing files required for SSL" 9 | sed -i.bak '/^#/! s/.*ssl/# &/' /etc/nginx/conf.d/securitymonkey.conf &&\ 10 | echo "$(date) Warn: Disabled ssl in securitymonkey.conf" 11 | fi 12 | 13 | exec nginx 14 | -------------------------------------------------------------------------------- /docker/scheduler-start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # wait the database 4 | sleep 10 5 | 6 | mkdir -p /var/log/security_monkey 7 | touch /var/log/security_monkey/security_monkey-deploy.log 8 | 9 | cd /usr/local/src/security_monkey 10 | 11 | echo "Starting Migrations" 12 | monkey db upgrade 13 | echo "Migrations Complete" 14 | 15 | celery -A security_monkey.task_scheduler.beat.CELERY beat -l debug 16 | -------------------------------------------------------------------------------- /docker/worker-start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # wait for the scheduler 4 | sleep 20 5 | 6 | mkdir -p /var/log/security_monkey 7 | touch /var/log/security_monkey/security_monkey-deploy.log 8 | 9 | cd /usr/local/src/security_monkey 10 | celery -A celery -A security_monkey.task_scheduler.tasks.CELERY worker -E 11 | -------------------------------------------------------------------------------- /docs/api/index.md: -------------------------------------------------------------------------------- 1 | API Reference 2 | ============= 3 | 4 | At a high-level, Security Monkey consists of the following components: 5 | 6 | Watcher - Component that monitors a given AWS account and technology (e.g. S3, EC2). The Watcher detects and records changes to configurations. So, if an S3 bucket policy changes, the Watcher will detect this and store the change. 7 | 8 | Notifier - Component that lets a user or group of users know when a particular item has changed. This component also provides notification based on the triggering of audit rules. 9 | 10 | Auditor - Component that executes a set of business rules against an AWS configuration to determine the level of risk associated with the configuration. For example, a rule may look for a security group with a rule allowing ingress from 0.0.0.0/0 (meaning the security group is open to the Internet). Or, a rule may look for an S3 policy that allows access from an unknown AWS account (meaning you may be unintentionally sharing the data stored in your S3 bucket). Security Monkey has a number of built-in rules included, and users are free to add their own rules. 11 | 12 | Class and method level definitions and documentation 13 | 14 | Indices and tables 15 | ------------------ 16 | 17 | - genindex 18 | - modindex 19 | - search 20 | 21 | -------------------------------------------------------------------------------- /docs/api/security_monkey.auditors.md: -------------------------------------------------------------------------------- 1 | auditors Package 2 | ================ 3 | 4 | auditors Package 5 | ---------------- 6 | 7 | elb Module 8 | ---------- 9 | 10 | iam\_group Module 11 | ----------------- 12 | 13 | iam\_policy Module 14 | ------------------ 15 | 16 | iam\_role Module 17 | ---------------- 18 | 19 | iam\_ssl Module 20 | --------------- 21 | 22 | iam\_user Module 23 | ---------------- 24 | 25 | rds\_security\_group Module 26 | --------------------------- 27 | 28 | redshift Module 29 | --------------- 30 | 31 | s3 Module 32 | --------- 33 | 34 | security\_group Module 35 | ---------------------- 36 | 37 | ses Module 38 | ---------- 39 | 40 | sns Module 41 | ---------- 42 | -------------------------------------------------------------------------------- /docs/api/security_monkey.common.md: -------------------------------------------------------------------------------- 1 | common Package 2 | ============== 3 | 4 | common Package 5 | -------------- 6 | 7 | jinja Module 8 | ------------ 9 | 10 | route53 Module 11 | -------------- 12 | 13 | sts\_connect Module 14 | ------------------- 15 | 16 | Subpackages 17 | ----------- 18 | -------------------------------------------------------------------------------- /docs/api/security_monkey.common.utils.md: -------------------------------------------------------------------------------- 1 | utils Package 2 | ============= 3 | 4 | utils Package 5 | ------------- 6 | 7 | PolicyDiff Module 8 | ----------------- 9 | 10 | utils Module 11 | ------------ 12 | -------------------------------------------------------------------------------- /docs/api/security_monkey.md: -------------------------------------------------------------------------------- 1 | security\_monkey Package 2 | ======================== 3 | 4 | security\_monkey Package 5 | ------------------------ 6 | 7 | alerter Module 8 | -------------- 9 | 10 | auditor Module 11 | -------------- 12 | 13 | constants Module 14 | ---------------- 15 | 16 | datastore Module 17 | ---------------- 18 | 19 | decorators Module 20 | ----------------- 21 | 22 | exceptions Module 23 | ----------------- 24 | 25 | monitors Module 26 | --------------- 27 | 28 | reporter Module 29 | --------------- 30 | 31 | scheduler Module 32 | ---------------- 33 | 34 | watcher Module 35 | -------------- 36 | 37 | Subpackages 38 | ----------- 39 | -------------------------------------------------------------------------------- /docs/api/security_monkey.tests.md: -------------------------------------------------------------------------------- 1 | tests Package 2 | ============= 3 | 4 | tests Package 5 | ------------- 6 | 7 | test\_s3 Module 8 | --------------- 9 | 10 | test\_sns Module 11 | ---------------- 12 | -------------------------------------------------------------------------------- /docs/api/security_monkey.views.md: -------------------------------------------------------------------------------- 1 | views Package 2 | ============= 3 | 4 | views Package 5 | ------------- 6 | 7 | account Module 8 | -------------- 9 | 10 | distinct Module 11 | --------------- 12 | 13 | ignore\_list Module 14 | ------------------- 15 | 16 | item Module 17 | ----------- 18 | 19 | item\_comment Module 20 | -------------------- 21 | 22 | item\_issue Module 23 | ------------------ 24 | 25 | item\_issue\_justification Module 26 | --------------------------------- 27 | 28 | logout Module 29 | ------------- 30 | 31 | revision Module 32 | --------------- 33 | 34 | revision\_comment Module 35 | ------------------------ 36 | 37 | user\_settings Module 38 | --------------------- 39 | 40 | whitelist Module 41 | ---------------- 42 | -------------------------------------------------------------------------------- /docs/api/security_monkey.watchers.md: -------------------------------------------------------------------------------- 1 | watchers Package 2 | ================ 3 | 4 | watchers Package 5 | ---------------- 6 | 7 | elastic\_ip Module 8 | ------------------ 9 | 10 | elb Module 11 | ---------- 12 | 13 | iam\_group Module 14 | ----------------- 15 | 16 | iam\_role Module 17 | ---------------- 18 | 19 | iam\_ssl Module 20 | --------------- 21 | 22 | iam\_user Module 23 | ---------------- 24 | 25 | keypair Module 26 | -------------- 27 | 28 | rds\_security\_group Module 29 | --------------------------- 30 | 31 | redshift Module 32 | --------------- 33 | 34 | s3 Module 35 | --------- 36 | 37 | security\_group Module 38 | ---------------------- 39 | 40 | ses Module 41 | ---------- 42 | 43 | sns Module 44 | ---------- 45 | 46 | sqs Module 47 | ---------- 48 | -------------------------------------------------------------------------------- /docs/architecture.md: -------------------------------------------------------------------------------- 1 | What does the Security Monkey architecture look like? 2 | --------------- 3 | Security Monkey operates in a hub-spoke type of model where Security Monkey lives in one account, 4 | but then "reaches into" other accounts to describe and collect details. 5 | 6 | More details on this are outlined in the IAM section for each respective infrastructure. 7 | 8 | The components that make up Security Monkey are as follows (not AWS specific): 9 | ![diagram](images/sm_instance_diagram.png) 10 | 11 | All of the components in the diagram should reside within the same account and region. 12 | 13 | IAM Permissions Access Diagram 14 | ------------ 15 | Security Monkey accesses accounts to scan via credentials it is provided ("Role Assumption" where available). 16 | ![diagram](images/sm_iam_diagram.png) 17 | -------------------------------------------------------------------------------- /docs/images/SES_LIMITED.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/SES_LIMITED.png -------------------------------------------------------------------------------- /docs/images/Security_Monkey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/Security_Monkey.png -------------------------------------------------------------------------------- /docs/images/add_user_to_service_account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/add_user_to_service_account.png -------------------------------------------------------------------------------- /docs/images/aws_rds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/aws_rds.png -------------------------------------------------------------------------------- /docs/images/check_score_with_pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/check_score_with_pattern.png -------------------------------------------------------------------------------- /docs/images/colored_JSON.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/colored_JSON.png -------------------------------------------------------------------------------- /docs/images/create_inline_policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/create_inline_policy.png -------------------------------------------------------------------------------- /docs/images/create_instance_profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/create_instance_profile.png -------------------------------------------------------------------------------- /docs/images/create_pattern_check_score.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/create_pattern_check_score.png -------------------------------------------------------------------------------- /docs/images/create_role.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/create_role.png -------------------------------------------------------------------------------- /docs/images/create_service_account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/create_service_account.png -------------------------------------------------------------------------------- /docs/images/created_check_score.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/created_check_score.png -------------------------------------------------------------------------------- /docs/images/disable_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/disable_check.png -------------------------------------------------------------------------------- /docs/images/edit_trust_relationship.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/edit_trust_relationship.png -------------------------------------------------------------------------------- /docs/images/empty_create_account_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/empty_create_account_page.png -------------------------------------------------------------------------------- /docs/images/empty_settings_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/empty_settings_page.png -------------------------------------------------------------------------------- /docs/images/filtered_search_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/filtered_search_1.png -------------------------------------------------------------------------------- /docs/images/github_scopes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/github_scopes.png -------------------------------------------------------------------------------- /docs/images/issues_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/issues_page.png -------------------------------------------------------------------------------- /docs/images/item_with_issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/item_with_issue.png -------------------------------------------------------------------------------- /docs/images/justified_issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/justified_issue.png -------------------------------------------------------------------------------- /docs/images/linked_issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/linked_issue.png -------------------------------------------------------------------------------- /docs/images/new_cache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/new_cache.png -------------------------------------------------------------------------------- /docs/images/new_security_group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/new_security_group.png -------------------------------------------------------------------------------- /docs/images/override_check_score.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/override_check_score.png -------------------------------------------------------------------------------- /docs/images/override_sg_egress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/override_sg_egress.png -------------------------------------------------------------------------------- /docs/images/rds_sg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/rds_sg.png -------------------------------------------------------------------------------- /docs/images/resized_launch_instance_with_role.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/resized_launch_instance_with_role.png -------------------------------------------------------------------------------- /docs/images/resized_launched_sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/resized_launched_sm.png -------------------------------------------------------------------------------- /docs/images/resized_login_page-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/resized_login_page-1.png -------------------------------------------------------------------------------- /docs/images/resized_register-page-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/resized_register-page-1.png -------------------------------------------------------------------------------- /docs/images/resized_role_confirmation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/resized_role_confirmation.png -------------------------------------------------------------------------------- /docs/images/resized_select_ec2_instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/resized_select_ec2_instance.png -------------------------------------------------------------------------------- /docs/images/resized_settings_link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/resized_settings_link.png -------------------------------------------------------------------------------- /docs/images/resized_ubuntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/resized_ubuntu.png -------------------------------------------------------------------------------- /docs/images/revision_comments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/revision_comments.png -------------------------------------------------------------------------------- /docs/images/search_for_instance_profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/search_for_instance_profile.png -------------------------------------------------------------------------------- /docs/images/search_results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/search_results.png -------------------------------------------------------------------------------- /docs/images/security_group_devel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/security_group_devel.png -------------------------------------------------------------------------------- /docs/images/security_monkey_roles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/security_monkey_roles.png -------------------------------------------------------------------------------- /docs/images/securitygroup_details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/securitygroup_details.png -------------------------------------------------------------------------------- /docs/images/select_custom_policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/select_custom_policy.png -------------------------------------------------------------------------------- /docs/images/select_role_type.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/select_role_type.png -------------------------------------------------------------------------------- /docs/images/select_roles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/select_roles.png -------------------------------------------------------------------------------- /docs/images/ses_elastic_ip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/ses_elastic_ip.png -------------------------------------------------------------------------------- /docs/images/ses_sm_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/ses_sm_setting.png -------------------------------------------------------------------------------- /docs/images/ses_verify_domain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/ses_verify_domain.png -------------------------------------------------------------------------------- /docs/images/ses_verify_domain_pending.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/ses_verify_domain_pending.png -------------------------------------------------------------------------------- /docs/images/skip_attach_policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/skip_attach_policy.png -------------------------------------------------------------------------------- /docs/images/sm_create_role.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/sm_create_role.png -------------------------------------------------------------------------------- /docs/images/sm_iam_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/sm_iam_diagram.png -------------------------------------------------------------------------------- /docs/images/sm_instance_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/docs/images/sm_instance_diagram.png -------------------------------------------------------------------------------- /docs/installation/01-launch-instance.md: -------------------------------------------------------------------------------- 1 | Launch an Instance: 2 | ------------------- 3 | 4 | - [docker instructions](../docker.md). 5 | - [Launch an AWS instance](../instance_launch_aws.md). 6 | - [Launch a GCP instance](../instance_launch_gcp.md). 7 | - [Launch an OpenStack instance](../instance_launch_openstack.md). 8 | 9 | -- 10 | ### Next step: [Create a database instance](02-create-db.md) 11 | -- -------------------------------------------------------------------------------- /docs/installation/02-create-db.md: -------------------------------------------------------------------------------- 1 | Database 2 | -------- 3 | 4 | Security Monkey needs a postgres database. Select one of the following: 5 | 6 | - Local Postgres (You'll set this up later once you have an instance up.). 7 | - [Postgres on AWS RDS](../postgres_aws.md). 8 | - [Postgres on GCP's Cloud SQL](../postgres_gcp.md). 9 | - Currently OpenStack utilizes a local postgres database. 10 | 11 | -- 12 | ### Next step: [Install Security Monkey on your server instance](03-install-sm.md) 13 | -- -------------------------------------------------------------------------------- /docs/installation/05-ssl.md: -------------------------------------------------------------------------------- 1 | Create an SSL Certificate 2 | ------------------------- 3 | 4 | For this quickstart guide, we will use a self-signed SSL certificate. In production, you will want to use a certificate that has been signed by a trusted certificate authority.: 5 | 6 | $ cd ~ 7 | 8 | There are some great instructions for generating a certificate on the Ubuntu website: 9 | 10 | [Ubuntu - Create a Self Signed SSL Certificate](https://help.ubuntu.com/14.04/serverguide/certificates-and-security.html) 11 | 12 | The last commands you need to run from that tutorial are in the "Installing the Certificate" section: 13 | 14 | ~~~~ {.sourceCode .bash} 15 | sudo cp server.crt /etc/ssl/certs 16 | sudo cp server.key /etc/ssl/private 17 | ~~~~ 18 | 19 | Once you have finished the instructions at the link above, and these two files are in your /etc/ssl/certs and /etc/ssl/private, you are ready to move on in this guide. 20 | 21 | -- 22 | ### Next step: [Setup Nginx](06-nginx.md) 23 | -- -------------------------------------------------------------------------------- /docs/installation/06-nginx.md: -------------------------------------------------------------------------------- 1 | Setup Nginx: 2 | ------------ 3 | 4 | Security Monkey uses gunicorn to serve up content on its internal 127.0.0.1 address. For better performance, and to offload the work of serving static files, we wrap gunicorn with nginx. Nginx listens on 0.0.0.0 and proxies some connections to gunicorn for processing and serves up static files quickly. 5 | 6 | ### securitymonkey.conf 7 | 8 | Copy the config file into place: 9 | 10 | sudo cp /usr/local/src/security_monkey/nginx/security_monkey.conf /etc/nginx/sites-available/security_monkey.conf 11 | sudo ln -s /etc/nginx/sites-available/security_monkey.conf /etc/nginx/sites-enabled/security_monkey.conf 12 | sudo rm /etc/nginx/sites-enabled/default 13 | sudo service nginx restart 14 | 15 | ### Start the API server 16 | 17 | Manually start Security Monkey with `monkey run_api_server`. Setting up autostart is explained later in this documentation. 18 | 19 | -- 20 | ### Next step: [Login to Security Monkey & load data](07-load-data.md) 21 | -- 22 | -------------------------------------------------------------------------------- /docs/installation/07-load-data.md: -------------------------------------------------------------------------------- 1 | Logging into the UI 2 | ------------------- 3 | 4 | You should now be able to reach your server 5 | 6 | ![image](../images/resized_login_page-1.png) 7 | 8 | Loading Data into Security Monkey 9 | -------------------------------- 10 | To initially get data into Security Monkey, you can run the `monkey find_changes` command. This will go through 11 | all your configured accounts in Security Monkey, fetch details about the accounts, store them into the database, 12 | and then audit the items for any issues. 13 | 14 | The `find_changes` command can be further scoped to account and technology with the `-a account` and `-m technology` parameters. 15 | 16 | *Note:* This is good for loading some initial data to play around with, however, you will want to configure jobs to automatically 17 | scan your environment periodically for changes. Please read the next section for details. 18 | 19 | 🚨 Important 🚨 - Autostarting and Fetching Data 20 | -------------------------------- 21 | At this point Security Monkey is set to manually run. However, we need to ensure that it is always running and automatically 22 | fetching data from your environment. 23 | 24 | Please review the next section titled [Autostarting Security Monkey](../autostarting.md) for details. Please note, this section 25 | is very important and involved, so please pay close attention to the details. -------------------------------------------------------------------------------- /docs/instance_launch_gcp.md: -------------------------------------------------------------------------------- 1 | Launch a GCP instance 2 | ===================== 3 | 4 | Create an instance running Ubuntu 16.04 LTS using our 'securitymonkey' service account. 5 | 6 | Navigate to the [Create Instance page](https://console.developers.google.com/compute/instancesAdd). Fill in the following fields: 7 | 8 | - **Name**: securitymonkey 9 | - **Zone**: If using GCP Cloud SQL, select the same zone here. [(Zone List)](https://cloud.google.com/compute/docs/regions-zones/regions-zones#available) 10 | - **Machine Type**: 1vCPU, 3.75GB (minimum; also known as n1-standard-1) 11 | - **Boot Disk**: Ubuntu 16.04 LTS 12 | - **Service Account**: securitymonkey (This is provisioned in the [IAM GCP instructions](https://github.com/Netflix/security_monkey/blob/develop/docs/iam_gcp.md).) 13 | - **Firewall**: Allow HTTPS Traffic 14 | 15 | Click the *Create* button to create the instance. 16 | 17 | Install gcloud 18 | -------------- 19 | 20 | If you haven't already, install *gcloud* from the [downloads](https://cloud.google.com/sdk/downloads) page. *gcloud* enables you to administer VMs, IAM policies, services and more from the command line. 21 | 22 | Connecting to your new instance: 23 | -------------------------------- 24 | 25 | We will connect to the new instance over ssh with the gcloud command: 26 | 27 | $ gcloud compute ssh securitymonkey --zone 28 | 29 | 30 | Next: 31 | ----- 32 | 33 | - [Back to the Quickstart](quickstart.md#install-security-monkey-on-your-instance) 34 | -------------------------------------------------------------------------------- /docs/instance_launch_openstack.md: -------------------------------------------------------------------------------- 1 | Launch an OpenStack instance 2 | ============================ 3 | 4 | Orchestrate an instance (via Horizon/Heat/APIs). Below are some guidelines. Your cloud setup, conventions, and policies will dictate specifics. 5 | 6 | - **Source**: Ubuntu LTS (14.04 or 16.04) source 7 | - **Machine Type**: m1.medium or equivalent (3.75GB RAM minimum) 8 | - **Security Group**: Allow appropriately restricted ingress HTTPS and SSH. For egress, allow access to the OpenStack service API endpoints (in Horizon, found under API Access details) and for the initial Security Monkey installation you will access to the Internet/proxy. 9 | 10 | 11 | Connecting to your new instance: 12 | -------------------------------- 13 | 14 | We will connect to the new instance over ssh: 15 | 16 | $ ssh -i -l ubuntu 17 | 18 | Replace the PRIVATE_KEY parameter with the private key for your keypair assigned in instance creation 19 | Replace the IP_ADDRESS with the IP address of your instance (public or floating ip, depending on network assignment) 20 | 21 | 22 | Next: 23 | ----- 24 | 25 | - [Back to the Quickstart](quickstart.md#install-security-monkey-on-your-instance) 26 | -------------------------------------------------------------------------------- /docs/issue_template.md: -------------------------------------------------------------------------------- 1 | ## Please make sure that you have checked the boxes: 2 | 3 | - [ ] [Pease review the Troubleshooting doc for additional details regarding your issue.](https://github.com/Netflix/security_monkey/blob/develop/docs/troubleshooting.md) 4 | - [ ] Review the [Quickstart guide](https://github.com/Netflix/security_monkey/blob/develop/docs/quickstart.md) 5 | - [ ] [Search for both open and closed issues](https://github.com/Netflix/security_monkey/issues?&q=is%3Aissue+) regarding the problem you are experiencing 6 | - [ ] **For permissions issues** (Access Denied and credential related errors), please refer to the requisite docs before submitting an issue: 7 | [AWS](https://github.com/Netflix/security_monkey/blob/develop/docs/iam_aws.md), [GCP](https://github.com/Netflix/security_monkey/blob/develop/docs/iam_gcp.md), [OpenStack](https://github.com/Netflix/security_monkey/blob/develop/docs/iam_openstack.md), [GitHub](https://github.com/Netflix/security_monkey/blob/develop/docs/github_setup.md#access-keys-and-permissions) 8 | 9 | 10 | ## Description of issue: 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/plugins.md: -------------------------------------------------------------------------------- 1 | Plugins 2 | ======= 3 | 4 | Security Monkey can be extended by writing own Account Managers, Watchers and Auditors. To do this you need to create a subclass of either `security_monkey.account_manager.AccountManager`, `security_monkey.watcher.Watcher` or `security_monkey.auditor.Auditor`. 5 | 6 | To make extension available to Security Monkey it should have entry point under group `security_monkey.plugins`. 7 | 8 | Sample AccountManager plugin 9 | ---------------------------- 10 | 11 | Assume we have a file account.py in directory my\_sm\_plugins/my\_sm\_plugins/account.py: 12 | 13 | ~~~~ {.sourceCode .python} 14 | from security_monkey.account_manager import AccountManager 15 | 16 | class MyAccountManager(AccountManager): 17 | pass 18 | ~~~~ 19 | 20 | NOTE: there also shoule be file my\_sm\_plugins/my\_sm\_plugins/\_\_init\_\_.py 21 | 22 | And we have a file setup.py in directory my\_sm\_plugins: 23 | 24 | ~~~~ {.sourceCode .python} 25 | from setuptools import setup, find_packages 26 | 27 | setup( 28 | name="my_sm_plugins", 29 | version="0.1-dev0", 30 | packages=find_packages(), 31 | include_package_data=True, 32 | install_requires=["security_monkey"], 33 | entry_points={ 34 | "security_monkey.plugins": [ 35 | "my_sm_plugins.account = my_sm_plugins.account", 36 | ] 37 | } 38 | ) 39 | ~~~~ 40 | 41 | Then we can install `my_sm_plugins` package and have security\_monkey with our plugin available. 42 | -------------------------------------------------------------------------------- /env_tests/test_dart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ########################################## 3 | # Copyright 2015 Netflix, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ########################################## 17 | # 18 | # Script to test Dart installation for Security Monkey 19 | # 20 | ########################################## 21 | 22 | DART_DOWNLOAD_LOCATION="https://storage.googleapis.com/dart-archive/channels/stable/release/1.16.1/sdk/dartsdk-linux-x64-release.zip" 23 | 24 | echo "Getting Dart..." 25 | wget $DART_DOWNLOAD_LOCATION -O 'dartsdk-linux-x64-release.zip' 26 | 27 | echo "Unzipping Dart..." 28 | unzip "dartsdk-linux-x64-release.zip" > /dev/null 29 | 30 | echo Setting up the environment variables 31 | export DART_SDK="$PWD/dart-sdk" 32 | export PATH="$DART_SDK/bin:$PATH" 33 | 34 | echo "Building the dart deps..." 35 | cd dart 36 | pub get 37 | pub build --mode=debug 38 | -------------------------------------------------------------------------------- /migrations/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /migrations/alembic.ini: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # template used to generate migration files 5 | # file_template = %%(rev)s_%%(slug)s 6 | 7 | # set to 'true' to run the environment during 8 | # the 'revision' command, regardless of autogenerate 9 | # revision_environment = false 10 | 11 | 12 | # Logging configuration 13 | [loggers] 14 | keys = root,sqlalchemy,alembic 15 | 16 | [handlers] 17 | keys = console 18 | 19 | [formatters] 20 | keys = generic 21 | 22 | [logger_root] 23 | level = WARN 24 | handlers = console 25 | qualname = 26 | 27 | [logger_sqlalchemy] 28 | level = WARN 29 | handlers = 30 | qualname = sqlalchemy.engine 31 | 32 | [logger_alembic] 33 | level = INFO 34 | handlers = 35 | qualname = alembic 36 | 37 | [handler_console] 38 | class = StreamHandler 39 | args = (sys.stderr,) 40 | level = NOTSET 41 | formatter = generic 42 | 43 | [formatter_generic] 44 | format = %(levelname)-5.5s [%(name)s] %(message)s 45 | datefmt = %H:%M:%S 46 | -------------------------------------------------------------------------------- /migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = ${repr(up_revision)} 11 | down_revision = ${repr(down_revision)} 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | ${imports if imports else ""} 16 | 17 | def upgrade(): 18 | ${upgrades if upgrades else "pass"} 19 | 20 | 21 | def downgrade(): 22 | ${downgrades if downgrades else "pass"} 23 | -------------------------------------------------------------------------------- /migrations/versions/00c1dabdbe85_lengthen_account_name.py: -------------------------------------------------------------------------------- 1 | """lengthen Account.name 2 | 3 | Revision ID: 00c1dabdbe85 4 | Revises: ea2739ecd874 5 | Create Date: 2018-03-09 14:29:17.620533 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '00c1dabdbe85' 11 | down_revision = 'ea2739ecd874' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | op.alter_column('account', 'name', 19 | existing_type=sa.VARCHAR(length=32), 20 | type_=sa.String(length=50), 21 | existing_nullable=True) 22 | 23 | 24 | def downgrade(): 25 | op.alter_column('account', 'name', 26 | existing_type=sa.VARCHAR(length=50), 27 | type_=sa.String(length=32), 28 | existing_nullable=True) 29 | -------------------------------------------------------------------------------- /migrations/versions/0ae4ef82b244_.py: -------------------------------------------------------------------------------- 1 | """Distinguishes items created by different auditors of the same type 2 | 3 | Revision ID: 0ae4ef82b244 4 | Revises: ad23a56abf25 5 | Create Date: 2016-03-25 19:07:11.312390 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '0ae4ef82b244' 11 | down_revision = '6245d75fa12' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.add_column('auditorsettings', sa.Column('auditor_class', sa.String(length=128), nullable=True)) 20 | ### end Alembic commands ### 21 | 22 | 23 | def downgrade(): 24 | ### commands auto generated by Alembic - please adjust! ### 25 | op.drop_column('auditorsettings', 'auditor_class') 26 | ### end Alembic commands ### 27 | -------------------------------------------------------------------------------- /migrations/versions/1583a48cb978_.py: -------------------------------------------------------------------------------- 1 | """Adding Unique Index to TechName and AccountName 2 | 3 | Revision ID: 1583a48cb978 4 | Revises: c93f246859f7 5 | Create Date: 2017-03-16 14:01:37.463000 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '1583a48cb978' 11 | down_revision = 'c93f246859f7' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | # ### commands auto generated by Alembic - please adjust! ### 19 | op.create_index('ix_account_name', 'account', ['name'], unique=True) 20 | op.drop_constraint(u'account_name_uc', 'account', type_='unique') 21 | op.create_index('ix_technology_name', 'technology', ['name'], unique=True) 22 | # ### end Alembic commands ### 23 | 24 | 25 | def downgrade(): 26 | # ### commands auto generated by Alembic - please adjust! ### 27 | op.drop_index('ix_technology_name', table_name='technology') 28 | op.create_unique_constraint(u'account_name_uc', 'account', ['name']) 29 | op.drop_index('ix_account_name', table_name='account') 30 | # ### end Alembic commands ### 31 | -------------------------------------------------------------------------------- /migrations/versions/15e39d43395f_.py: -------------------------------------------------------------------------------- 1 | """Expand the Hash fields due to the adoption of DeepHash 2 | 3 | Revision ID: 15e39d43395f 4 | Revises: 7c54b06e227b 5 | Create Date: 2020-09-07 12:29:37.391979 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '15e39d43395f' 11 | down_revision = '7c54b06e227b' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | """This revision is going to expand the hash database fields from `varchar(32)` to `varchar(64)`. Due to the usage of DeepHash. 19 | Note: This is going to result in all change items getting re-updated as the hashes are going to be different. 20 | """ 21 | op.alter_column('item', 'latest_revision_complete_hash', type_=sa.VARCHAR(64), existing_type=sa.VARCHAR(length=32), existing_nullable=True) 22 | op.alter_column('item', 'latest_revision_durable_hash', type_=sa.VARCHAR(64), existing_type=sa.VARCHAR(length=32), existing_nullable=True) 23 | 24 | 25 | def downgrade(): 26 | # No downgrading is possible for this DB revision. 27 | raise ValueError("You cannot downgrade from this DB revision!! Sorry!") 28 | # op.alter_column('item', 'latest_revision_complete_hash', type_=sa.VARCHAR(32), existing_type=sa.VARCHAR(length=64), existing_nullable=True) 29 | # op.alter_column('item', 'latest_revision_durable_hash', type_=sa.VARCHAR(32), existing_type=sa.VARCHAR(length=64), existing_nullable=True) 30 | -------------------------------------------------------------------------------- /migrations/versions/1727fb4309d8_.py: -------------------------------------------------------------------------------- 1 | """Updating max length of s3_name in account table 2 | 3 | Revision ID: 1727fb4309d8 4 | Revises: 51170afa2b48 5 | Create Date: 2015-07-06 12:29:48.859104 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '1727fb4309d8' 11 | down_revision = '51170afa2b48' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.alter_column('account', 's3_name', type_=sa.VARCHAR(64), existing_type=sa.VARCHAR(length=32), nullable=True) 20 | ### end Alembic commands ### 21 | 22 | 23 | def downgrade(): 24 | ### commands auto generated by Alembic - please adjust! ### 25 | op.alter_column('account', 's3_name', type_=sa.VARCHAR(32), existing_type=sa.VARCHAR(length=64), nullable=True) 26 | ### end Alembic commands ### 27 | -------------------------------------------------------------------------------- /migrations/versions/1a863bd1acb1_.py: -------------------------------------------------------------------------------- 1 | """Renaming rds to rdssecuritygroup 2 | 3 | Revision ID: 1a863bd1acb1 4 | Revises: 0ae4ef82b244 5 | Create Date: 2016-09-20 20:22:19.687138 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '1a863bd1acb1' 11 | down_revision = '0ae4ef82b244' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | from sqlalchemy.orm import sessionmaker 16 | from sqlalchemy.ext.declarative import declarative_base 17 | 18 | 19 | Session = sessionmaker() 20 | Base = declarative_base() 21 | 22 | 23 | class Technology(Base): 24 | __tablename__ = 'technology' 25 | id = sa.Column(sa.Integer, primary_key=True) 26 | name = sa.Column(sa.String(32)) 27 | 28 | 29 | def upgrade(): 30 | bind = op.get_bind() 31 | session = Session(bind=bind) 32 | rds_tech = session.query(Technology).filter(Technology.name == 'rds').first() 33 | if rds_tech: 34 | rds_tech.name = 'rdssecuritygroup' 35 | session.commit() 36 | 37 | 38 | def downgrade(): 39 | bind = op.get_bind() 40 | session = Session(bind=bind) 41 | rds_tech = session.query(Technology).filter(Technology.name == 'rdssecuritygroup').first() 42 | if rds_tech: 43 | rds_tech.name = 'rds' 44 | session.commit() 45 | -------------------------------------------------------------------------------- /migrations/versions/1c847ae1209a_.py: -------------------------------------------------------------------------------- 1 | """Increase note max size 2 | 3 | Revision ID: 1c847ae1209a 4 | Revises: bbd695323107 5 | Create Date: 2016-07-29 11:18:00.550197 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '1c847ae1209a' 11 | down_revision = '2ce75615b24d' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.alter_column('itemaudit', 'notes', type_=sa.VARCHAR(1024), existing_type=sa.VARCHAR(length=512), nullable=True) 20 | ### end Alembic commands ### 21 | 22 | 23 | def downgrade(): 24 | ### commands auto generated by Alembic - please adjust! ### 25 | op.alter_column('itemaudit', 'notes', type_=sa.VARCHAR(512), existing_type=sa.VARCHAR(length=1024), nullable=True) 26 | ### end Alembic commands ### 27 | -------------------------------------------------------------------------------- /migrations/versions/2705e6e13a8f_.py: -------------------------------------------------------------------------------- 1 | """Adding the ignorelist table. 2 | 3 | Revision ID: 2705e6e13a8f 4 | Revises: fb592c81e71 5 | Create Date: 2014-11-01 19:02:35.149559 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '2705e6e13a8f' 11 | down_revision = 'fb592c81e71' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.create_table('ignorelist', 20 | sa.Column('id', sa.Integer(), nullable=False), 21 | sa.Column('prefix', sa.String(length=512), nullable=True), 22 | sa.Column('notes', sa.String(length=512), nullable=True), 23 | sa.Column('tech_id', sa.Integer(), nullable=False), 24 | sa.ForeignKeyConstraint(['tech_id'], ['technology.id'], ), 25 | sa.PrimaryKeyConstraint('id') 26 | ) 27 | ### end Alembic commands ### 28 | 29 | 30 | def downgrade(): 31 | ### commands auto generated by Alembic - please adjust! ### 32 | op.drop_table('ignorelist') 33 | ### end Alembic commands ### 34 | -------------------------------------------------------------------------------- /migrations/versions/2ea41f4610fd_.py: -------------------------------------------------------------------------------- 1 | """Increasing size of name field to accomodate longer AWS Resource IDs 2 | 3 | Revision ID: 2ea41f4610fd 4 | Revises: 1727fb4309d8 5 | Create Date: 2016-04-18 17:59:04.622111 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '2ea41f4610fd' 11 | down_revision = '1727fb4309d8' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.alter_column('item', 'name', type_=sa.VARCHAR(303), existing_type=sa.VARCHAR(length=285), nullable=True) 20 | ### end Alembic commands ### 21 | 22 | 23 | def downgrade(): 24 | ### commands auto generated by Alembic - please adjust! ### 25 | op.alter_column('item', 'name', type_=sa.VARCHAR(285), existing_type=sa.VARCHAR(length=303), nullable=True) 26 | ### end Alembic commands ### 27 | -------------------------------------------------------------------------------- /migrations/versions/331ca47ce8ad_.py: -------------------------------------------------------------------------------- 1 | """Updating max length of Item name from 128 characters to 285. AWS Max size is 255. Add 30 chars for Security_monkey specific metadata. 2 | 3 | Revision ID: 331ca47ce8ad 4 | Revises: c01df2202a9 5 | Create Date: 2014-08-26 12:40:02.577519 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '331ca47ce8ad' 11 | down_revision = 'c01df2202a9' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | op.alter_column('item', 'name', type_=sa.String(285), existing_type=sa.String(length=128), nullable=True) 19 | 20 | 21 | def downgrade(): 22 | op.alter_column('item', 'name', type_=sa.String(128), existing_type=sa.String(length=285), nullable=True) 23 | 24 | -------------------------------------------------------------------------------- /migrations/versions/4ac52090a637_.py: -------------------------------------------------------------------------------- 1 | """Adding a fixed flag to the issue table 2 | 3 | Revision ID: 4ac52090a637 4 | Revises: daee17da2abd 5 | Create Date: 2017-09-14 23:24:40.967949 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '4ac52090a637' 11 | down_revision = 'daee17da2abd' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | # ### commands auto generated by Alembic - please adjust! ### 19 | op.add_column('itemaudit', sa.Column('fixed', sa.Boolean(), nullable=True)) 20 | # ### end Alembic commands ### 21 | 22 | 23 | def downgrade(): 24 | # ### commands auto generated by Alembic - please adjust! ### 25 | op.drop_column('itemaudit', 'fixed') 26 | # ### end Alembic commands ### -------------------------------------------------------------------------------- /migrations/versions/51170afa2b48_custom_role_name.py: -------------------------------------------------------------------------------- 1 | """custom role name 2 | 3 | Revision ID: 51170afa2b48 4 | Revises: 595e27f36454 5 | Create Date: 2015-03-11 16:29:51.037379 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '51170afa2b48' 11 | down_revision = '595e27f36454' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.add_column('account', sa.Column('role_name', sa.String(length=256), nullable=True)) 20 | ### end Alembic commands ### 21 | 22 | 23 | def downgrade(): 24 | ### commands auto generated by Alembic - please adjust! ### 25 | op.drop_column('account', 'role_name') 26 | ### end Alembic commands ### 27 | -------------------------------------------------------------------------------- /migrations/versions/538eeb160af6_.py: -------------------------------------------------------------------------------- 1 | """Adding role column to user table 2 | 3 | Revision ID: 538eeb160af6 4 | Revises: 6b9d673d8e30 5 | Create Date: 2015-09-17 04:22:21.262285 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '538eeb160af6' 11 | down_revision = '6b9d673d8e30' 12 | 13 | from alembic import op 14 | from flask_sqlalchemy import _SessionSignalEvents 15 | import sqlalchemy as sa 16 | from sqlalchemy import event 17 | from sqlalchemy.ext.declarative import declarative_base 18 | from sqlalchemy.orm import sessionmaker, Session as BaseSession, relationship 19 | 20 | Session = sessionmaker() 21 | 22 | #event.remove(BaseSession, 'before_commit', _SessionSignalEvents.session_signal_before_commit) 23 | #event.remove(BaseSession, 'after_commit', _SessionSignalEvents.session_signal_after_commit) 24 | #event.remove(BaseSession, 'after_rollback', _SessionSignalEvents.session_signal_after_rollback) 25 | 26 | Base = declarative_base() 27 | 28 | class User(Base): 29 | __tablename__ = 'user' 30 | id = sa.Column(sa.Integer, primary_key=True) 31 | active = sa.Column(sa.Boolean()) 32 | role = sa.Column(sa.String(30), default="View") 33 | 34 | 35 | def upgrade(): 36 | ### commands auto generated by Alembic - please adjust! ### 37 | ### end Alembic commands ### 38 | 39 | bind = op.get_bind() 40 | session = Session(bind=bind) 41 | op.add_column('user', sa.Column('role', sa.String(length=30), nullable=True)) 42 | for user in session.query(User): 43 | if user.active: 44 | user.role = 'View' 45 | 46 | session.commit() 47 | 48 | 49 | def downgrade(): 50 | ### commands auto generated by Alembic - please adjust! ### 51 | op.drop_column('user', 'role') 52 | ### end Alembic commands ### 53 | -------------------------------------------------------------------------------- /migrations/versions/57f648d4b597_.py: -------------------------------------------------------------------------------- 1 | """Add auditorsettings 2 | 3 | Revision ID: 57f648d4b597 4 | Revises: 2705e6e13a8f 5 | Create Date: 2015-01-30 22:32:18.420819 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '57f648d4b597' 11 | down_revision = '2705e6e13a8f' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.create_table('auditorsettings', 20 | sa.Column('id', sa.Integer(), nullable=False), 21 | sa.Column('tech_id', sa.Integer(), nullable=True), 22 | sa.Column('notes', sa.String(length=512), nullable=True), 23 | sa.Column('account_id', sa.Integer(), nullable=True), 24 | sa.Column('disabled', sa.Boolean(), nullable=False), 25 | sa.Column('issue', sa.String(length=512), nullable=False), 26 | sa.ForeignKeyConstraint(['account_id'], ['account.id'], ), 27 | sa.ForeignKeyConstraint(['tech_id'], ['technology.id'], ), 28 | sa.PrimaryKeyConstraint('id') 29 | ) 30 | ### end Alembic commands ### 31 | 32 | 33 | def downgrade(): 34 | ### commands auto generated by Alembic - please adjust! ### 35 | op.drop_table('auditorsettings') 36 | ### end Alembic commands ### 37 | -------------------------------------------------------------------------------- /migrations/versions/595e27f36454_.py: -------------------------------------------------------------------------------- 1 | """Optimizing the new AuditorSettings for faster setup, queries, pagination, and filtering. 2 | 3 | Revision ID: 595e27f36454 4 | Revises: 57f648d4b597 5 | Create Date: 2015-02-14 00:16:25.590209 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '595e27f36454' 11 | down_revision = '57f648d4b597' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | def upgrade(): 17 | ### commands auto generated by Alembic - please adjust! ### 18 | op.add_column('auditorsettings', sa.Column('issue_text', sa.String(length=512), nullable=True)) 19 | op.drop_column('auditorsettings', 'notes') 20 | op.drop_column('auditorsettings', 'issue') 21 | op.add_column('itemaudit', sa.Column('auditor_setting_id', sa.Integer(), nullable=True)) 22 | op.create_foreign_key(None, 'itemaudit', 'auditorsettings', ['auditor_setting_id'], ['id']) 23 | ### end Alembic commands ### 24 | 25 | 26 | def downgrade(): 27 | ### commands auto generated by Alembic - please adjust! ### 28 | op.drop_constraint(None, 'itemaudit', type_='foreignkey') 29 | op.drop_column('itemaudit', 'auditor_setting_id') 30 | op.add_column('auditorsettings', sa.Column('issue', sa.VARCHAR(length=512), autoincrement=False, nullable=False)) 31 | op.add_column('auditorsettings', sa.Column('notes', sa.VARCHAR(length=512), autoincrement=False, nullable=True)) 32 | op.drop_column('auditorsettings', 'issue_text') 33 | ### end Alembic commands ### 34 | -------------------------------------------------------------------------------- /migrations/versions/5bd631a1b748_.py: -------------------------------------------------------------------------------- 1 | """Updating fixed flag in the issue table to be not nullable. 2 | 3 | Revision ID: 5bd631a1b748 4 | Revises: 4ac52090a637 5 | Create Date: 2017-09-26 11:05:23.060909 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '5bd631a1b748' 11 | down_revision = '4ac52090a637' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | from sqlalchemy.orm import sessionmaker 17 | from sqlalchemy.ext.declarative import declarative_base 18 | 19 | 20 | Session = sessionmaker() 21 | Base = declarative_base() 22 | 23 | 24 | class ItemAudit(Base): 25 | __tablename__ = 'itemaudit' 26 | id = sa.Column(sa.Integer, primary_key=True) 27 | fixed = sa.Column(sa.Boolean) 28 | 29 | 30 | def upgrade(): 31 | bind = op.get_bind() 32 | session = Session(bind=bind) 33 | 34 | # update itemaudit set fixed = False where fixed is NULL 35 | session.query(ItemAudit).filter(ItemAudit.fixed==None).update(dict(fixed=False)) 36 | session.commit() 37 | 38 | # Make column not nullable: 39 | op.alter_column('itemaudit', 'fixed', nullable=False) 40 | 41 | 42 | def downgrade(): 43 | # Make column nullable: 44 | op.alter_column('itemaudit', 'fixed', nullable=True) -------------------------------------------------------------------------------- /migrations/versions/61a6fd4b4500_.py: -------------------------------------------------------------------------------- 1 | """Adding new fields to the User model for SECURITY_TRACKABLE 2 | 3 | Revision ID: 61a6fd4b4500 4 | Revises: 538eeb160af6 5 | Create Date: 2016-04-23 18:17:47.216434 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '61a6fd4b4500' 11 | down_revision = '538eeb160af6' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.add_column('user', sa.Column('current_login_at', sa.DateTime(), nullable=True)) 20 | op.add_column('user', sa.Column('current_login_ip', sa.String(length=45), nullable=True)) 21 | op.add_column('user', sa.Column('last_login_at', sa.DateTime(), nullable=True)) 22 | op.add_column('user', sa.Column('last_login_ip', sa.String(length=45), nullable=True)) 23 | op.add_column('user', sa.Column('login_count', sa.Integer(), nullable=True)) 24 | ### end Alembic commands ### 25 | 26 | 27 | def downgrade(): 28 | ### commands auto generated by Alembic - please adjust! ### 29 | op.drop_column('user', 'login_count') 30 | op.drop_column('user', 'last_login_ip') 31 | op.drop_column('user', 'last_login_at') 32 | op.drop_column('user', 'current_login_ip') 33 | op.drop_column('user', 'current_login_at') 34 | ### end Alembic commands ### 35 | 36 | -------------------------------------------------------------------------------- /migrations/versions/67ea2aac5ea0_.py: -------------------------------------------------------------------------------- 1 | """Adding itemauditscores table 2 | 3 | Revision ID: 67ea2aac5ea0 4 | Revises: 55725cc4bf25 5 | Create Date: 2016-01-26 21:43:10.398048 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '67ea2aac5ea0' 11 | down_revision = '55725cc4bf25' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.create_table('itemauditscores', 20 | sa.Column('id', sa.Integer(), nullable=False), 21 | sa.Column('technology', sa.String(length=128), nullable=False), 22 | sa.Column('method', sa.String(length=256), nullable=False), 23 | sa.Column('score', sa.Integer(), nullable=False), 24 | sa.Column('disabled', sa.Boolean(), nullable=True), 25 | sa.PrimaryKeyConstraint('id') 26 | ) 27 | 28 | op.create_unique_constraint('tech_method_uc', 'itemauditscores', ['technology', 'method']) 29 | ### end Alembic commands ### 30 | 31 | 32 | def downgrade(): 33 | ### commands auto generated by Alembic - please adjust! ### 34 | op.drop_table('itemauditscores') 35 | ### end Alembic commands ### 36 | -------------------------------------------------------------------------------- /migrations/versions/6b9d673d8e30_added_index_for_itemrevision_created.py: -------------------------------------------------------------------------------- 1 | """Added index for itemrevision created_date 2 | 3 | Revision ID: 6b9d673d8e30 4 | Revises: 2ea41f4610fd 5 | Create Date: 2016-04-01 09:39:35.148502 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '6b9d673d8e30' 11 | down_revision = '2ea41f4610fd' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | op.create_index('ix_itemrevision_date_created', 'itemrevision', ['date_created'], unique=False) 19 | 20 | 21 | def downgrade(): 22 | op.drop_index('ix_itemrevision_date_created', table_name='itemrevision') 23 | -------------------------------------------------------------------------------- /migrations/versions/6d2354fb841c_.py: -------------------------------------------------------------------------------- 1 | """Adding accountpatternauditscore table 2 | 3 | Revision ID: 6d2354fb841c 4 | Revises: 67ea2aac5ea0 5 | Create Date: 2016-06-21 19:58:12.949279 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '6d2354fb841c' 11 | down_revision = '67ea2aac5ea0' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.create_table('accountpatternauditscore', 20 | sa.Column('id', sa.Integer(), nullable=False), 21 | sa.Column('account_type', sa.String(length=80), nullable=False), 22 | sa.Column('account_field', sa.String(length=128), nullable=False), 23 | sa.Column('account_pattern', sa.String(length=128), nullable=False), 24 | sa.Column('score', sa.Integer(), nullable=False), 25 | sa.Column('itemauditscores_id', sa.Integer(), nullable=False), 26 | sa.ForeignKeyConstraint(['itemauditscores_id'], ['itemauditscores.id'], ), 27 | sa.PrimaryKeyConstraint('id') 28 | ) 29 | ### end Alembic commands ### 30 | 31 | 32 | def downgrade(): 33 | ### commands auto generated by Alembic - please adjust! ### 34 | op.drop_table('accountpatternauditscore') 35 | ### end Alembic commands ### 36 | -------------------------------------------------------------------------------- /migrations/versions/ad23a56abf25_.py: -------------------------------------------------------------------------------- 1 | """Ability to link issues to other tech type items 2 | 3 | Revision ID: ad23a56abf25 4 | Revises: 67ea2aac5ea0 5 | Create Date: 2016-02-23 18:52:45.024716 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = 'ad23a56abf25' 11 | down_revision = '1a863bd1acb1' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.create_table('issue_item_association', 20 | sa.Column('super_issue_id', sa.Integer(), nullable=True), 21 | sa.Column('sub_item_id', sa.Integer(), nullable=True), 22 | sa.ForeignKeyConstraint(['sub_item_id'], ['item.id'], ), 23 | sa.ForeignKeyConstraint(['super_issue_id'], ['itemaudit.id'], ) 24 | ) 25 | ### end Alembic commands ### 26 | 27 | 28 | def downgrade(): 29 | ### commands auto generated by Alembic - please adjust! ### 30 | op.drop_table('issue_item_association') 31 | ### end Alembic commands ### 32 | -------------------------------------------------------------------------------- /migrations/versions/ae5c0a6aebb3_.py: -------------------------------------------------------------------------------- 1 | """Adding ephemeral change datetime column to itemrevision. 2 | 3 | Revision ID: ae5c0a6aebb3 4 | Revises: 61a6fd4b4500 5 | Create Date: 2016-05-16 17:47:00.946859 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = 'ae5c0a6aebb3' 11 | down_revision = '61a6fd4b4500' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.add_column('itemrevision', sa.Column('date_last_ephemeral_change', sa.DateTime(), nullable=True)) 20 | op.create_index('ix_itemrevision_date_last_ephemeral_change', 'itemrevision', ['date_last_ephemeral_change'], unique=False) 21 | ### end Alembic commands ### 22 | 23 | 24 | def downgrade(): 25 | ### commands auto generated by Alembic - please adjust! ### 26 | op.drop_index('ix_itemrevision_date_last_ephemeral_change', table_name='itemrevision') 27 | op.drop_column('itemrevision', 'date_last_ephemeral_change') 28 | ### end Alembic commands ### 29 | -------------------------------------------------------------------------------- /migrations/versions/b8ccf5b8089b_.py: -------------------------------------------------------------------------------- 1 | """Please run "monkey fetch_aws_canonical_ids" 2 | 3 | Revision ID: b8ccf5b8089b 4 | Revises: 908b0085d28d 5 | Create Date: 2017-03-23 11:00:43.792538 6 | Author: Mike Grima , No-op'ed by Patrick 7 | 8 | """ 9 | 10 | # revision identifiers, used by Alembic. 11 | import sqlalchemy as sa 12 | 13 | from alembic import op 14 | from sqlalchemy.ext.declarative import declarative_base 15 | from sqlalchemy.orm import sessionmaker 16 | 17 | revision = 'b8ccf5b8089b' 18 | down_revision = '908b0085d28d' 19 | 20 | 21 | def upgrade(): 22 | # This revision has been replaced with a no-op after numerous reports of db upgrade problems. 23 | # We recommend you run: 24 | # monkey fetch_aws_canonical_ids 25 | pass 26 | 27 | 28 | def downgrade(): 29 | # No need to go back... 30 | pass 31 | -------------------------------------------------------------------------------- /migrations/versions/c93f246859f7_.py: -------------------------------------------------------------------------------- 1 | """Add watcher config table 2 | 3 | Revision ID: c93f246859f7 4 | Revises: 6d2354fb841c 5 | Create Date: 2016-09-29 16:13:29.946116 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = 'c93f246859f7' 11 | down_revision = '6d2354fb841c' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.create_table('watcher_config', 20 | sa.Column('id', sa.Integer(), nullable=False), 21 | sa.Column('index', sa.String(length=80), nullable=True), 22 | sa.Column('interval', sa.Integer(), nullable=False), 23 | sa.Column('active', sa.Boolean(), nullable=False), 24 | sa.PrimaryKeyConstraint('id'), 25 | sa.UniqueConstraint('index') 26 | ) 27 | ### end Alembic commands ### 28 | 29 | 30 | def downgrade(): 31 | ### commands auto generated by Alembic - please adjust! ### 32 | op.drop_table('watcher_config') 33 | ### end Alembic commands ### 34 | -------------------------------------------------------------------------------- /migrations/versions/daee17da2abd_.py: -------------------------------------------------------------------------------- 1 | """Rename the new Glacier watcher from 'vault' to 'glacier'. 2 | 3 | Revision ID: daee17da2abd 4 | Revises: c9dd06c919ac 5 | Create Date: 2017-09-06 17:21:08.162000 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = 'daee17da2abd' 11 | down_revision = 'c9dd06c919ac' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | from sqlalchemy.orm import sessionmaker 17 | from sqlalchemy.ext.declarative import declarative_base 18 | 19 | 20 | Session = sessionmaker() 21 | Base = declarative_base() 22 | 23 | 24 | class Technology(Base): 25 | __tablename__ = 'technology' 26 | id = sa.Column(sa.Integer, primary_key=True) 27 | name = sa.Column(sa.String(32)) 28 | 29 | 30 | def upgrade(): 31 | # Rename vault to glacier 32 | bind = op.get_bind() 33 | session = Session(bind=bind) 34 | glacier_tech = session.query(Technology).filter(Technology.name == 'vault').first() 35 | if glacier_tech: 36 | glacier_tech.name = 'glacier' 37 | session.commit() 38 | 39 | def downgrade(): 40 | # Rename glacier to vault 41 | bind = op.get_bind() 42 | session = Session(bind=bind) 43 | glacier_tech = session.query(Technology).filter(Technology.name == 'glacier').first() 44 | if glacier_tech: 45 | glacier_tech.name = 'vault' 46 | session.commit() 47 | -------------------------------------------------------------------------------- /migrations/versions/ea2739ecd874_.py: -------------------------------------------------------------------------------- 1 | """Ensures that account.identifier is unique. 2 | 3 | Revision ID: ea2739ecd874 4 | Revises: 5bd631a1b748 5 | Create Date: 2017-09-29 09:16:09.436339 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = 'ea2739ecd874' 11 | down_revision = '5bd631a1b748' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | # ### commands auto generated by Alembic - please adjust! ### 19 | op.create_unique_constraint(None, 'account', ['identifier']) 20 | # ### end Alembic commands ### 21 | 22 | 23 | def downgrade(): 24 | # ### commands auto generated by Alembic - please adjust! ### 25 | op.drop_constraint(None, 'account', type_='unique') 26 | # ### end Alembic commands ### 27 | -------------------------------------------------------------------------------- /migrations/versions/fb592c81e71_.py: -------------------------------------------------------------------------------- 1 | """Adding networkwhitelist table 2 | 3 | Revision ID: fb592c81e71 4 | Revises: 331ca47ce8ad 5 | Create Date: 2014-10-16 20:30:14.435034 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = 'fb592c81e71' 11 | down_revision = '331ca47ce8ad' 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | from sqlalchemy.dialects import postgresql 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.create_table('networkwhitelist', 20 | sa.Column('id', sa.Integer(), nullable=False), 21 | sa.Column('name', sa.String(length=512), nullable=True), 22 | sa.Column('notes', sa.String(length=512), nullable=True), 23 | sa.Column('cidr', postgresql.CIDR(), nullable=True), 24 | sa.PrimaryKeyConstraint('id') 25 | ) 26 | ### end Alembic commands ### 27 | 28 | 29 | def downgrade(): 30 | ### commands auto generated by Alembic - please adjust! ### 31 | op.drop_table('networkwhitelist') 32 | ### end Alembic commands ### 33 | 34 | -------------------------------------------------------------------------------- /nginx/security_monkey.conf: -------------------------------------------------------------------------------- 1 | add_header X-Content-Type-Options "nosniff"; 2 | add_header X-XSS-Protection "1; mode=block"; 3 | add_header X-Frame-Options "SAMEORIGIN"; 4 | add_header Strict-Transport-Security "max-age=631138519"; 5 | add_header Content-Security-Policy "default-src 'self'; font-src 'self' https://fonts.gstatic.com; script-src 'self' https://ajax.googleapis.com; style-src 'self' https://fonts.googleapis.com;"; 6 | 7 | server { 8 | listen 0.0.0.0:443 ssl; 9 | ssl_certificate /etc/ssl/certs/server.crt; 10 | ssl_certificate_key /etc/ssl/private/server.key; 11 | access_log /var/log/security_monkey/security_monkey.access.log; 12 | error_log /var/log/security_monkey/security_monkey.error.log; 13 | 14 | location ~* ^/(reset|confirm|healthcheck|register|login|logout|api) { 15 | proxy_read_timeout 1800; 16 | proxy_pass http://127.0.0.1:5000; 17 | proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; 18 | proxy_redirect off; 19 | proxy_buffering off; 20 | proxy_set_header Host $http_host; 21 | proxy_set_header X-Real-IP $remote_addr; 22 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 23 | } 24 | 25 | location /static { 26 | rewrite ^/static/(.*)$ /$1 break; 27 | root /usr/local/src/security_monkey/static; 28 | index ui.html; 29 | } 30 | 31 | location / { 32 | root /usr/local/src/security_monkey/static; 33 | index ui.html; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask-CLI==0.4.0 2 | Flask-BabelEx==0.9.3 3 | Flask-Login==0.4.1 4 | Flask-Mail==0.9.1 5 | Flask-Migrate==2.5.2 6 | Flask-Principal==0.4.0 7 | Flask-RESTful==0.3.7 8 | Flask-Script==2.0.6 9 | Flask-SQLAlchemy==2.4.1 10 | Flask-Security==3.0.0 11 | Flask-WTF==0.14.2 12 | Flask==1.1.1 13 | Jinja2==2.11.0 14 | PyJWT==1.7.1 15 | PyYAML==5.3 16 | SQLAlchemy==1.3.13 17 | Werkzeug==0.16.1 18 | bcrypt==3.1.7 19 | boto3==1.12.12 20 | boto==2.49.0 21 | botocore<1.16.0,>=1.15.12 22 | celery==4.4.0 23 | cloudaux==1.8.4 24 | cryptography==2.8 25 | deepdiff==5.0.2 26 | dpath==2.0.1 27 | flask-marshmallow==0.10.1 28 | gunicorn==20.0.4 29 | idna==2.8 30 | ipaddr==2.2.0 31 | itsdangerous==1.1.0 32 | jira==3.0a2 33 | joblib==0.14.1 34 | marshmallow==2.19.1 35 | netaddr==0.7.19 36 | policyuniverse==1.3.2.1 37 | psycopg2-binary==2.8.4 38 | python-dotenv==0.11.0 39 | python-openstackclient==4.0.0 40 | python-cinderclient==7.2.0 41 | pyopenssl==19.1.0 42 | six==1.14.0 43 | swag-client==0.4.7 44 | vine==1.3.0 45 | email-validator==1.1.1 46 | redis==3.5.3 47 | -------------------------------------------------------------------------------- /secmonkey.env: -------------------------------------------------------------------------------- 1 | AWS_ACCESS_KEY_ID= 2 | AWS_SECRET_ACCESS_KEY= 3 | SECURITY_MONKEY_POSTGRES_HOST=postgres 4 | SECURITY_MONKEY_FQDN=127.0.0.1 5 | # Must be false if HTTP 6 | SESSION_COOKIE_SECURE=False -------------------------------------------------------------------------------- /security_monkey/account_managers/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/account_managers/custom/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/account_managers/custom/sample_active_directory.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.accounts.sample_active_directory 16 | :platform: Unix 17 | :synopsis: Manages Active Directory account. Adds fields needed to connect 18 | as custom fields 19 | 20 | .. version:: $$VERSION$$ 21 | .. moduleauthor:: Bridgewater OSS 22 | 23 | 24 | """ 25 | # from security_monkey.account_manager import AccountManager, CustomFieldConfig 26 | # 27 | # class ActiveDirectoryAccountManager(AccountManager): 28 | # account_type = 'ACTIVE_DIRECTORY' 29 | # identifier_label = 'URL' 30 | # identifier_tool_tip = 'Enter the URL of the active directory account' 31 | # custom_field_configs = [ 32 | # CustomFieldConfig('user_id', 'User ID', True, 33 | # 'Enter the user id for the account'), 34 | # CustomFieldConfig('password', 'Password', True, 35 | # "Enter the user's password to access the account", True) 36 | # ] 37 | # 38 | # def __init__(self): 39 | # super(AccountManager, self).__init__() 40 | -------------------------------------------------------------------------------- /security_monkey/account_managers/github_account.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Netflix 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.accounts.github_account 16 | :platform: Unix 17 | :synopsis: Manages GitHub Organizations. 18 | 19 | 20 | .. version:: $$VERSION$$ 21 | .. moduleauthor:: Mike Grima 22 | 23 | 24 | """ 25 | from security_monkey.account_manager import AccountManager, CustomFieldConfig 26 | 27 | 28 | class GitHubAccountManager(AccountManager): 29 | account_type = 'GitHub' 30 | identifier_label = 'Organization Name' 31 | identifier_tool_tip = 'Enter the GitHub Organization Name' 32 | access_token_tool_tip = "Enter the path to the file that contains the GitHub personal access token." 33 | custom_field_configs = [ 34 | CustomFieldConfig('access_token_file', "Personal Access Token", True, access_token_tool_tip), 35 | ] 36 | 37 | def __init__(self): 38 | super(GitHubAccountManager, self).__init__() 39 | -------------------------------------------------------------------------------- /security_monkey/account_managers/openstack_account.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.accounts.openstack_account 16 | :platform: Unix 17 | :synopsis: Manages generic OpenStack account. 18 | 19 | 20 | .. version:: $$VERSION$$ 21 | .. moduleauthor:: Michael Stair 22 | 23 | 24 | """ 25 | from security_monkey.account_manager import AccountManager, CustomFieldConfig 26 | from security_monkey.datastore import Account 27 | 28 | 29 | class OpenStackAccountManager(AccountManager): 30 | account_type = 'OpenStack' 31 | identifier_label = 'Cloud Name' 32 | identifier_tool_tip = 'OpenStack Cloud Name. Cloud configuration to load from clouds.yaml file' 33 | 34 | cloudsyaml_tool_tip = ('Path on disk to clouds.yaml file') 35 | custom_field_configs = [ 36 | CustomFieldConfig('cloudsyaml_file', 'OpenStack clouds.yaml file', True, cloudsyaml_tool_tip) 37 | ] 38 | 39 | def __init__(self): 40 | super(OpenStackAccountManager, self).__init__() 41 | -------------------------------------------------------------------------------- /security_monkey/alerters/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/alerters/custom_alerter.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.alerters.custom_alerter 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Bridgewater OSS 20 | 21 | 22 | """ 23 | from security_monkey import app 24 | 25 | alerter_registry = [] 26 | 27 | 28 | class AlerterType(type): 29 | 30 | def __init__(cls, name, bases, attrs): 31 | if getattr(cls, "report_auditor_changes", None) and getattr(cls, "report_watcher_changes", None): 32 | app.logger.debug("Registering alerter %s", cls.__name__) 33 | alerter_registry.append(cls) 34 | 35 | 36 | def report_auditor_changes(auditor): 37 | for alerter_class in alerter_registry: 38 | alerter = alerter_class() 39 | alerter.report_auditor_changes(auditor) 40 | 41 | 42 | def report_watcher_changes(watcher): 43 | for alerter_class in alerter_registry: 44 | alerter = alerter_class() 45 | alerter.report_watcher_changes(watcher) 46 | -------------------------------------------------------------------------------- /security_monkey/alerters/slack_alerter.py: -------------------------------------------------------------------------------- 1 | """alert slack with any auditor""" 2 | 3 | import json 4 | 5 | import requests 6 | from security_monkey import app 7 | from security_monkey.alerters import custom_alerter 8 | 9 | 10 | class SlackAlerter(object, metaclass=custom_alerter.AlerterType): 11 | def __init__(self, cls, name, bases, attrs): 12 | super().__init__(cls, name, bases, attrs) 13 | self.slack_config = {} 14 | self.slack_hook = "" 15 | 16 | if app.config.get('SLACK_HOOK'): 17 | 18 | self.slack_config = { 19 | 'channel': app.config.get('SLACK_CHANNEL'), 20 | 'username': app.config.get('SLACK_USERNAME'), 21 | 'icon_emoji': app.config.get('SLACK_ICON'), 22 | } 23 | 24 | self.slack_hook = app.config.get('SLACK_HOOK') 25 | 26 | def report_auditor_changes(self, auditor): 27 | for item in auditor.items: 28 | for issue in item.confirmed_new_issues: 29 | x = { 30 | 'text': "New Issue: Index: {!s}\n Account: {!s}\n Region: {!s}\n Name: {!s}".format(item.index, item.account, item.region, item.name) 31 | } 32 | 33 | self.slack_config['attachments'] = x 34 | 35 | try: 36 | requests.post(self.slack_hook, data=json.dumps(self.slack_config)) 37 | self.slack_config['attachments'] = [] 38 | 39 | except Exception as e: 40 | app.logger.exception(e) 41 | app.logger.error("something has gone wrong with the slack post. Please check your configuration. " + e) 42 | -------------------------------------------------------------------------------- /security_monkey/auditors/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Netflix, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/auditors/custom/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/auditors/elasticsearch_service.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Netflix, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.auditors.elasticsearch_service 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Mike Grima 20 | .. moduleauthor:: Patrick Kelley @monkeysecurity 21 | 22 | """ 23 | from security_monkey.watchers.elasticsearch_service import ElasticSearchService 24 | from security_monkey.auditors.resource_policy_auditor import ResourcePolicyAuditor 25 | from policyuniverse.arn import ARN 26 | 27 | 28 | class ElasticSearchServiceAuditor(ResourcePolicyAuditor): 29 | index = ElasticSearchService.index 30 | i_am_singular = ElasticSearchService.i_am_singular 31 | i_am_plural = ElasticSearchService.i_am_plural 32 | 33 | def __init__(self, accounts=None, debug=False): 34 | super(ElasticSearchServiceAuditor, self).__init__(accounts=accounts, debug=debug) 35 | self.policy_keys = ['policy'] 36 | -------------------------------------------------------------------------------- /security_monkey/auditors/gcp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/auditors/gcp/__init__.py -------------------------------------------------------------------------------- /security_monkey/auditors/gcp/gce/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/auditors/gcp/gce/__init__.py -------------------------------------------------------------------------------- /security_monkey/auditors/gcp/gcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/auditors/gcp/gcs/__init__.py -------------------------------------------------------------------------------- /security_monkey/auditors/gcp/iam/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/auditors/gcp/iam/__init__.py -------------------------------------------------------------------------------- /security_monkey/auditors/github/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/auditors/github/__init__.py -------------------------------------------------------------------------------- /security_monkey/auditors/glacier.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); 2 | # you may not use this file except in compliance with the License. 3 | # You may obtain a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | """ 13 | .. module: security_monkey.auditors.glacier 14 | :platform: Unix 15 | 16 | .. version:: $$VERSION$$ 17 | .. moduleauthor:: Patrick Kelley @monkeysecurity 18 | 19 | """ 20 | from security_monkey.watchers.glacier import GlacierVault 21 | from security_monkey.auditors.resource_policy_auditor import ResourcePolicyAuditor 22 | 23 | 24 | class GlacierVaultAuditor(ResourcePolicyAuditor): 25 | index = GlacierVault.index 26 | i_am_singular = GlacierVault.i_am_singular 27 | i_am_plural = GlacierVault.i_am_plural 28 | 29 | def __init__(self, accounts=None, debug=False): 30 | super(GlacierVaultAuditor, self).__init__(accounts=accounts, debug=debug) 31 | self.policy_keys = ['Policy'] -------------------------------------------------------------------------------- /security_monkey/auditors/iam/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/auditors/iam/__init__.py -------------------------------------------------------------------------------- /security_monkey/auditors/lambda_function.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Netflix, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.auditors.lambda_function 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Patrick Kelley 20 | 21 | """ 22 | 23 | from security_monkey.auditors.resource_policy_auditor import ResourcePolicyAuditor 24 | from security_monkey.watchers.lambda_function import LambdaFunction 25 | 26 | from policyuniverse.arn import ARN 27 | import json 28 | 29 | 30 | class LambdaFunctionAuditor(ResourcePolicyAuditor): 31 | index = LambdaFunction.index 32 | i_am_singular = LambdaFunction.i_am_singular 33 | i_am_plural = LambdaFunction.i_am_plural 34 | 35 | def __init__(self, accounts=None, debug=False): 36 | super(LambdaFunctionAuditor, self).__init__(accounts=accounts, debug=debug) 37 | self.policy_keys = ['Policy$DEFAULT', 'Policy$Aliases', 'Policy$Versions'] 38 | -------------------------------------------------------------------------------- /security_monkey/auditors/openstack/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/auditors/openstack/__init__.py -------------------------------------------------------------------------------- /security_monkey/auditors/rds/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/auditors/rds/__init__.py -------------------------------------------------------------------------------- /security_monkey/auditors/redshift.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Yelp, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.auditors.redshift 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Ivan Leichtling @c0wl 20 | 21 | """ 22 | from security_monkey.auditor import Auditor 23 | from security_monkey.watchers.redshift import Redshift 24 | 25 | 26 | class RedshiftAuditor(Auditor): 27 | index = Redshift.index 28 | i_am_singular = Redshift.i_am_singular 29 | i_am_plural = Redshift.i_am_plural 30 | 31 | def __init__(self, accounts=None, debug=False): 32 | super(RedshiftAuditor, self).__init__(accounts=accounts, debug=debug) 33 | 34 | def check_running_in_vpc(self, redshift_cluster): 35 | """ 36 | alert when not running in a VPC. 37 | """ 38 | if not redshift_cluster.config.get('VpcId'): 39 | message = "POLICY - Redshift cluster not in VPC." 40 | self.add_issue(10, message, redshift_cluster) 41 | 42 | -------------------------------------------------------------------------------- /security_monkey/auditors/ses.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Netflix, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.auditors.ses 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Patrick Kelley @monkeysecurity 20 | 21 | """ 22 | from security_monkey.auditor import Auditor 23 | from security_monkey.watchers.ses import SES 24 | 25 | 26 | class SESAuditor(Auditor): 27 | index = SES.index 28 | i_am_singular = SES.i_am_singular 29 | i_am_plural = SES.i_am_plural 30 | 31 | def __init__(self, accounts=None, debug=False): 32 | super(SESAuditor, self).__init__(accounts=accounts, debug=debug) 33 | 34 | 35 | def check_verified(self, ses_item): 36 | """ 37 | alert when an SES identity is not verified. 38 | """ 39 | if not ses_item.config.get('verified'): 40 | self.add_issue(1, 'SES Identity Not Verified.', ses_item) 41 | -------------------------------------------------------------------------------- /security_monkey/auditors/sqs.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Netflix, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.auditors.sqs 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Denver Janke 20 | 21 | """ 22 | 23 | from security_monkey.auditors.resource_policy_auditor import ResourcePolicyAuditor 24 | from security_monkey.watchers.sqs import SQS 25 | 26 | 27 | class SQSAuditor(ResourcePolicyAuditor): 28 | index = SQS.index 29 | i_am_singular = SQS.i_am_singular 30 | i_am_plural = SQS.i_am_plural 31 | 32 | def __init__(self, accounts=None, debug=False): 33 | super(SQSAuditor, self).__init__(accounts=accounts, debug=debug) 34 | self.policy_keys = ['Policy'] 35 | -------------------------------------------------------------------------------- /security_monkey/auth/__init__.py: -------------------------------------------------------------------------------- 1 | from .models import RBACRole 2 | 3 | anonymous = RBACRole(name="anonymous") 4 | 5 | view = RBACRole(name="View") 6 | 7 | comment = RBACRole(name="Comment") 8 | comment.add_parent(view) 9 | 10 | justify = RBACRole(name="Justify") 11 | justify.add_parent(comment) 12 | 13 | admin = RBACRole(name="Admin") 14 | admin.add_parent(justify) 15 | -------------------------------------------------------------------------------- /security_monkey/common/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Netflix, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/common/gcp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/common/gcp/__init__.py -------------------------------------------------------------------------------- /security_monkey/common/gcp/error.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.common.gcp.error 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Tom Melendez @supertom 20 | 21 | """ 22 | 23 | 24 | class AuditIssue(object): 25 | 26 | def __init__(self, code, notes=None): 27 | self.code = code 28 | self.notes = notes 29 | -------------------------------------------------------------------------------- /security_monkey/common/github/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/common/github/__init__.py -------------------------------------------------------------------------------- /security_monkey/common/jinja.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Netflix, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_onkey.common.jinja 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Patrick Kelley @monkeysecurity 20 | 21 | """ 22 | 23 | import os.path 24 | import jinja2 25 | from jinja2 import select_autoescape 26 | 27 | 28 | templates = "templates" 29 | 30 | 31 | def get_jinja_env(): 32 | """ 33 | Returns a Jinja environment with a FileSystemLoader for our templates 34 | """ 35 | templates_directory = os.path.abspath(os.path.join(__file__, '..', '..', templates)) 36 | jinja_environment = jinja2.Environment(loader=jinja2.FileSystemLoader(templates_directory), # nosec 37 | autoescape=select_autoescape(['html', 'xml'])) 38 | # nosec - jinja autoescape enabled for potentially dangerous extensions html, xml 39 | #jinja_environment.filters['dateformat'] = dateformat 40 | return jinja_environment 41 | -------------------------------------------------------------------------------- /security_monkey/constants.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Netflix, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.constants 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Patrick Kelley @monkeysecurity 20 | 21 | """ 22 | 23 | # SM will not alert on exceptions that occur while attempting to retrieve data 24 | # from these regions. In our case, we do not have permissions to these regions. 25 | TROUBLE_REGIONS = ['cn-north-1'] 26 | -------------------------------------------------------------------------------- /security_monkey/sso/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/sso/__init__.py -------------------------------------------------------------------------------- /security_monkey/task_scheduler/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/task_scheduler/__init__.py -------------------------------------------------------------------------------- /security_monkey/templates/csrf_error.json: -------------------------------------------------------------------------------- 1 | { 2 | "csrf_error": "{{ reason|e }}" 3 | } -------------------------------------------------------------------------------- /security_monkey/templates/jinja_audit_email.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% for item in items %} 14 | 15 | 16 | 17 | {% for issue in item.reportable_issues %} 18 | 19 | {% if loop.index > 1 %} 20 | 21 | {% endif %} 22 | {% if issue.justified %} 23 | 24 | {% elif issue.score <= 3 and issue.score > 0 %} 25 | 26 | {% elif issue.score > 6 %} 27 | 28 | {% else %} 29 | 30 | {% endif %} 31 | 32 | 33 | {% if issue.justified %} 34 | 39 | {% else %} 40 | 41 | {% endif %} 42 | 43 | {% endfor %} 44 | 45 | {% endfor %} 46 |
ItemTotal ScoreIssue ScoreIssue DescriptionNotesJustification
{{ item.account }} / {{ item.region }} / {{item.index}} / {{item.name }}Total: {{ item.db_item.score }} Unjustified: {{ item.db_item.unjustified_score }}
{{ issue.score }}{{ issue.score }}{{ issue.score }}{{ issue.score }}{{ issue.issue|e }}{{ issue.notes|e }} 35 | {{ issue.user.name|e }}
36 | {{ issue.justified_date|e }}
37 |

{{ issue.justification|e }}


38 |
None
47 | 48 | 49 | -------------------------------------------------------------------------------- /security_monkey/templates/security/_macros.html: -------------------------------------------------------------------------------- 1 | {% macro render_field_with_errors(field) %} 2 |

3 | {{ field.label }} {{ field(**kwargs)|safe }} 4 | {% if field.errors %} 5 |

    6 | {% for error in field.errors %} 7 |
  • {{ error }}
  • 8 | {% endfor %} 9 |
10 | {% endif %} 11 |

12 | {% endmacro %} 13 | 14 | {% macro render_errors(field) %} 15 |

16 | {% if field.errors %} 17 |

    18 | {% for error in field.errors %} 19 |
  • {{ error }}
  • 20 | {% endfor %} 21 |
22 | {% endif %} 23 |

24 | {% endmacro %} 25 | 26 | {% macro render_generic_error(field1, field2) %} 27 |

28 | {% if field1.errors or field2.errors %} 29 |

    30 |
  • Either the email or password you supplied are incorrect.
  • 31 |
32 | {% endif %} 33 |

34 | {% endmacro %} 35 | 36 | {% macro render_field(field) %} 37 |

{{ field(**kwargs)|safe }}

38 | {% endmacro %} -------------------------------------------------------------------------------- /security_monkey/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Netflix, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.tests.__init__ 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Patrick Kelley 20 | 21 | """ 22 | 23 | import unittest 24 | from security_monkey import app, db 25 | 26 | 27 | class SecurityMonkeyTestCase(unittest.TestCase): 28 | def setUp(self): 29 | self.app = app 30 | self.test_app = self.app.test_client() 31 | db.drop_all() 32 | db.create_all() 33 | self.pre_test_setup() 34 | 35 | def pre_test_setup(self): 36 | # Each sub-class can implement this. 37 | pass 38 | 39 | def tearDown(self): 40 | db.session.remove() 41 | -------------------------------------------------------------------------------- /security_monkey/tests/auditors/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/tests/auditors/gcp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/tests/auditors/gcp/__init__.py -------------------------------------------------------------------------------- /security_monkey/tests/auditors/github/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/tests/auditors/github/__init__.py -------------------------------------------------------------------------------- /security_monkey/tests/auditors/openstack/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/tests/auditors/openstack/__init__.py -------------------------------------------------------------------------------- /security_monkey/tests/auditors/rds/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/tests/auditors/rds/__init__.py -------------------------------------------------------------------------------- /security_monkey/tests/core/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/tests/interface/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/tests/not_used/github/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/tests/not_used/github/__init__.py -------------------------------------------------------------------------------- /security_monkey/tests/not_used/openstack/compute/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/tests/not_used/openstack/compute/__init__.py -------------------------------------------------------------------------------- /security_monkey/tests/not_used/openstack/compute/test_instance.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.tests.watchers.openstack.test_instance 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Michael Stair 20 | 21 | """ 22 | from security_monkey.tests.watchers.openstack import OpenStackWatcherTestCase 23 | 24 | class OpenStackInstanceWatcherTestCase(OpenStackWatcherTestCase): 25 | 26 | def pre_test_setup(self): 27 | super(OpenStackInstanceWatcherTestCase, self).pre_test_setup() 28 | from security_monkey.watchers.openstack.compute.openstack_instance import OpenStackInstance 29 | self.watcher = OpenStackInstance(accounts=[self.account.name]) 30 | -------------------------------------------------------------------------------- /security_monkey/tests/not_used/openstack/network/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/tests/not_used/openstack/network/__init__.py -------------------------------------------------------------------------------- /security_monkey/tests/not_used/openstack/network/test_floating_ip.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.tests.watchers.openstack.test_floating_ip 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Michael Stair 20 | 21 | """ 22 | from security_monkey.tests.watchers.openstack import OpenStackWatcherTestCase 23 | 24 | class OpenStackFloatingIPWatcherTestCase(OpenStackWatcherTestCase): 25 | 26 | def pre_test_setup(self): 27 | super(OpenStackFloatingIPWatcherTestCase, self).pre_test_setup() 28 | from security_monkey.watchers.openstack.network.openstack_floating_ip import OpenStackFloatingIP 29 | self.watcher = OpenStackFloatingIP(accounts=[self.account.name]) 30 | -------------------------------------------------------------------------------- /security_monkey/tests/not_used/openstack/network/test_network.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.tests.watchers.openstack.test_port 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Michael Stair 20 | 21 | """ 22 | from security_monkey.tests.watchers.openstack import OpenStackWatcherTestCase 23 | 24 | class OpenStackNetworkWatcherTestCase(OpenStackWatcherTestCase): 25 | 26 | def pre_test_setup(self): 27 | super(OpenStackNetworkWatcherTestCase, self).pre_test_setup() 28 | from security_monkey.watchers.openstack.network.openstack_network import OpenStackNetwork 29 | self.watcher = OpenStackNetwork(accounts=[self.account.name]) 30 | -------------------------------------------------------------------------------- /security_monkey/tests/not_used/openstack/network/test_port.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.tests.watchers.openstack.test_port 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Michael Stair 20 | 21 | """ 22 | from security_monkey.tests.watchers.openstack import OpenStackWatcherTestCase 23 | 24 | class OpenStackPortWatcherTestCase(OpenStackWatcherTestCase): 25 | 26 | def pre_test_setup(self): 27 | super(OpenStackPortWatcherTestCase, self).pre_test_setup() 28 | from security_monkey.watchers.openstack.network.openstack_port import OpenStackPort 29 | self.watcher = OpenStackPort(accounts=[self.account.name]) 30 | -------------------------------------------------------------------------------- /security_monkey/tests/not_used/openstack/network/test_router.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.tests.watchers.openstack.test_router 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Michael Stair 20 | 21 | """ 22 | from security_monkey.tests.watchers.openstack import OpenStackWatcherTestCase 23 | 24 | class OpenStackRouterWatcherTestCase(OpenStackWatcherTestCase): 25 | 26 | def pre_test_setup(self): 27 | super(OpenStackRouterWatcherTestCase, self).pre_test_setup() 28 | from security_monkey.watchers.openstack.network.openstack_router import OpenStackRouter 29 | self.watcher = OpenStackRouter(accounts=[self.account.name]) 30 | -------------------------------------------------------------------------------- /security_monkey/tests/not_used/openstack/network/test_subnet.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.tests.watchers.openstack.test_subnet 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Michael Stair 20 | 21 | """ 22 | from security_monkey.tests.watchers.openstack import OpenStackWatcherTestCase 23 | 24 | class OpenStackSubnetWatcherTestCase(OpenStackWatcherTestCase): 25 | 26 | def pre_test_setup(self): 27 | super(OpenStackSubnetWatcherTestCase, self).pre_test_setup() 28 | from security_monkey.watchers.openstack.network.openstack_subnet import OpenStackSubnet 29 | self.watcher = OpenStackSubnet(accounts=[self.account.name]) 30 | -------------------------------------------------------------------------------- /security_monkey/tests/not_used/openstack/object_store/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/tests/not_used/openstack/object_store/__init__.py -------------------------------------------------------------------------------- /security_monkey/tests/scheduling/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/tests/scheduling/__init__.py -------------------------------------------------------------------------------- /security_monkey/tests/utilities/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/tests/utilities/__init__.py -------------------------------------------------------------------------------- /security_monkey/tests/utilities/templates/github_creds: -------------------------------------------------------------------------------- 1 | { 2 | "Org-one": "token-one", 3 | "Org-two": "token-two", 4 | "Org-three": "token-three" 5 | } -------------------------------------------------------------------------------- /security_monkey/tests/watchers/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from security_monkey.tests import SecurityMonkeyTestCase 16 | from security_monkey.datastore import Account, AccountType 17 | from security_monkey import db 18 | 19 | class SecurityMonkeyWatcherTestCase(SecurityMonkeyTestCase): 20 | def pre_test_setup(self): 21 | account_type_result = AccountType(name='AWS') 22 | db.session.add(account_type_result) 23 | db.session.commit() 24 | 25 | self.account = Account(identifier="012345678910", name="TEST_ACCOUNT", 26 | account_type_id=account_type_result.id, notes="TEST_ACCOUNT", 27 | third_party=False, active=True) 28 | 29 | db.session.add(self.account) 30 | db.session.commit() 31 | -------------------------------------------------------------------------------- /security_monkey/tests/watchers/ec2/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/tests/watchers/rds/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/tests/watchers/vpc/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/tests/watchers/vpc/test_networkacl.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.tests.watchers.vpc.test_networkacl 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Bridgewater OSS 20 | 21 | 22 | """ 23 | from security_monkey.tests.watchers import SecurityMonkeyWatcherTestCase 24 | from security_monkey.watchers.vpc.networkacl import NetworkACL 25 | 26 | import boto 27 | from moto import mock_sts, mock_ec2_deprecated 28 | from freezegun import freeze_time 29 | 30 | 31 | class NetworkACLWatcherTestCase(SecurityMonkeyWatcherTestCase): 32 | 33 | @freeze_time("2016-07-18 12:00:00") 34 | @mock_sts 35 | @mock_ec2_deprecated 36 | def test_slurp(self): 37 | conn = boto.connect_vpc('the_key', 'the secret') 38 | vpc = conn.create_vpc("10.0.0.0/16") 39 | 40 | watcher = NetworkACL(accounts=[self.account.name]) 41 | item_list, exception_map = watcher.slurp() 42 | 43 | vpc_ids = {nacl.config['vpc_id'] for nacl in item_list} 44 | self.assertIn(vpc.id, vpc_ids) 45 | -------------------------------------------------------------------------------- /security_monkey/tests/watchers/vpc/test_route_table.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.tests.watchers.vpc.test_peering 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Bridgewater OSS 20 | 21 | 22 | """ 23 | from security_monkey.tests.watchers import SecurityMonkeyWatcherTestCase 24 | from security_monkey.watchers.vpc.route_table import RouteTable 25 | 26 | import boto 27 | from moto import mock_sts, mock_ec2_deprecated 28 | from freezegun import freeze_time 29 | 30 | 31 | class RouteTableWatcherTestCase(SecurityMonkeyWatcherTestCase): 32 | 33 | @freeze_time("2016-07-18 12:00:00") 34 | @mock_sts 35 | @mock_ec2_deprecated 36 | def test_slurp(self): 37 | conn = boto.connect_vpc('the_key', 'the secret') 38 | vpc = conn.create_vpc("10.0.0.0/16") 39 | 40 | watcher = RouteTable(accounts=[self.account.name]) 41 | item_list, exception_map = watcher.slurp() 42 | 43 | vpc_ids = {routetable.config['vpc_id'] for routetable in item_list} 44 | self.assertIn(vpc.id, vpc_ids) 45 | -------------------------------------------------------------------------------- /security_monkey/views/logout.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Netflix, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from flask_login import current_user, logout_user 16 | from flask_restful import Resource 17 | 18 | 19 | # End the Flask-Logins session 20 | from security_monkey import rbac 21 | 22 | 23 | class Logout(Resource): 24 | 25 | decorators = [rbac.exempt] 26 | 27 | def get(self): 28 | if not current_user.is_authenticated: 29 | return "Must be logged in to log out", 200 30 | 31 | logout_user() 32 | return "Logged Out", 200 33 | -------------------------------------------------------------------------------- /security_monkey/watchers/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Netflix, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/watchers/custom/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/watchers/direct_connect/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/watchers/ec2/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/watchers/ec2/ec2_image.py: -------------------------------------------------------------------------------- 1 | from security_monkey.cloudaux_watcher import CloudAuxWatcher 2 | from cloudaux.aws.ec2 import describe_images 3 | from cloudaux.orchestration.aws.image import get_image 4 | 5 | 6 | class EC2Image(CloudAuxWatcher): 7 | index = 'ec2image' 8 | i_am_singular = 'EC2 Image' 9 | i_am_plural = 'EC2 Images' 10 | honor_ephemerals = False 11 | ephemeral_paths = ['_version'] 12 | service_name = 'ec2' 13 | 14 | def get_name_from_list_output(self, item): 15 | return item['ImageId'] 16 | 17 | def list_method(self, **kwargs): 18 | return describe_images( 19 | Filters=[ 20 | # {'Name': 'is-public', 'Values': ['true']}, 21 | {'Name': 'owner-id', 'Values': [kwargs['account_number']]}], 22 | **kwargs) 23 | 24 | def get_method(self, item, **kwargs): 25 | return get_image(item['ImageId'], **kwargs) 26 | -------------------------------------------------------------------------------- /security_monkey/watchers/elb.py: -------------------------------------------------------------------------------- 1 | from security_monkey.cloudaux_watcher import CloudAuxWatcher 2 | from cloudaux.aws.elb import describe_load_balancers 3 | from cloudaux.orchestration.aws.elb import get_load_balancer 4 | from security_monkey import app 5 | 6 | 7 | class ELB(CloudAuxWatcher): 8 | index = 'elb' 9 | i_am_singular = 'ELB' 10 | i_am_plural = 'ELBs' 11 | ephemeral_paths = ['_version'] 12 | service_name = 'elb' 13 | detail = app.config.get('SECURITYGROUP_INSTANCE_DETAIL', 'FULL') 14 | 15 | def __init__(self, accounts=None, debug=None): 16 | super(ELB, self).__init__(accounts=accounts, debug=debug) 17 | 18 | self.honor_ephemerals = True 19 | self.ephemeral_paths = ['_version'] 20 | 21 | def get_name_from_list_output(self, item): 22 | return item['LoadBalancerName'] 23 | 24 | def list_method(self, **kwargs): 25 | return describe_load_balancers(**kwargs) 26 | 27 | def get_method(self, item, **kwargs): 28 | result = get_load_balancer(item, **kwargs) 29 | if self.detail == 'NONE' or self.detail == None: 30 | result.pop('Instances', None) 31 | elif self.detail == 'SUMMARY': 32 | result['Instances'] = '{len} Instance(s)'.format(len=len(result.get('Instances', []))) 33 | return result 34 | -------------------------------------------------------------------------------- /security_monkey/watchers/elbv2.py: -------------------------------------------------------------------------------- 1 | from security_monkey.cloudaux_watcher import CloudAuxWatcher 2 | from cloudaux.aws.elbv2 import describe_load_balancers 3 | from cloudaux.orchestration.aws.elbv2 import get_elbv2 4 | 5 | 6 | class ELBv2(CloudAuxWatcher): 7 | index = 'alb' 8 | i_am_singular = 'ALB' 9 | i_am_plural = 'ALBs' 10 | service_name = 'elbv2' 11 | 12 | def __init__(self, accounts=None, debug=None): 13 | super(ELBv2, self).__init__(accounts=accounts, debug=debug) 14 | 15 | self.honor_ephemerals = True 16 | self.ephemeral_paths = ['_version', 'TargetGroupHealth'] 17 | 18 | def get_name_from_list_output(self, item): 19 | return item['LoadBalancerName'] 20 | 21 | def list_method(self, **kwargs): 22 | return describe_load_balancers(**kwargs) 23 | 24 | def get_method(self, item, **kwargs): 25 | return get_elbv2(item, **kwargs) 26 | -------------------------------------------------------------------------------- /security_monkey/watchers/gcp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/watchers/gcp/__init__.py -------------------------------------------------------------------------------- /security_monkey/watchers/gcp/gce/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/watchers/gcp/gce/__init__.py -------------------------------------------------------------------------------- /security_monkey/watchers/gcp/gcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/watchers/gcp/gcs/__init__.py -------------------------------------------------------------------------------- /security_monkey/watchers/gcp/iam/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/watchers/gcp/iam/__init__.py -------------------------------------------------------------------------------- /security_monkey/watchers/github/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/watchers/github/__init__.py -------------------------------------------------------------------------------- /security_monkey/watchers/glacier.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Netflix 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.watchers.glacier 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Travis McPeak @travismcpeak 20 | 21 | """ 22 | 23 | from security_monkey.cloudaux_watcher import CloudAuxWatcher 24 | 25 | from cloudaux.aws.glacier import list_vaults 26 | from cloudaux.orchestration.aws.glacier import get_vault 27 | 28 | 29 | class GlacierVault(CloudAuxWatcher): 30 | index = 'glacier' 31 | i_am_singular = 'Glacier Vault' 32 | i_am_plural = 'Glacier Vaults' 33 | 34 | def __init__(self, **kwargs): 35 | super(GlacierVault, self).__init__(**kwargs) 36 | self.honor_ephemerals = True 37 | self.ephemeral_paths = ['LastInventoryDate', 'NumberOfArchives', 'SizeInBytes'] 38 | 39 | def get_name_from_list_output(self, item): 40 | return item['VaultName'] 41 | 42 | def list_method(self, **kwargs): 43 | return list_vaults(**kwargs) 44 | 45 | def get_method(self, item, **kwargs): 46 | return get_vault(dict(item), **kwargs) 47 | -------------------------------------------------------------------------------- /security_monkey/watchers/iam/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/watchers/iam/__init__.py -------------------------------------------------------------------------------- /security_monkey/watchers/iam/iam_role.py: -------------------------------------------------------------------------------- 1 | from security_monkey.cloudaux_batched_watcher import CloudAuxBatchedWatcher 2 | from cloudaux.aws.iam import list_roles 3 | from cloudaux.orchestration.aws.iam.role import get_role 4 | from security_monkey import AWS_DEFAULT_REGION 5 | 6 | 7 | class IAMRole(CloudAuxBatchedWatcher): 8 | index = 'iamrole' 9 | i_am_singular = 'IAM Role' 10 | i_am_plural = 'IAM Roles' 11 | override_region = 'universal' 12 | 13 | def __init__(self, **kwargs): 14 | super(IAMRole, self).__init__(**kwargs) 15 | self.honor_ephemerals = True 16 | self.ephemeral_paths = ['_version', "Region"] 17 | 18 | def _get_regions(self): 19 | return [AWS_DEFAULT_REGION] 20 | 21 | def get_name_from_list_output(self, item): 22 | return item['RoleName'] 23 | 24 | def list_method(self, **kwargs): 25 | all_roles = list_roles(**kwargs) 26 | items = [] 27 | 28 | for role in all_roles: 29 | role["Region"] = "us-east-1" # IAM is global 30 | items.append(role) 31 | 32 | return items 33 | 34 | def get_method(self, item, **kwargs): 35 | # This is not needed for IAM Role: 36 | item.pop("Region") 37 | 38 | return get_role(dict(item), **kwargs) 39 | -------------------------------------------------------------------------------- /security_monkey/watchers/iam/iam_user.py: -------------------------------------------------------------------------------- 1 | from security_monkey.cloudaux_watcher import CloudAuxWatcher 2 | from security_monkey import AWS_DEFAULT_REGION 3 | from cloudaux.aws.iam import list_users 4 | from cloudaux.orchestration.aws.iam.user import get_user 5 | 6 | 7 | class IAMUser(CloudAuxWatcher): 8 | index = 'iamuser' 9 | i_am_singular = 'IAM User' 10 | i_am_plural = 'IAM Users' 11 | 12 | def __init__(self, *args, **kwargs): 13 | super(IAMUser, self).__init__(*args, **kwargs) 14 | self.honor_ephemerals = True 15 | self.ephemeral_paths = [ 16 | "PasswordLastUsed", 17 | "AccessKeys$*$LastUsedDate", 18 | "AccessKeys$*$Region", 19 | "AccessKeys$*$ServiceName", 20 | "_version"] 21 | self.override_region = 'universal' 22 | 23 | def get_name_from_list_output(self, item): 24 | return item['UserName'] 25 | 26 | def _get_regions(self): 27 | return [AWS_DEFAULT_REGION] 28 | 29 | def list_method(self, **kwargs): 30 | return list_users(**kwargs) 31 | 32 | def get_method(self, item, **kwargs): 33 | return get_user(item, **kwargs) 34 | -------------------------------------------------------------------------------- /security_monkey/watchers/iam/saml_provider.py: -------------------------------------------------------------------------------- 1 | from security_monkey.cloudaux_watcher import CloudAuxWatcher 2 | from security_monkey import AWS_DEFAULT_REGION 3 | from cloudaux.aws.iam import list_saml_providers 4 | from cloudaux.orchestration.aws.iam.saml_provider import get_saml_provider 5 | 6 | 7 | class SAMLProvider(CloudAuxWatcher): 8 | index = 'samlprovider' 9 | i_am_singular = 'SAML Provider' 10 | i_am_plural = 'SAML Providers' 11 | honor_ephemerals = False 12 | ephemeral_paths = ['_version'] 13 | override_region = 'universal' 14 | 15 | def get_name_from_list_output(self, item): 16 | # Extract the name from the ARN 17 | return item['Arn'].split('/')[-1] 18 | 19 | def _get_regions(self): 20 | return [AWS_DEFAULT_REGION] 21 | 22 | def list_method(self, **kwargs): 23 | return list_saml_providers(**kwargs) 24 | 25 | def get_method(self, item, **kwargs): 26 | return get_saml_provider(item, **kwargs) 27 | -------------------------------------------------------------------------------- /security_monkey/watchers/lambda_function.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.watchers.lambda_function 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Bridgewater OSS 20 | .. moduleauthor:: Patrick Kelley 21 | 22 | """ 23 | from security_monkey.cloudaux_watcher import CloudAuxWatcher 24 | from cloudaux.aws.lambda_function import list_functions 25 | from cloudaux.orchestration.aws.lambda_function import get_lambda_function 26 | 27 | 28 | class LambdaFunction(CloudAuxWatcher): 29 | index = 'lambda' 30 | i_am_singular = 'Lambda Function' 31 | i_am_plural = 'Lambda Functions' 32 | service_name = 'lambda' 33 | 34 | def get_name_from_list_output(self, item): 35 | return item['FunctionName'] 36 | 37 | def list_method(self, **kwargs): 38 | return list_functions(**kwargs) 39 | 40 | def get_method(self, item, **kwargs): 41 | return get_lambda_function(item, **kwargs) 42 | 43 | -------------------------------------------------------------------------------- /security_monkey/watchers/openstack/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/watchers/openstack/__init__.py -------------------------------------------------------------------------------- /security_monkey/watchers/openstack/compute/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/watchers/openstack/compute/__init__.py -------------------------------------------------------------------------------- /security_monkey/watchers/openstack/compute/openstack_instance.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.openstack.watchers.instance 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Michael Stair 20 | 21 | """ 22 | from security_monkey.watchers.openstack.openstack_watcher import OpenStackWatcher 23 | 24 | 25 | class OpenStackInstance(OpenStackWatcher): 26 | index = 'openstack_instance' 27 | i_am_singular = 'Instance' 28 | i_am_plural = 'Instances' 29 | account_type = 'OpenStack' 30 | 31 | def __init__(self, *args, **kwargs): 32 | super(OpenStackInstance, self).__init__(*args, **kwargs) 33 | self.item_type = 'instance' 34 | self.service = 'compute' 35 | self.generator = 'servers' 36 | -------------------------------------------------------------------------------- /security_monkey/watchers/openstack/network/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/watchers/openstack/network/__init__.py -------------------------------------------------------------------------------- /security_monkey/watchers/openstack/network/openstack_floating_ip.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.openstack.watchers.floating_ip 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Michael Stair 20 | 21 | """ 22 | from security_monkey.watchers.openstack.openstack_watcher import OpenStackWatcher 23 | 24 | 25 | class OpenStackFloatingIP(OpenStackWatcher): 26 | index = 'openstack_floatingip' 27 | i_am_singular = 'Floating IP' 28 | i_am_plural = 'Floating IPs' 29 | account_type = 'OpenStack' 30 | 31 | def __init__(self, *args, **kwargs): 32 | super(OpenStackFloatingIP, self).__init__(*args, **kwargs) 33 | self.honor_ephemerals = True 34 | self.item_type = 'floatingip' 35 | self.service = 'network' 36 | self.generator = 'ips' 37 | self.ephemeral_paths = ["updated_at"] 38 | -------------------------------------------------------------------------------- /security_monkey/watchers/openstack/network/openstack_network.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.openstack.watchers.network 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Michael Stair 20 | 21 | """ 22 | from security_monkey.watchers.openstack.openstack_watcher import OpenStackWatcher 23 | 24 | 25 | class OpenStackNetwork(OpenStackWatcher): 26 | index = 'openstack_network' 27 | i_am_singular = 'Network' 28 | i_am_plural = 'Network' 29 | account_type = 'OpenStack' 30 | 31 | def __init__(self, *args, **kwargs): 32 | super(OpenStackNetwork, self).__init__(*args, **kwargs) 33 | self.honor_ephemerals = True 34 | self.item_type = 'network' 35 | self.service = 'network' 36 | self.generator = 'networks' 37 | self.ephemeral_paths = ["updated_at"] 38 | -------------------------------------------------------------------------------- /security_monkey/watchers/openstack/network/openstack_port.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.openstack.watchers.port 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Michael Stair 20 | 21 | """ 22 | from security_monkey.watchers.openstack.openstack_watcher import OpenStackWatcher 23 | 24 | 25 | class OpenStackPort(OpenStackWatcher): 26 | index = 'openstack_port' 27 | i_am_singular = 'Port' 28 | i_am_plural = 'Ports' 29 | account_type = 'OpenStack' 30 | 31 | def __init__(self, *args, **kwargs): 32 | super(OpenStackPort, self).__init__(*args, **kwargs) 33 | self.honor_ephemerals = True 34 | self.item_type = 'port' 35 | self.service = 'network' 36 | self.generator = 'ports' 37 | self.ephemeral_paths = [ "updated_at" ] 38 | 39 | def get_name_from_list_output(self, item): 40 | return "{} ({})".format(item.mac_address, item.id) 41 | -------------------------------------------------------------------------------- /security_monkey/watchers/openstack/network/openstack_router.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.openstack.watchers.router 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Michael Stair 20 | 21 | """ 22 | from security_monkey.watchers.openstack.openstack_watcher import OpenStackWatcher 23 | 24 | 25 | class OpenStackRouter(OpenStackWatcher): 26 | index = 'openstack_router' 27 | i_am_singular = 'Router' 28 | i_am_plural = 'Routers' 29 | account_type = 'OpenStack' 30 | 31 | def __init__(self, *args, **kwargs): 32 | super(OpenStackRouter, self).__init__(*args, **kwargs) 33 | self.honor_ephemerals = True 34 | self.item_type = 'router' 35 | self.service = 'network' 36 | self.generator = 'routers' 37 | self.ephemeral_paths = [ "updated_at" ] 38 | -------------------------------------------------------------------------------- /security_monkey/watchers/openstack/network/openstack_subnet.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """ 15 | .. module: security_monkey.openstack.watchers.subnet 16 | :platform: Unix 17 | 18 | .. version:: $$VERSION$$ 19 | .. moduleauthor:: Michael Stair 20 | 21 | """ 22 | from security_monkey.watchers.openstack.openstack_watcher import OpenStackWatcher 23 | 24 | 25 | class OpenStackSubnet(OpenStackWatcher): 26 | index = 'openstack_subnet' 27 | i_am_singular = 'Subnet' 28 | i_am_plural = 'Subnets' 29 | account_type = 'OpenStack' 30 | 31 | def __init__(self, *args, **kwargs): 32 | super(OpenStackSubnet, self).__init__(*args, **kwargs) 33 | self.item_type = 'subnet' 34 | self.service = 'network' 35 | self.generator = 'subnets' 36 | -------------------------------------------------------------------------------- /security_monkey/watchers/openstack/object_store/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/watchers/openstack/object_store/__init__.py -------------------------------------------------------------------------------- /security_monkey/watchers/rds/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Bridgewater Associates 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /security_monkey/watchers/s3.py: -------------------------------------------------------------------------------- 1 | from security_monkey.cloudaux_watcher import CloudAuxWatcher 2 | from security_monkey.exceptions import SecurityMonkeyException 3 | from cloudaux.aws.s3 import list_buckets 4 | from cloudaux.orchestration.aws.s3 import get_bucket 5 | from security_monkey import AWS_DEFAULT_REGION 6 | 7 | 8 | class S3(CloudAuxWatcher): 9 | index = 's3' 10 | i_am_singular = 'S3 Bucket' 11 | i_am_plural = 'S3 Buckets' 12 | 13 | def __init__(self, *args, **kwargs): 14 | super(S3, self).__init__(*args, **kwargs) 15 | self.honor_ephemerals = True 16 | self.ephemeral_paths = ['GrantReferences', '_version'] 17 | self.service_name = 's3' 18 | 19 | def list_method(self, **kwargs): 20 | buckets = list_buckets(**kwargs)['Buckets'] 21 | return [bucket['Name'] for bucket in buckets] 22 | 23 | def get_name_from_list_output(self, item): 24 | return item 25 | 26 | def _get_regions(self): 27 | return [AWS_DEFAULT_REGION] 28 | 29 | def get_method(self, item_name, **kwargs): 30 | bucket = get_bucket(item_name, **kwargs) 31 | 32 | if bucket and bucket.get("Error"): 33 | raise SecurityMonkeyException("S3 Bucket: {} fetching error: {}".format(item_name, bucket["Error"])) 34 | 35 | return bucket 36 | -------------------------------------------------------------------------------- /security_monkey/watchers/vpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix/security_monkey/c28592ffd518fa399527d26262683fc860c30eef/security_monkey/watchers/vpc/__init__.py -------------------------------------------------------------------------------- /supervisor/security_monkey_scheduler.conf: -------------------------------------------------------------------------------- 1 | # Copy this file to: 2 | # /etc/supervisor/conf.d/security_monkey_scheduler.conf 3 | # Restart system supervisor 4 | # sudo systemctl restart supervisor 5 | # Control Startup/Shutdown: 6 | # sudo supervisorctl start/stop securitymonkeyscheduler 7 | 8 | [program:securitymonkeyscheduler] 9 | user=www-data 10 | autostart=true 11 | autorestart=true 12 | numprocs=1 13 | directory=/usr/local/src/security_monkey/ 14 | environment=PYTHONPATH='/usr/local/src/security_monkey/',PATH="/usr/local/src/security_monkey/venv/bin:%(ENV_PATH)s" 15 | command=/usr/local/src/security_monkey/venv/bin/celery -A security_monkey.task_scheduler.beat.CELERY -s /tmp/sm-celerybeat-schedule --pidfile=/tmp/sm-celerybeat-scheduler.pid beat -l debug 16 | 17 | ; Causes supervisor to send the termination signal (SIGTERM) to the whole process group. 18 | stopasgroup=true 19 | -------------------------------------------------------------------------------- /supervisor/security_monkey_ui.conf: -------------------------------------------------------------------------------- 1 | # Copy this file to: 2 | # /etc/supervisor/conf.d/security_monkey_ui.conf 3 | # Restart system supervisor 4 | # sudo systemctl restart supervisor 5 | # Control Startup/Shutdown: 6 | # sudo supervisorctl start/stop securitymonkeyui 7 | 8 | [program:securitymonkeyui] 9 | user=www-data 10 | autostart=true 11 | autorestart=true 12 | environment=PYTHONPATH='/usr/local/src/security_monkey/',PATH="/usr/local/src/security_monkey/venv/bin:%(ENV_PATH)s" 13 | command=/usr/local/src/security_monkey/venv/bin/monkey run_api_server 14 | -------------------------------------------------------------------------------- /supervisor/security_monkey_workers.conf: -------------------------------------------------------------------------------- 1 | # Copy this file to: 2 | # /etc/supervisor/conf.d/security_monkey_workers.conf 3 | # Restart system supervisor 4 | # sudo systemctl restart supervisor 5 | # Control Startup/Shutdown: 6 | # sudo supervisorctl start/stop securitymonkeyworkers 7 | 8 | [program:securitymonkeyworkers] 9 | user=www-data 10 | autostart=true 11 | autorestart=true 12 | numprocs=1 13 | directory=/usr/local/src/security_monkey/ 14 | environment=PYTHONPATH='/usr/local/src/security_monkey/',PATH="/usr/local/src/security_monkey/venv/bin:%(ENV_PATH)s",PYTHON_EGG_CACHE='/tmp/python-eggs' 15 | startsecs=60 16 | command=/usr/local/src/security_monkey/venv/bin/celery -A security_monkey.task_scheduler.tasks.CELERY --pidfile=/tmp/sm-celerybeat-worker.pid worker 17 | 18 | 19 | ; Causes supervisor to send the termination signal (SIGTERM) to the whole process group. 20 | stopasgroup=true 21 | --------------------------------------------------------------------------------