Files
prowler/providers/aws/services/awslambda/awslambda_service.py
2022-11-23 14:34:51 +01:00

160 lines
5.5 KiB
Python

import io
import json
import threading
import zipfile
from enum import Enum
from typing import Any
import requests
from pydantic import BaseModel
from lib.logger import logger
from providers.aws.aws_provider import generate_regional_clients
################## Lambda
class Lambda:
def __init__(self, audit_info):
self.service = "lambda"
self.session = audit_info.audit_session
self.audited_account = audit_info.audited_account
self.regional_clients = generate_regional_clients(self.service, audit_info)
self.functions = {}
self.__threading_call__(self.__list_functions__)
self.__threading_call__(self.__get_function__)
self.__threading_call__(self.__get_policy__)
self.__threading_call__(self.__get_function_url_config__)
def __get_session__(self):
return self.session
def __threading_call__(self, call):
threads = []
for regional_client in self.regional_clients.values():
threads.append(threading.Thread(target=call, args=(regional_client,)))
for t in threads:
t.start()
for t in threads:
t.join()
def __list_functions__(self, regional_client):
logger.info("Lambda - Listing Functions...")
try:
list_functions_paginator = regional_client.get_paginator("list_functions")
for page in list_functions_paginator.paginate():
for function in page["Functions"]:
lambda_name = function["FunctionName"]
lambda_arn = function["FunctionArn"]
lambda_runtime = function["Runtime"]
self.functions[lambda_name] = Function(
name=lambda_name,
arn=lambda_arn,
runtime=lambda_runtime,
region=regional_client.region,
)
if "Environment" in function:
lambda_environment = function["Environment"]["Variables"]
self.functions[lambda_name].environment = lambda_environment
except Exception as error:
logger.error(
f"{regional_client.region} --"
f" {error.__class__.__name__}[{error.__traceback__.tb_lineno}]:"
f" {error}"
)
def __get_function__(self, regional_client):
logger.info("Lambda - Getting Function...")
try:
for function in self.functions.values():
if function.region == regional_client.region:
function_information = regional_client.get_function(
FunctionName=function.name
)
code_location_uri = function_information["Code"]["Location"]
raw_code_zip = requests.get(code_location_uri).content
self.functions[function.name].code = LambdaCode(
location=code_location_uri,
code_zip=zipfile.ZipFile(io.BytesIO(raw_code_zip)),
)
except Exception as error:
logger.error(
f"{regional_client.region} --"
f" {error.__class__.__name__}[{error.__traceback__.tb_lineno}]:"
f" {error}"
)
def __get_policy__(self, regional_client):
logger.info("Lambda - Getting Policy...")
try:
for function in self.functions.values():
if function.region == regional_client.region:
function_policy = regional_client.get_policy(
FunctionName=function.name
)
self.functions[function.name].policy = json.loads(
function_policy["Policy"]
)
except Exception as error:
logger.error(
f"{regional_client.region} --"
f" {error.__class__.__name__}[{error.__traceback__.tb_lineno}]:"
f" {error}"
)
def __get_function_url_config__(self, regional_client):
logger.info("Lambda - Getting Function URL Config...")
try:
for function in self.functions.values():
if function.region == regional_client.region:
function_url_config = regional_client.get_function_url_config(
FunctionName=function.name
)
self.functions[function.name].url_config = URLConfig(
auth_type=function_url_config["AuthType"],
url=function_url_config["FunctionUrl"],
cors_config=URLConfigCORS(
allow_origins=function_url_config["Cors"]["AllowOrigins"]
),
)
except Exception as error:
logger.error(
f"{regional_client.region} --"
f" {error.__class__.__name__}[{error.__traceback__.tb_lineno}]:"
f" {error}"
)
class LambdaCode(BaseModel):
location: str
code_zip: Any
class AuthType(Enum):
NONE = "NONE"
AWS_IAM = "AWS_IAM"
class URLConfigCORS(BaseModel):
allow_origins: list[str]
class URLConfig(BaseModel):
auth_type: AuthType
url: str
cors_config: URLConfigCORS
class Function(BaseModel):
name: str
arn: str
runtime: str
environment: dict = None
region: str
policy: dict = None
code: LambdaCode = None
url_config: URLConfig = None