Skip to content

Commit

Permalink
Added CLI parameter for replyuri dns resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Johnson authored and Andrew Johnson committed Oct 30, 2019
1 parent ee159c6 commit 9b65a68
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 11 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -104,6 +104,7 @@ Time to set up the server that will run Cartography. Cartography _should_ work
1. Use the cli --okta-org-id parameter with the organization id you want to query. The organization id is the first part of the Okta url for your organization.
1. If you are using okta to administer AWS as a SAML provider(https://saml-doc.okta.com/SAML_Docs/How-to-Configure-SAML-2.0-for-Amazon-Web-Service#scenarioC) the the module will automatically match OktaGroups to the AWSRole they control access for.
- If you are using a regex other than the standard okta group to role regex `^aws\#\S+\#(?{{role}}[\w\-]+)\#(?{{accountid}}\d+)$` then you can specify your regex with the --okta-saml-role-regex parameter.
1. Use the cli switch --okta-resolve-replyuris to perform DNS resolution on the reply uris

1. **Get and run Cartography**

Expand Down
8 changes: 8 additions & 0 deletions cartography/cli.py
Expand Up @@ -152,6 +152,14 @@ def _build_parser(self):
'It the regex must contain the {{role}} and {{accountid}} tags'
),
)
parser.add_argument(
'--okta-resolve-replyuris',
action='store_true',
help=(
'Perform a DNS lookup on the replyuris. Reply uris that no longer resolve are suseptable to '
'Redirect URL manipulation https://www.oauth.com/oauth2-servers/authorization/security-considerations/'
),
)
return parser

def main(self, argv):
Expand Down
6 changes: 6 additions & 0 deletions cartography/config.py
Expand Up @@ -23,6 +23,10 @@ class Config:
:param okta_org_id: Okta organization id. Optional.
:type okta_api_key: str
:param okta_api_key: Okta API key. Optional.
:type okta_saml_role_regex: str
:param okta_saml_role_regex: Okta Group to role Regex. Optional.
:type okta_resolve_reply_uri: bool
:param okta_resolve_reply_uri: Resolve DNS of reply uris. Optional.
"""

def __init__(
Expand All @@ -36,6 +40,7 @@ def __init__(
okta_org_id=None,
okta_api_key=None,
okta_saml_role_regex=None,
okta_resolve_reply_uri=None,
):
self.neo4j_uri = neo4j_uri
self.neo4j_user = neo4j_user
Expand All @@ -46,3 +51,4 @@ def __init__(
self.okta_org_id = okta_org_id
self.okta_api_key = okta_api_key
self.okta_saml_role_regex = okta_saml_role_regex
self.okta_resolve_reply_uri = okta_resolve_reply_uri
5 changes: 4 additions & 1 deletion cartography/intel/okta/__init__.py
Expand Up @@ -47,7 +47,10 @@ def start_okta_ingestion(neo4j_session, config):
organization.create_okta_organization(neo4j_session, config.okta_org_id, config.update_tag)
users.sync_okta_users(neo4j_session, config.okta_org_id, config.update_tag, config.okta_api_key, state)
groups.sync_okta_groups(neo4j_session, config.okta_org_id, config.update_tag, config.okta_api_key, state)
applications.sync_okta_applications(neo4j_session, config.okta_org_id, config.update_tag, config.okta_api_key)
applications.sync_okta_applications(
neo4j_session, config.okta_org_id,
config.update_tag, config.okta_api_key, config.okta_resolve_replyuris,
)
factors.sync_users_factors(neo4j_session, config.okta_org_id, config.update_tag, config.okta_api_key, state)
origins.sync_trusted_origins(neo4j_session, config.okta_org_id, config.update_tag, config.okta_api_key)
awssaml.sync_okta_aws_saml(neo4j_session, config.okta_saml_role_regex, config.update_tag)
Expand Down
20 changes: 11 additions & 9 deletions cartography/intel/okta/applications.py
Expand Up @@ -213,7 +213,7 @@ def transform_okta_application(okta_application):
return app_props


def transform_okta_application_extract_replyurls(okta_application):
def transform_okta_application_extract_replyurls(okta_application, resolve_reply_uris):
"""
Extracts the reply uri information from an okta app
and determines if the dns of the reply url is valid
Expand All @@ -222,12 +222,14 @@ def transform_okta_application_extract_replyurls(okta_application):
if "oauthClient" in okta_application["settings"]:
if "redirect_uris" in okta_application["settings"]["oauthClient"]:
for uri in okta_application["settings"]["oauthClient"]["redirect_uris"]:
netloc = urlparse(uri).netloc
try:
socket.gethostbyname(netloc)
resolved = True
except Exception:
resolved = False
resolved = None
if resolve_reply_uris:
netloc = urlparse(uri).netloc
try:
socket.gethostbyname(netloc)
resolved = True
except Exception:
resolved = False
uris.append({"uri": uri, "valid": resolved})
return uris
return None
Expand Down Expand Up @@ -360,7 +362,7 @@ def _load_application_reply_urls(neo4j_session, app_id, reply_urls, okta_update_
)


def sync_okta_applications(neo4j_session, okta_org_id, okta_update_tag, okta_api_key):
def sync_okta_applications(neo4j_session, okta_org_id, okta_update_tag, okta_api_key, resolve_reply_uris):
"""
Sync okta application
:param neo4j_session: session from the Neo4j server
Expand All @@ -387,5 +389,5 @@ def sync_okta_applications(neo4j_session, okta_org_id, okta_update_tag, okta_api
group_list = transform_application_assigned_groups_list(group_list_data)
_load_application_group(neo4j_session, app_id, group_list, okta_update_tag)

reply_urls = transform_okta_application_extract_replyurls(app)
reply_urls = transform_okta_application_extract_replyurls(app, resolve_reply_uris)
_load_application_reply_urls(neo4j_session, app_id, reply_urls, okta_update_tag)
2 changes: 1 addition & 1 deletion docs/schema/okta.md
Expand Up @@ -273,7 +273,7 @@ Representation of Okta application ReplyUri. For more information, visit Okta do
| Field | Description |
|-------|--------------|
| uri | uri the app can send the reply to |
| valid | is the DNS of the reply uri valid. Invalid replyuris can lead to oath phishing |
| valid | is the DNS of the reply uri valid. Invalid replyuris can lead to oath phishing. This field is only present if DNS resolution was performed using the --okta-resolve-replyuris command line switch|
| firstseen| Timestamp of when a sync job first discovered this node |
| lastupdated | Timestamp of the last time the node was updated |

Expand Down

0 comments on commit 9b65a68

Please sign in to comment.