【小ネタ】SecurityHubのJSONデータをPythonで加工する時に役立つスニペット集


# 拝啓

AWS SecurityHubを活用する際に、セキュリティ関連の発見事項（Findings）をJSON形式で取得することができます。しかし、このデータをそのまま使用するのではなく、より使いやすい形にすることがたまーに求められます。

この記事では、AWS SecurityHubのJSONデータをちょっとだけ便利に加工するPythonコードをいくつか紹介します。

:::note info
↓FindingsのJSONイメージはこちらから確認できます
https://docs.aws.amazon.com/ja_jp/securityhub/1.0/APIReference/API_GetFindings.html#API_GetFindings_ResponseSyntax
:::

# はじめに
JSONの読み込みを```json_data```と定義しました。

    json_data = json.load(f)


## 1. Finding IDをFinding URLに変換する

Finding URLで直接アクセスしたい場合。

```python
# Finding IDをFinding URLに変換する関数
def convert_finding_id_to_url(finding_id):
    region_name = json_data.get("Region")
    encoded_finding_id = urllib.parse.quote(finding_id, safe='')
    finding_url = (f"https://{region_name}.console.aws.amazon.com/securityhub/home?"
                   f"region={region_name}#/findings?search=Id%3D%255Coperator%255C%253AEQUALS%255C%253A{encoded_finding_id}")
    return finding_url

# Finding IDを取得しURLに変換
finding_id = json_data.get("Id")
finding_url = convert_finding_id_to_url(finding_id)
```

## 2. Googletransを利用した翻訳

SecurityHubのタイトルとか詳細は日本語化したい場合。

```python
from googletrans import Translator

    # 翻訳オブジェクトを初期化
    translator = Translator()
    
    # タイトルと詳細を翻訳
    title = translator.translate(json_data.get("Title"), src='en', dest='ja').text
    description = translator.translate(json_data.get("Description"), src='en', dest='ja').text
```


## 3. UTCをJSTに変換する

作成日時(CreatedAt)や、更新日時(UpdateAt)をUTCからJSTにしたい場合。

```python
from datetime import datetime, timezone, timedelta

    # UTCをJSTに変換する関数
    def utc_to_jst(utc_time_str):
        jst_time = datetime.fromisoformat(utc_time_str).astimezone(timezone(timedelta(hours=9)))
        return jst_time.replace(tzinfo=None).isoformat(' ', timespec='seconds')

    
    # 作成日時の変換
    created_at_jst = utc_to_jst(json_data.get("CreatedAt"))
```


## 4. リソースURLの取得

直接リソースURLにアクセスしたい場合。

・リソースIDからリソース名を抽出し、そしてリソースURLを取得します
・リソースによってURLが異なるため、条件分岐してます

```python
# リソースIDを取得
resource_id = json_data.get("Resources", [{}])[0].get("Id")
resource_name = extract_resource_name(resource_id)

# リソースIDからリソース名を抽出する関数
def extract_resource_name(resource_id):
    if resource_id:
        if "/" in resource_id:
            return resource_id.split("/")[-1]
        elif ":" in resource_id:
            return resource_id.split(":")[-1]
    return None

# リソースURL取得のための設定
region_name = json_data.get("Region")
resource_type = json_data.get("Resources", [{}])[0].get("Type")

# リソース名にコロンがついてたら修正する関数
def modify_resource_name(resource_name):
    if ":" in resource_name:
        return resource_name.replace(":", "/")
    return resource_name

# リソースURL取得
if resource_type == "AwsEcsTaskDefinition":
    url = f"https://console.aws.amazon.com/ecs/home?region={region_name}#/taskDefinitions/{modify_resource_name(resource_name)}"
elif resource_type == "AwsS3Bucket":
    url = f"https://s3.console.aws.amazon.com/s3/buckets/{resource_name}?region={region_name}"
elif resource_type == "AwsRdsDbInstance":
    url = f"https://console.aws.amazon.com/rds/home?region={region_name}#database:id={resource_name}"
elif resource_type == "AwsIamUser":
    url = f"https://console.aws.amazon.com/iamv2/home#/users/details/{resource_name}"
elif resource_type == "AwsEc2Instance":
    url = f"https://console.aws.amazon.com/ec2/home?region={region_name}#InstanceDetails:instanceId={resource_name}"
elif resource_type == "AwsLambdaFunction":
    url = f"https://console.aws.amazon.com/lambda/home?region={region_name}#/functions/{resource_name}"
elif resource_type == "AwsElasticBeanstalkEnvironment":
    url = f"https://console.aws.amazon.com/elasticbeanstalk/home?region={region_name}#/environment/dashboard?environmentName={resource_name}"
elif resource_type == "AwsAthenaWorkGroup":
    url = f"https://console.aws.amazon.com/athena/home?region={region_name}#/workgroups/details/{resource_name}"
else:
    url = "該当するリソースタイプのURLが定義されていません"
```


---

参考になれば幸いです。