diff --git a/mythx_cli/fuzz/faas.py b/mythx_cli/fuzz/faas.py index 4eeed7e..0073e36 100644 --- a/mythx_cli/fuzz/faas.py +++ b/mythx_cli/fuzz/faas.py @@ -4,6 +4,7 @@ import string import requests +from requests.structures import CaseInsensitiveDict from mythx_cli.analyze.scribble import ScribbleMixin @@ -17,8 +18,6 @@ LOGGER = logging.getLogger("mythx-cli") -headers = {"Content-Type": "application/json"} - class FaasClient: """ A client to interact with the FaaS API. @@ -27,10 +26,14 @@ class FaasClient: API can consume and submits it, also triggering the start of a Campaign. """ - def __init__(self, faas_url, campaign_name_prefix, project_type): + def __init__(self, faas_url, campaign_name_prefix, project_type, api_key): self.faas_url = faas_url self.campaign_name_prefix = campaign_name_prefix self.project_type = project_type + self.api_key = api_key + self.headers = CaseInsensitiveDict() + self.headers["Content-Type"] = "application/json" + self.headers["Authorization"] = "Bearer " + str(self.api_key) def generate_campaign_name(self): """Return a random name with the provided prefix self.campaign_name_prefix.""" @@ -41,10 +44,11 @@ def generate_campaign_name(self): def start_faas_campaign(self, payload): """Make HTTP request to the faas""" try: - req_url = f"{self.faas_url}/api/campaigns?start_immediately=true" - response = requests.post(req_url, json=payload, headers=headers) + req_url = f"{self.faas_url}/api/campaigns/?start_immediately=true" + response = requests.post(req_url, json=payload, headers=self.headers) response_data = response.json() if response.status_code != requests.codes.ok: + print(response.text) raise BadStatusCode( f"Got http status code {response.status_code} for request {req_url}", detail=response_data["detail"], @@ -55,7 +59,7 @@ def start_faas_campaign(self, payload): raise e raise RequestError(f"Error starting FaaS campaign.") - def create_faas_campaign(self, campaign_data, seed_state, dry_run = False): + def create_faas_campaign(self, campaign_data, seed_state, dry_run=False): """Submit a campaign to the FaaS and start that campaign. This function takes a FaaS payload and makes an HTTP request to the Faas backend, which diff --git a/mythx_cli/fuzz/run.py b/mythx_cli/fuzz/run.py index a8d4e37..711bc40 100644 --- a/mythx_cli/fuzz/run.py +++ b/mythx_cli/fuzz/run.py @@ -77,8 +77,16 @@ def determine_ide() -> IDE: help="Outputs the data to be sent to the FaaS API without making the request.", ) +@click.option( + "-k", + "--api-key", + type=click.STRING, + help="API key, can be created on the FaaS Dashboard. ", + default=None, + required=False, +) @click.pass_obj -def fuzz_run(ctx, address, more_addresses, corpus_target, map_to_original_source, dry_run, target): +def fuzz_run(ctx, address, more_addresses, corpus_target, map_to_original_source, dry_run, api_key, target): # read YAML config params from ctx dict, e.g. ganache rpc url # Introduce a separate `fuzz` section in the YAML file @@ -132,6 +140,12 @@ def fuzz_run(ctx, address, more_addresses, corpus_target, map_to_original_source if "map_to_original_source" in config_options else default_config["map_to_original_source"] ) + if not api_key: + api_key = ( + analyze_config["api_key"] + if "api_key" in config_options + else None + ) # Optional config parameters # Here we parse the config parameters from the config file and use defaults for non available values contract_address = analyze_config["deployed_contract_address"] @@ -197,7 +211,7 @@ def fuzz_run(ctx, address, more_addresses, corpus_target, map_to_original_source ) faas_client = FaasClient( - faas_url=faas_url, campaign_name_prefix=campaign_name_prefix, project_type=ide + faas_url=faas_url, campaign_name_prefix=campaign_name_prefix, project_type=ide, api_key=api_key ) try: campaign_id = faas_client.create_faas_campaign(