mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-01-25 02:08:11 +00:00
Compare commits
9 Commits
5.16.1
...
review_met
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
915699cf9b | ||
|
|
d19160b566 | ||
|
|
f4a78d64f1 | ||
|
|
e5cd25e60c | ||
|
|
7d963751aa | ||
|
|
fa4371bbf6 | ||
|
|
ff6fbcbf48 | ||
|
|
9bf3702d71 | ||
|
|
ec32be2f1d |
2
.env
2
.env
@@ -119,7 +119,7 @@ NEXT_PUBLIC_SENTRY_ENVIRONMENT=${SENTRY_ENVIRONMENT}
|
||||
|
||||
|
||||
#### Prowler release version ####
|
||||
NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v5.12.2
|
||||
NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v5.16.0
|
||||
|
||||
# Social login credentials
|
||||
SOCIAL_GOOGLE_OAUTH_CALLBACK_URL="${AUTH_URL}/api/auth/callback/google"
|
||||
|
||||
254
.github/workflows/api-bump-version.yml
vendored
Normal file
254
.github/workflows/api-bump-version.yml
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
name: 'API: Bump Version'
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- 'published'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.release.tag_name }}
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
PROWLER_VERSION: ${{ github.event.release.tag_name }}
|
||||
BASE_BRANCH: master
|
||||
|
||||
jobs:
|
||||
detect-release-type:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
is_minor: ${{ steps.detect.outputs.is_minor }}
|
||||
is_patch: ${{ steps.detect.outputs.is_patch }}
|
||||
major_version: ${{ steps.detect.outputs.major_version }}
|
||||
minor_version: ${{ steps.detect.outputs.minor_version }}
|
||||
patch_version: ${{ steps.detect.outputs.patch_version }}
|
||||
current_api_version: ${{ steps.get_api_version.outputs.current_api_version }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Get current API version
|
||||
id: get_api_version
|
||||
run: |
|
||||
CURRENT_API_VERSION=$(grep -oP '^version = "\K[^"]+' api/pyproject.toml)
|
||||
echo "current_api_version=${CURRENT_API_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
echo "Current API version: $CURRENT_API_VERSION"
|
||||
|
||||
- name: Detect release type and parse version
|
||||
id: detect
|
||||
run: |
|
||||
if [[ $PROWLER_VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
|
||||
MAJOR_VERSION=${BASH_REMATCH[1]}
|
||||
MINOR_VERSION=${BASH_REMATCH[2]}
|
||||
PATCH_VERSION=${BASH_REMATCH[3]}
|
||||
|
||||
echo "major_version=${MAJOR_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
echo "minor_version=${MINOR_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
echo "patch_version=${PATCH_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
if (( MAJOR_VERSION != 5 )); then
|
||||
echo "::error::Releasing another Prowler major version, aborting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if (( PATCH_VERSION == 0 )); then
|
||||
echo "is_minor=true" >> "${GITHUB_OUTPUT}"
|
||||
echo "is_patch=false" >> "${GITHUB_OUTPUT}"
|
||||
echo "✓ Minor release detected: $PROWLER_VERSION"
|
||||
else
|
||||
echo "is_minor=false" >> "${GITHUB_OUTPUT}"
|
||||
echo "is_patch=true" >> "${GITHUB_OUTPUT}"
|
||||
echo "✓ Patch release detected: $PROWLER_VERSION"
|
||||
fi
|
||||
else
|
||||
echo "::error::Invalid version syntax: '$PROWLER_VERSION' (must be X.Y.Z)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bump-minor-version:
|
||||
needs: detect-release-type
|
||||
if: needs.detect-release-type.outputs.is_minor == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Calculate next API minor version
|
||||
run: |
|
||||
MAJOR_VERSION=${{ needs.detect-release-type.outputs.major_version }}
|
||||
MINOR_VERSION=${{ needs.detect-release-type.outputs.minor_version }}
|
||||
CURRENT_API_VERSION="${{ needs.detect-release-type.outputs.current_api_version }}"
|
||||
|
||||
# API version follows Prowler minor + 1
|
||||
# For Prowler 5.17.0 -> API 1.18.0
|
||||
# For next master (Prowler 5.18.0) -> API 1.19.0
|
||||
NEXT_API_VERSION=1.$((MINOR_VERSION + 2)).0
|
||||
|
||||
echo "CURRENT_API_VERSION=${CURRENT_API_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "NEXT_API_VERSION=${NEXT_API_VERSION}" >> "${GITHUB_ENV}"
|
||||
|
||||
echo "Prowler release version: ${MAJOR_VERSION}.${MINOR_VERSION}.0"
|
||||
echo "Current API version: $CURRENT_API_VERSION"
|
||||
echo "Next API minor version (for master): $NEXT_API_VERSION"
|
||||
|
||||
- name: Bump API versions in files for master
|
||||
run: |
|
||||
set -e
|
||||
|
||||
sed -i "s|version = \"${CURRENT_API_VERSION}\"|version = \"${NEXT_API_VERSION}\"|" api/pyproject.toml
|
||||
sed -i "s|spectacular_settings.VERSION = \"${CURRENT_API_VERSION}\"|spectacular_settings.VERSION = \"${NEXT_API_VERSION}\"|" api/src/backend/api/v1/views.py
|
||||
sed -i "s| version: ${CURRENT_API_VERSION}| version: ${NEXT_API_VERSION}|" api/src/backend/api/specs/v1.yaml
|
||||
|
||||
echo "Files modified:"
|
||||
git --no-pager diff
|
||||
|
||||
- name: Create PR for next API minor version to master
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
with:
|
||||
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
|
||||
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
|
||||
base: master
|
||||
commit-message: 'chore(api): Bump version to v${{ env.NEXT_API_VERSION }}'
|
||||
branch: api-version-bump-to-v${{ env.NEXT_API_VERSION }}
|
||||
title: 'chore(api): Bump version to v${{ env.NEXT_API_VERSION }}'
|
||||
labels: no-changelog,skip-sync
|
||||
body: |
|
||||
### Description
|
||||
|
||||
Bump Prowler API version to v${{ env.NEXT_API_VERSION }} after releasing Prowler v${{ env.PROWLER_VERSION }}.
|
||||
|
||||
### License
|
||||
|
||||
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
|
||||
|
||||
- name: Checkout version branch
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
ref: v${{ needs.detect-release-type.outputs.major_version }}.${{ needs.detect-release-type.outputs.minor_version }}
|
||||
|
||||
- name: Calculate first API patch version
|
||||
run: |
|
||||
MAJOR_VERSION=${{ needs.detect-release-type.outputs.major_version }}
|
||||
MINOR_VERSION=${{ needs.detect-release-type.outputs.minor_version }}
|
||||
CURRENT_API_VERSION="${{ needs.detect-release-type.outputs.current_api_version }}"
|
||||
VERSION_BRANCH=v${MAJOR_VERSION}.${MINOR_VERSION}
|
||||
|
||||
# API version follows Prowler minor + 1
|
||||
# For Prowler 5.17.0 release -> version branch v5.17 should have API 1.18.1
|
||||
FIRST_API_PATCH_VERSION=1.$((MINOR_VERSION + 1)).1
|
||||
|
||||
echo "CURRENT_API_VERSION=${CURRENT_API_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "FIRST_API_PATCH_VERSION=${FIRST_API_PATCH_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "VERSION_BRANCH=${VERSION_BRANCH}" >> "${GITHUB_ENV}"
|
||||
|
||||
echo "Prowler release version: ${MAJOR_VERSION}.${MINOR_VERSION}.0"
|
||||
echo "First API patch version (for ${VERSION_BRANCH}): $FIRST_API_PATCH_VERSION"
|
||||
echo "Version branch: $VERSION_BRANCH"
|
||||
|
||||
- name: Bump API versions in files for version branch
|
||||
run: |
|
||||
set -e
|
||||
|
||||
sed -i "s|version = \"${CURRENT_API_VERSION}\"|version = \"${FIRST_API_PATCH_VERSION}\"|" api/pyproject.toml
|
||||
sed -i "s|spectacular_settings.VERSION = \"${CURRENT_API_VERSION}\"|spectacular_settings.VERSION = \"${FIRST_API_PATCH_VERSION}\"|" api/src/backend/api/v1/views.py
|
||||
sed -i "s| version: ${CURRENT_API_VERSION}| version: ${FIRST_API_PATCH_VERSION}|" api/src/backend/api/specs/v1.yaml
|
||||
|
||||
echo "Files modified:"
|
||||
git --no-pager diff
|
||||
|
||||
- name: Create PR for first API patch version to version branch
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
with:
|
||||
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
|
||||
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
|
||||
base: ${{ env.VERSION_BRANCH }}
|
||||
commit-message: 'chore(api): Bump version to v${{ env.FIRST_API_PATCH_VERSION }}'
|
||||
branch: api-version-bump-to-v${{ env.FIRST_API_PATCH_VERSION }}
|
||||
title: 'chore(api): Bump version to v${{ env.FIRST_API_PATCH_VERSION }}'
|
||||
labels: no-changelog,skip-sync
|
||||
body: |
|
||||
### Description
|
||||
|
||||
Bump Prowler API version to v${{ env.FIRST_API_PATCH_VERSION }} in version branch after releasing Prowler v${{ env.PROWLER_VERSION }}.
|
||||
|
||||
### License
|
||||
|
||||
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
|
||||
|
||||
bump-patch-version:
|
||||
needs: detect-release-type
|
||||
if: needs.detect-release-type.outputs.is_patch == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Calculate next API patch version
|
||||
run: |
|
||||
MAJOR_VERSION=${{ needs.detect-release-type.outputs.major_version }}
|
||||
MINOR_VERSION=${{ needs.detect-release-type.outputs.minor_version }}
|
||||
PATCH_VERSION=${{ needs.detect-release-type.outputs.patch_version }}
|
||||
CURRENT_API_VERSION="${{ needs.detect-release-type.outputs.current_api_version }}"
|
||||
VERSION_BRANCH=v${MAJOR_VERSION}.${MINOR_VERSION}
|
||||
|
||||
# Extract current API patch to increment it
|
||||
if [[ $CURRENT_API_VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
|
||||
API_PATCH=${BASH_REMATCH[3]}
|
||||
|
||||
# API version follows Prowler minor + 1
|
||||
# Keep same API minor (based on Prowler minor), increment patch
|
||||
NEXT_API_PATCH_VERSION=1.$((MINOR_VERSION + 1)).$((API_PATCH + 1))
|
||||
|
||||
echo "CURRENT_API_VERSION=${CURRENT_API_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "NEXT_API_PATCH_VERSION=${NEXT_API_PATCH_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "VERSION_BRANCH=${VERSION_BRANCH}" >> "${GITHUB_ENV}"
|
||||
|
||||
echo "Prowler release version: ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}"
|
||||
echo "Current API version: $CURRENT_API_VERSION"
|
||||
echo "Next API patch version: $NEXT_API_PATCH_VERSION"
|
||||
echo "Target branch: $VERSION_BRANCH"
|
||||
else
|
||||
echo "::error::Invalid API version format: $CURRENT_API_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Bump API versions in files for version branch
|
||||
run: |
|
||||
set -e
|
||||
|
||||
sed -i "s|version = \"${CURRENT_API_VERSION}\"|version = \"${NEXT_API_PATCH_VERSION}\"|" api/pyproject.toml
|
||||
sed -i "s|spectacular_settings.VERSION = \"${CURRENT_API_VERSION}\"|spectacular_settings.VERSION = \"${NEXT_API_PATCH_VERSION}\"|" api/src/backend/api/v1/views.py
|
||||
sed -i "s| version: ${CURRENT_API_VERSION}| version: ${NEXT_API_PATCH_VERSION}|" api/src/backend/api/specs/v1.yaml
|
||||
|
||||
echo "Files modified:"
|
||||
git --no-pager diff
|
||||
|
||||
- name: Create PR for next API patch version to version branch
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
with:
|
||||
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
|
||||
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
|
||||
base: ${{ env.VERSION_BRANCH }}
|
||||
commit-message: 'chore(api): Bump version to v${{ env.NEXT_API_PATCH_VERSION }}'
|
||||
branch: api-version-bump-to-v${{ env.NEXT_API_PATCH_VERSION }}
|
||||
title: 'chore(api): Bump version to v${{ env.NEXT_API_PATCH_VERSION }}'
|
||||
labels: no-changelog,skip-sync
|
||||
body: |
|
||||
### Description
|
||||
|
||||
Bump Prowler API version to v${{ env.NEXT_API_PATCH_VERSION }} after releasing Prowler v${{ env.PROWLER_VERSION }}.
|
||||
|
||||
### License
|
||||
|
||||
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
|
||||
247
.github/workflows/docs-bump-version.yml
vendored
Normal file
247
.github/workflows/docs-bump-version.yml
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
name: 'Docs: Bump Version'
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- 'published'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.release.tag_name }}
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
PROWLER_VERSION: ${{ github.event.release.tag_name }}
|
||||
BASE_BRANCH: master
|
||||
|
||||
jobs:
|
||||
detect-release-type:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
is_minor: ${{ steps.detect.outputs.is_minor }}
|
||||
is_patch: ${{ steps.detect.outputs.is_patch }}
|
||||
major_version: ${{ steps.detect.outputs.major_version }}
|
||||
minor_version: ${{ steps.detect.outputs.minor_version }}
|
||||
patch_version: ${{ steps.detect.outputs.patch_version }}
|
||||
current_docs_version: ${{ steps.get_docs_version.outputs.current_docs_version }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Get current documentation version
|
||||
id: get_docs_version
|
||||
run: |
|
||||
CURRENT_DOCS_VERSION=$(grep -oP 'PROWLER_UI_VERSION="\K[^"]+' docs/getting-started/installation/prowler-app.mdx)
|
||||
echo "current_docs_version=${CURRENT_DOCS_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
echo "Current documentation version: $CURRENT_DOCS_VERSION"
|
||||
|
||||
- name: Detect release type and parse version
|
||||
id: detect
|
||||
run: |
|
||||
if [[ $PROWLER_VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
|
||||
MAJOR_VERSION=${BASH_REMATCH[1]}
|
||||
MINOR_VERSION=${BASH_REMATCH[2]}
|
||||
PATCH_VERSION=${BASH_REMATCH[3]}
|
||||
|
||||
echo "major_version=${MAJOR_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
echo "minor_version=${MINOR_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
echo "patch_version=${PATCH_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
if (( MAJOR_VERSION != 5 )); then
|
||||
echo "::error::Releasing another Prowler major version, aborting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if (( PATCH_VERSION == 0 )); then
|
||||
echo "is_minor=true" >> "${GITHUB_OUTPUT}"
|
||||
echo "is_patch=false" >> "${GITHUB_OUTPUT}"
|
||||
echo "✓ Minor release detected: $PROWLER_VERSION"
|
||||
else
|
||||
echo "is_minor=false" >> "${GITHUB_OUTPUT}"
|
||||
echo "is_patch=true" >> "${GITHUB_OUTPUT}"
|
||||
echo "✓ Patch release detected: $PROWLER_VERSION"
|
||||
fi
|
||||
else
|
||||
echo "::error::Invalid version syntax: '$PROWLER_VERSION' (must be X.Y.Z)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bump-minor-version:
|
||||
needs: detect-release-type
|
||||
if: needs.detect-release-type.outputs.is_minor == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Calculate next minor version
|
||||
run: |
|
||||
MAJOR_VERSION=${{ needs.detect-release-type.outputs.major_version }}
|
||||
MINOR_VERSION=${{ needs.detect-release-type.outputs.minor_version }}
|
||||
CURRENT_DOCS_VERSION="${{ needs.detect-release-type.outputs.current_docs_version }}"
|
||||
|
||||
NEXT_MINOR_VERSION=${MAJOR_VERSION}.$((MINOR_VERSION + 1)).0
|
||||
echo "CURRENT_DOCS_VERSION=${CURRENT_DOCS_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "NEXT_MINOR_VERSION=${NEXT_MINOR_VERSION}" >> "${GITHUB_ENV}"
|
||||
|
||||
echo "Current documentation version: $CURRENT_DOCS_VERSION"
|
||||
echo "Current release version: $PROWLER_VERSION"
|
||||
echo "Next minor version: $NEXT_MINOR_VERSION"
|
||||
|
||||
- name: Bump versions in documentation for master
|
||||
run: |
|
||||
set -e
|
||||
|
||||
# Update prowler-app.mdx with current release version
|
||||
sed -i "s|PROWLER_UI_VERSION=\"${CURRENT_DOCS_VERSION}\"|PROWLER_UI_VERSION=\"${PROWLER_VERSION}\"|" docs/getting-started/installation/prowler-app.mdx
|
||||
sed -i "s|PROWLER_API_VERSION=\"${CURRENT_DOCS_VERSION}\"|PROWLER_API_VERSION=\"${PROWLER_VERSION}\"|" docs/getting-started/installation/prowler-app.mdx
|
||||
|
||||
echo "Files modified:"
|
||||
git --no-pager diff
|
||||
|
||||
- name: Create PR for documentation update to master
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
with:
|
||||
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
|
||||
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
|
||||
base: master
|
||||
commit-message: 'docs: Update version to v${{ env.PROWLER_VERSION }}'
|
||||
branch: docs-version-update-to-v${{ env.PROWLER_VERSION }}
|
||||
title: 'docs: Update version to v${{ env.PROWLER_VERSION }}'
|
||||
labels: no-changelog,skip-sync
|
||||
body: |
|
||||
### Description
|
||||
|
||||
Update Prowler documentation version references to v${{ env.PROWLER_VERSION }} after releasing Prowler v${{ env.PROWLER_VERSION }}.
|
||||
|
||||
### Files Updated
|
||||
- `docs/getting-started/installation/prowler-app.mdx`: `PROWLER_UI_VERSION` and `PROWLER_API_VERSION`
|
||||
- All `*.mdx` files with `<VersionBadge>` components
|
||||
|
||||
### License
|
||||
|
||||
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
|
||||
|
||||
- name: Checkout version branch
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
ref: v${{ needs.detect-release-type.outputs.major_version }}.${{ needs.detect-release-type.outputs.minor_version }}
|
||||
|
||||
- name: Calculate first patch version
|
||||
run: |
|
||||
MAJOR_VERSION=${{ needs.detect-release-type.outputs.major_version }}
|
||||
MINOR_VERSION=${{ needs.detect-release-type.outputs.minor_version }}
|
||||
CURRENT_DOCS_VERSION="${{ needs.detect-release-type.outputs.current_docs_version }}"
|
||||
|
||||
FIRST_PATCH_VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.1
|
||||
VERSION_BRANCH=v${MAJOR_VERSION}.${MINOR_VERSION}
|
||||
|
||||
echo "CURRENT_DOCS_VERSION=${CURRENT_DOCS_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "FIRST_PATCH_VERSION=${FIRST_PATCH_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "VERSION_BRANCH=${VERSION_BRANCH}" >> "${GITHUB_ENV}"
|
||||
|
||||
echo "First patch version: $FIRST_PATCH_VERSION"
|
||||
echo "Version branch: $VERSION_BRANCH"
|
||||
|
||||
- name: Bump versions in documentation for version branch
|
||||
run: |
|
||||
set -e
|
||||
|
||||
# Update prowler-app.mdx with current release version
|
||||
sed -i "s|PROWLER_UI_VERSION=\"${CURRENT_DOCS_VERSION}\"|PROWLER_UI_VERSION=\"${PROWLER_VERSION}\"|" docs/getting-started/installation/prowler-app.mdx
|
||||
sed -i "s|PROWLER_API_VERSION=\"${CURRENT_DOCS_VERSION}\"|PROWLER_API_VERSION=\"${PROWLER_VERSION}\"|" docs/getting-started/installation/prowler-app.mdx
|
||||
|
||||
echo "Files modified:"
|
||||
git --no-pager diff
|
||||
|
||||
- name: Create PR for documentation update to version branch
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
with:
|
||||
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
|
||||
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
|
||||
base: ${{ env.VERSION_BRANCH }}
|
||||
commit-message: 'docs: Update version to v${{ env.PROWLER_VERSION }}'
|
||||
branch: docs-version-update-to-v${{ env.PROWLER_VERSION }}-branch
|
||||
title: 'docs: Update version to v${{ env.PROWLER_VERSION }}'
|
||||
labels: no-changelog,skip-sync
|
||||
body: |
|
||||
### Description
|
||||
|
||||
Update Prowler documentation version references to v${{ env.PROWLER_VERSION }} in version branch after releasing Prowler v${{ env.PROWLER_VERSION }}.
|
||||
|
||||
### Files Updated
|
||||
- `docs/getting-started/installation/prowler-app.mdx`: `PROWLER_UI_VERSION` and `PROWLER_API_VERSION`
|
||||
|
||||
### License
|
||||
|
||||
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
|
||||
|
||||
bump-patch-version:
|
||||
needs: detect-release-type
|
||||
if: needs.detect-release-type.outputs.is_patch == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Calculate next patch version
|
||||
run: |
|
||||
MAJOR_VERSION=${{ needs.detect-release-type.outputs.major_version }}
|
||||
MINOR_VERSION=${{ needs.detect-release-type.outputs.minor_version }}
|
||||
PATCH_VERSION=${{ needs.detect-release-type.outputs.patch_version }}
|
||||
CURRENT_DOCS_VERSION="${{ needs.detect-release-type.outputs.current_docs_version }}"
|
||||
|
||||
NEXT_PATCH_VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.$((PATCH_VERSION + 1))
|
||||
VERSION_BRANCH=v${MAJOR_VERSION}.${MINOR_VERSION}
|
||||
|
||||
echo "CURRENT_DOCS_VERSION=${CURRENT_DOCS_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "NEXT_PATCH_VERSION=${NEXT_PATCH_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "VERSION_BRANCH=${VERSION_BRANCH}" >> "${GITHUB_ENV}"
|
||||
|
||||
echo "Current documentation version: $CURRENT_DOCS_VERSION"
|
||||
echo "Current release version: $PROWLER_VERSION"
|
||||
echo "Next patch version: $NEXT_PATCH_VERSION"
|
||||
echo "Target branch: $VERSION_BRANCH"
|
||||
|
||||
- name: Bump versions in documentation for patch version
|
||||
run: |
|
||||
set -e
|
||||
|
||||
# Update prowler-app.mdx with current release version
|
||||
sed -i "s|PROWLER_UI_VERSION=\"${CURRENT_DOCS_VERSION}\"|PROWLER_UI_VERSION=\"${PROWLER_VERSION}\"|" docs/getting-started/installation/prowler-app.mdx
|
||||
sed -i "s|PROWLER_API_VERSION=\"${CURRENT_DOCS_VERSION}\"|PROWLER_API_VERSION=\"${PROWLER_VERSION}\"|" docs/getting-started/installation/prowler-app.mdx
|
||||
|
||||
echo "Files modified:"
|
||||
git --no-pager diff
|
||||
|
||||
- name: Create PR for documentation update to version branch
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
with:
|
||||
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
|
||||
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
|
||||
base: ${{ env.VERSION_BRANCH }}
|
||||
commit-message: 'docs: Update version to v${{ env.PROWLER_VERSION }}'
|
||||
branch: docs-version-update-to-v${{ env.PROWLER_VERSION }}
|
||||
title: 'docs: Update version to v${{ env.PROWLER_VERSION }}'
|
||||
labels: no-changelog,skip-sync
|
||||
body: |
|
||||
### Description
|
||||
|
||||
Update Prowler documentation version references to v${{ env.PROWLER_VERSION }} after releasing Prowler v${{ env.PROWLER_VERSION }}.
|
||||
|
||||
### Files Updated
|
||||
- `docs/getting-started/installation/prowler-app.mdx`: `PROWLER_UI_VERSION` and `PROWLER_API_VERSION`
|
||||
|
||||
### License
|
||||
|
||||
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
|
||||
5
.github/workflows/pr-merged.yml
vendored
5
.github/workflows/pr-merged.yml
vendored
@@ -13,7 +13,10 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
trigger-cloud-pull-request:
|
||||
if: github.event.pull_request.merged == true && github.repository == 'prowler-cloud/prowler'
|
||||
if: |
|
||||
github.event.pull_request.merged == true &&
|
||||
github.repository == 'prowler-cloud/prowler' &&
|
||||
!contains(github.event.pull_request.labels.*.name, 'skip-sync')
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
|
||||
9
.github/workflows/sdk-bump-version.yml
vendored
9
.github/workflows/sdk-bump-version.yml
vendored
@@ -86,7 +86,6 @@ jobs:
|
||||
|
||||
sed -i "s|version = \"${PROWLER_VERSION}\"|version = \"${NEXT_MINOR_VERSION}\"|" pyproject.toml
|
||||
sed -i "s|prowler_version = \"${PROWLER_VERSION}\"|prowler_version = \"${NEXT_MINOR_VERSION}\"|" prowler/config/config.py
|
||||
sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${NEXT_MINOR_VERSION}|" .env
|
||||
|
||||
echo "Files modified:"
|
||||
git --no-pager diff
|
||||
@@ -100,7 +99,7 @@ jobs:
|
||||
commit-message: 'chore(release): Bump version to v${{ env.NEXT_MINOR_VERSION }}'
|
||||
branch: version-bump-to-v${{ env.NEXT_MINOR_VERSION }}
|
||||
title: 'chore(release): Bump version to v${{ env.NEXT_MINOR_VERSION }}'
|
||||
labels: no-changelog
|
||||
labels: no-changelog,skip-sync
|
||||
body: |
|
||||
### Description
|
||||
|
||||
@@ -135,7 +134,6 @@ jobs:
|
||||
|
||||
sed -i "s|version = \"${PROWLER_VERSION}\"|version = \"${FIRST_PATCH_VERSION}\"|" pyproject.toml
|
||||
sed -i "s|prowler_version = \"${PROWLER_VERSION}\"|prowler_version = \"${FIRST_PATCH_VERSION}\"|" prowler/config/config.py
|
||||
sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${FIRST_PATCH_VERSION}|" .env
|
||||
|
||||
echo "Files modified:"
|
||||
git --no-pager diff
|
||||
@@ -149,7 +147,7 @@ jobs:
|
||||
commit-message: 'chore(release): Bump version to v${{ env.FIRST_PATCH_VERSION }}'
|
||||
branch: version-bump-to-v${{ env.FIRST_PATCH_VERSION }}
|
||||
title: 'chore(release): Bump version to v${{ env.FIRST_PATCH_VERSION }}'
|
||||
labels: no-changelog
|
||||
labels: no-changelog,skip-sync
|
||||
body: |
|
||||
### Description
|
||||
|
||||
@@ -193,7 +191,6 @@ jobs:
|
||||
|
||||
sed -i "s|version = \"${PROWLER_VERSION}\"|version = \"${NEXT_PATCH_VERSION}\"|" pyproject.toml
|
||||
sed -i "s|prowler_version = \"${PROWLER_VERSION}\"|prowler_version = \"${NEXT_PATCH_VERSION}\"|" prowler/config/config.py
|
||||
sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${NEXT_PATCH_VERSION}|" .env
|
||||
|
||||
echo "Files modified:"
|
||||
git --no-pager diff
|
||||
@@ -207,7 +204,7 @@ jobs:
|
||||
commit-message: 'chore(release): Bump version to v${{ env.NEXT_PATCH_VERSION }}'
|
||||
branch: version-bump-to-v${{ env.NEXT_PATCH_VERSION }}
|
||||
title: 'chore(release): Bump version to v${{ env.NEXT_PATCH_VERSION }}'
|
||||
labels: no-changelog
|
||||
labels: no-changelog,skip-sync
|
||||
body: |
|
||||
### Description
|
||||
|
||||
|
||||
221
.github/workflows/ui-bump-version.yml
vendored
Normal file
221
.github/workflows/ui-bump-version.yml
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
name: 'UI: Bump Version'
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- 'published'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.release.tag_name }}
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
PROWLER_VERSION: ${{ github.event.release.tag_name }}
|
||||
BASE_BRANCH: master
|
||||
|
||||
jobs:
|
||||
detect-release-type:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
is_minor: ${{ steps.detect.outputs.is_minor }}
|
||||
is_patch: ${{ steps.detect.outputs.is_patch }}
|
||||
major_version: ${{ steps.detect.outputs.major_version }}
|
||||
minor_version: ${{ steps.detect.outputs.minor_version }}
|
||||
patch_version: ${{ steps.detect.outputs.patch_version }}
|
||||
steps:
|
||||
- name: Detect release type and parse version
|
||||
id: detect
|
||||
run: |
|
||||
if [[ $PROWLER_VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
|
||||
MAJOR_VERSION=${BASH_REMATCH[1]}
|
||||
MINOR_VERSION=${BASH_REMATCH[2]}
|
||||
PATCH_VERSION=${BASH_REMATCH[3]}
|
||||
|
||||
echo "major_version=${MAJOR_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
echo "minor_version=${MINOR_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
echo "patch_version=${PATCH_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
if (( MAJOR_VERSION != 5 )); then
|
||||
echo "::error::Releasing another Prowler major version, aborting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if (( PATCH_VERSION == 0 )); then
|
||||
echo "is_minor=true" >> "${GITHUB_OUTPUT}"
|
||||
echo "is_patch=false" >> "${GITHUB_OUTPUT}"
|
||||
echo "✓ Minor release detected: $PROWLER_VERSION"
|
||||
else
|
||||
echo "is_minor=false" >> "${GITHUB_OUTPUT}"
|
||||
echo "is_patch=true" >> "${GITHUB_OUTPUT}"
|
||||
echo "✓ Patch release detected: $PROWLER_VERSION"
|
||||
fi
|
||||
else
|
||||
echo "::error::Invalid version syntax: '$PROWLER_VERSION' (must be X.Y.Z)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bump-minor-version:
|
||||
needs: detect-release-type
|
||||
if: needs.detect-release-type.outputs.is_minor == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Calculate next minor version
|
||||
run: |
|
||||
MAJOR_VERSION=${{ needs.detect-release-type.outputs.major_version }}
|
||||
MINOR_VERSION=${{ needs.detect-release-type.outputs.minor_version }}
|
||||
|
||||
NEXT_MINOR_VERSION=${MAJOR_VERSION}.$((MINOR_VERSION + 1)).0
|
||||
echo "NEXT_MINOR_VERSION=${NEXT_MINOR_VERSION}" >> "${GITHUB_ENV}"
|
||||
|
||||
echo "Current version: $PROWLER_VERSION"
|
||||
echo "Next minor version: $NEXT_MINOR_VERSION"
|
||||
|
||||
- name: Bump UI version in .env for master
|
||||
run: |
|
||||
set -e
|
||||
|
||||
sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${NEXT_MINOR_VERSION}|" .env
|
||||
|
||||
echo "Files modified:"
|
||||
git --no-pager diff
|
||||
|
||||
- name: Create PR for next minor version to master
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
with:
|
||||
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
|
||||
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
|
||||
base: master
|
||||
commit-message: 'chore(ui): Bump version to v${{ env.NEXT_MINOR_VERSION }}'
|
||||
branch: ui-version-bump-to-v${{ env.NEXT_MINOR_VERSION }}
|
||||
title: 'chore(ui): Bump version to v${{ env.NEXT_MINOR_VERSION }}'
|
||||
labels: no-changelog,skip-sync
|
||||
body: |
|
||||
### Description
|
||||
|
||||
Bump Prowler UI version to v${{ env.NEXT_MINOR_VERSION }} after releasing Prowler v${{ env.PROWLER_VERSION }}.
|
||||
|
||||
### Files Updated
|
||||
- `.env`: `NEXT_PUBLIC_PROWLER_RELEASE_VERSION`
|
||||
|
||||
### License
|
||||
|
||||
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
|
||||
|
||||
- name: Checkout version branch
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
ref: v${{ needs.detect-release-type.outputs.major_version }}.${{ needs.detect-release-type.outputs.minor_version }}
|
||||
|
||||
- name: Calculate first patch version
|
||||
run: |
|
||||
MAJOR_VERSION=${{ needs.detect-release-type.outputs.major_version }}
|
||||
MINOR_VERSION=${{ needs.detect-release-type.outputs.minor_version }}
|
||||
|
||||
FIRST_PATCH_VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.1
|
||||
VERSION_BRANCH=v${MAJOR_VERSION}.${MINOR_VERSION}
|
||||
|
||||
echo "FIRST_PATCH_VERSION=${FIRST_PATCH_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "VERSION_BRANCH=${VERSION_BRANCH}" >> "${GITHUB_ENV}"
|
||||
|
||||
echo "First patch version: $FIRST_PATCH_VERSION"
|
||||
echo "Version branch: $VERSION_BRANCH"
|
||||
|
||||
- name: Bump UI version in .env for version branch
|
||||
run: |
|
||||
set -e
|
||||
|
||||
sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${FIRST_PATCH_VERSION}|" .env
|
||||
|
||||
echo "Files modified:"
|
||||
git --no-pager diff
|
||||
|
||||
- name: Create PR for first patch version to version branch
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
with:
|
||||
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
|
||||
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
|
||||
base: ${{ env.VERSION_BRANCH }}
|
||||
commit-message: 'chore(ui): Bump version to v${{ env.FIRST_PATCH_VERSION }}'
|
||||
branch: ui-version-bump-to-v${{ env.FIRST_PATCH_VERSION }}
|
||||
title: 'chore(ui): Bump version to v${{ env.FIRST_PATCH_VERSION }}'
|
||||
labels: no-changelog,skip-sync
|
||||
body: |
|
||||
### Description
|
||||
|
||||
Bump Prowler UI version to v${{ env.FIRST_PATCH_VERSION }} in version branch after releasing Prowler v${{ env.PROWLER_VERSION }}.
|
||||
|
||||
### Files Updated
|
||||
- `.env`: `NEXT_PUBLIC_PROWLER_RELEASE_VERSION`
|
||||
|
||||
### License
|
||||
|
||||
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
|
||||
|
||||
bump-patch-version:
|
||||
needs: detect-release-type
|
||||
if: needs.detect-release-type.outputs.is_patch == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Calculate next patch version
|
||||
run: |
|
||||
MAJOR_VERSION=${{ needs.detect-release-type.outputs.major_version }}
|
||||
MINOR_VERSION=${{ needs.detect-release-type.outputs.minor_version }}
|
||||
PATCH_VERSION=${{ needs.detect-release-type.outputs.patch_version }}
|
||||
|
||||
NEXT_PATCH_VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.$((PATCH_VERSION + 1))
|
||||
VERSION_BRANCH=v${MAJOR_VERSION}.${MINOR_VERSION}
|
||||
|
||||
echo "NEXT_PATCH_VERSION=${NEXT_PATCH_VERSION}" >> "${GITHUB_ENV}"
|
||||
echo "VERSION_BRANCH=${VERSION_BRANCH}" >> "${GITHUB_ENV}"
|
||||
|
||||
echo "Current version: $PROWLER_VERSION"
|
||||
echo "Next patch version: $NEXT_PATCH_VERSION"
|
||||
echo "Target branch: $VERSION_BRANCH"
|
||||
|
||||
- name: Bump UI version in .env for version branch
|
||||
run: |
|
||||
set -e
|
||||
|
||||
sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${NEXT_PATCH_VERSION}|" .env
|
||||
|
||||
echo "Files modified:"
|
||||
git --no-pager diff
|
||||
|
||||
- name: Create PR for next patch version to version branch
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
with:
|
||||
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
|
||||
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
|
||||
base: ${{ env.VERSION_BRANCH }}
|
||||
commit-message: 'chore(ui): Bump version to v${{ env.NEXT_PATCH_VERSION }}'
|
||||
branch: ui-version-bump-to-v${{ env.NEXT_PATCH_VERSION }}
|
||||
title: 'chore(ui): Bump version to v${{ env.NEXT_PATCH_VERSION }}'
|
||||
labels: no-changelog,skip-sync
|
||||
body: |
|
||||
### Description
|
||||
|
||||
Bump Prowler UI version to v${{ env.NEXT_PATCH_VERSION }} after releasing Prowler v${{ env.PROWLER_VERSION }}.
|
||||
|
||||
### Files Updated
|
||||
- `.env`: `NEXT_PUBLIC_PROWLER_RELEASE_VERSION`
|
||||
|
||||
### License
|
||||
|
||||
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
|
||||
@@ -44,7 +44,7 @@ name = "prowler-api"
|
||||
package-mode = false
|
||||
# Needed for the SDK compatibility
|
||||
requires-python = ">=3.11,<3.13"
|
||||
version = "1.16.0"
|
||||
version = "1.18.0"
|
||||
|
||||
[project.scripts]
|
||||
celery = "src.backend.config.settings.celery"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Prowler API
|
||||
version: 1.17.0
|
||||
version: 1.18.0
|
||||
description: |-
|
||||
Prowler API specification.
|
||||
|
||||
|
||||
@@ -359,7 +359,7 @@ class SchemaView(SpectacularAPIView):
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
spectacular_settings.TITLE = "Prowler API"
|
||||
spectacular_settings.VERSION = "1.17.0"
|
||||
spectacular_settings.VERSION = "1.18.0"
|
||||
spectacular_settings.DESCRIPTION = (
|
||||
"Prowler API specification.\n\nThis file is auto-generated."
|
||||
)
|
||||
|
||||
28
dashboard/compliance/prowler_threatscore_alibabacloud.py
Normal file
28
dashboard/compliance/prowler_threatscore_alibabacloud.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import warnings
|
||||
|
||||
from dashboard.common_methods import get_section_containers_threatscore
|
||||
|
||||
warnings.filterwarnings("ignore")
|
||||
|
||||
|
||||
def get_table(data):
|
||||
aux = data[
|
||||
[
|
||||
"REQUIREMENTS_ID",
|
||||
"REQUIREMENTS_DESCRIPTION",
|
||||
"REQUIREMENTS_ATTRIBUTES_SECTION",
|
||||
"REQUIREMENTS_ATTRIBUTES_SUBSECTION",
|
||||
"CHECKID",
|
||||
"STATUS",
|
||||
"REGION",
|
||||
"ACCOUNTID",
|
||||
"RESOURCEID",
|
||||
]
|
||||
].copy()
|
||||
|
||||
return get_section_containers_threatscore(
|
||||
aux,
|
||||
"REQUIREMENTS_ATTRIBUTES_SECTION",
|
||||
"REQUIREMENTS_ATTRIBUTES_SUBSECTION",
|
||||
"REQUIREMENTS_ID",
|
||||
)
|
||||
@@ -407,9 +407,11 @@ def display_data(
|
||||
compliance_module = importlib.import_module(
|
||||
f"dashboard.compliance.{current}"
|
||||
)
|
||||
data = data.drop_duplicates(
|
||||
subset=["CHECKID", "STATUS", "MUTED", "RESOURCEID", "STATUSEXTENDED"]
|
||||
)
|
||||
# Build subset list based on available columns
|
||||
dedup_columns = ["CHECKID", "STATUS", "RESOURCEID", "STATUSEXTENDED"]
|
||||
if "MUTED" in data.columns:
|
||||
dedup_columns.insert(2, "MUTED")
|
||||
data = data.drop_duplicates(subset=dedup_columns)
|
||||
|
||||
if "threatscore" in analytics_input:
|
||||
data = get_threatscore_mean_by_pillar(data)
|
||||
@@ -652,6 +654,7 @@ def get_table(current_compliance, table):
|
||||
def get_threatscore_mean_by_pillar(df):
|
||||
score_per_pillar = {}
|
||||
max_score_per_pillar = {}
|
||||
counted_findings_per_pillar = {}
|
||||
|
||||
for _, row in df.iterrows():
|
||||
pillar = (
|
||||
@@ -663,6 +666,18 @@ def get_threatscore_mean_by_pillar(df):
|
||||
if pillar not in score_per_pillar:
|
||||
score_per_pillar[pillar] = 0
|
||||
max_score_per_pillar[pillar] = 0
|
||||
counted_findings_per_pillar[pillar] = set()
|
||||
|
||||
# Skip muted findings for score calculation
|
||||
is_muted = "MUTED" in df.columns and row.get("MUTED") == "True"
|
||||
if is_muted:
|
||||
continue
|
||||
|
||||
# Create unique finding identifier to avoid counting duplicates
|
||||
finding_id = f"{row.get('CHECKID', '')}_{row.get('RESOURCEID', '')}"
|
||||
if finding_id in counted_findings_per_pillar[pillar]:
|
||||
continue
|
||||
counted_findings_per_pillar[pillar].add(finding_id)
|
||||
|
||||
level_of_risk = pd.to_numeric(
|
||||
row["REQUIREMENTS_ATTRIBUTES_LEVELOFRISK"], errors="coerce"
|
||||
@@ -706,6 +721,10 @@ def get_table_prowler_threatscore(df):
|
||||
score_per_pillar = {}
|
||||
max_score_per_pillar = {}
|
||||
pillars = {}
|
||||
counted_findings_per_pillar = {}
|
||||
counted_pass = set()
|
||||
counted_fail = set()
|
||||
counted_muted = set()
|
||||
|
||||
df_copy = df.copy()
|
||||
|
||||
@@ -720,6 +739,24 @@ def get_table_prowler_threatscore(df):
|
||||
pillars[pillar] = {"FAIL": 0, "PASS": 0, "MUTED": 0}
|
||||
score_per_pillar[pillar] = 0
|
||||
max_score_per_pillar[pillar] = 0
|
||||
counted_findings_per_pillar[pillar] = set()
|
||||
|
||||
# Create unique finding identifier
|
||||
finding_id = f"{row.get('CHECKID', '')}_{row.get('RESOURCEID', '')}"
|
||||
|
||||
# Check if muted
|
||||
is_muted = "MUTED" in df_copy.columns and row.get("MUTED") == "True"
|
||||
|
||||
# Count muted findings (separate from score calculation)
|
||||
if is_muted and finding_id not in counted_muted:
|
||||
counted_muted.add(finding_id)
|
||||
pillars[pillar]["MUTED"] += 1
|
||||
continue # Skip muted findings for score calculation
|
||||
|
||||
# Skip if already counted for this pillar
|
||||
if finding_id in counted_findings_per_pillar[pillar]:
|
||||
continue
|
||||
counted_findings_per_pillar[pillar].add(finding_id)
|
||||
|
||||
level_of_risk = pd.to_numeric(
|
||||
row["REQUIREMENTS_ATTRIBUTES_LEVELOFRISK"], errors="coerce"
|
||||
@@ -738,13 +775,14 @@ def get_table_prowler_threatscore(df):
|
||||
max_score_per_pillar[pillar] += level_of_risk * weight
|
||||
|
||||
if row["STATUS"] == "PASS":
|
||||
pillars[pillar]["PASS"] += 1
|
||||
if finding_id not in counted_pass:
|
||||
counted_pass.add(finding_id)
|
||||
pillars[pillar]["PASS"] += 1
|
||||
score_per_pillar[pillar] += level_of_risk * weight
|
||||
elif row["STATUS"] == "FAIL":
|
||||
pillars[pillar]["FAIL"] += 1
|
||||
|
||||
if "MUTED" in row and row["MUTED"] == "True":
|
||||
pillars[pillar]["MUTED"] += 1
|
||||
if finding_id not in counted_fail:
|
||||
counted_fail.add(finding_id)
|
||||
pillars[pillar]["FAIL"] += 1
|
||||
|
||||
result_df = []
|
||||
|
||||
|
||||
@@ -95,7 +95,14 @@
|
||||
},
|
||||
"user-guide/tutorials/prowler-app-rbac",
|
||||
"user-guide/tutorials/prowler-app-api-keys",
|
||||
"user-guide/tutorials/prowler-app-mute-findings",
|
||||
{
|
||||
"group": "Mutelist",
|
||||
"expanded": true,
|
||||
"pages": [
|
||||
"user-guide/tutorials/prowler-app-simple-mutelist",
|
||||
"user-guide/tutorials/prowler-app-mute-findings"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Integrations",
|
||||
"expanded": true,
|
||||
|
||||
@@ -115,8 +115,8 @@ To update the environment file:
|
||||
Edit the `.env` file and change version values:
|
||||
|
||||
```env
|
||||
PROWLER_UI_VERSION="5.15.0"
|
||||
PROWLER_API_VERSION="5.15.0"
|
||||
PROWLER_UI_VERSION="5.16.0"
|
||||
PROWLER_API_VERSION="5.16.0"
|
||||
```
|
||||
|
||||
<Note>
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
---
|
||||
title: 'Mute Findings (Mutelist)'
|
||||
title: 'Advanced Mutelist (YAML)'
|
||||
---
|
||||
import { VersionBadge } from "/snippets/version-badge.mdx"
|
||||
|
||||
<VersionBadge version="5.9.0" />
|
||||
|
||||
Prowler App allows users to mute specific findings to focus on the most critical security issues. This comprehensive guide demonstrates how to effectively use the Mutelist feature to manage and prioritize security findings.
|
||||
Prowler App allows users to mute specific findings to focus on the most critical security issues. This guide demonstrates how to use the Advanced Mutelist feature with YAML configuration for complex, pattern-based muting rules.
|
||||
|
||||
## What Is the Mutelist Feature?
|
||||
<Note>
|
||||
For muting individual findings without YAML configuration, use [Simple Mutelist](/user-guide/tutorials/prowler-app-simple-mutelist) to mute findings directly from the Findings table.
|
||||
|
||||
The Mutelist feature enables users to:
|
||||
</Note>
|
||||
|
||||
- **Suppress specific findings** from appearing in future scans
|
||||
- **Focus on critical issues** by hiding resolved or accepted risks
|
||||
## What Is Advanced Mutelist?
|
||||
|
||||
Advanced Mutelist enables users to create powerful, pattern-based muting rules using YAML configuration:
|
||||
|
||||
- **Define complex muting patterns** using regular expressions
|
||||
- **Mute findings by check, region, resource, or tag** across multiple accounts
|
||||
- **Apply wildcards** to mute entire categories of findings
|
||||
- **Create exceptions** within broad muting rules
|
||||
- **Maintain audit trails** of muted findings for compliance purposes
|
||||
- **Streamline security workflows** by reducing noise from non-critical findings
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -28,46 +34,51 @@ Before muting findings, ensure:
|
||||
Muting findings does not resolve underlying security issues. Review each finding carefully before muting to ensure it represents an acceptable risk or has been properly addressed.
|
||||
|
||||
</Warning>
|
||||
## Step 1: Add a provider
|
||||
## Step 1: Connect a Provider
|
||||
|
||||
To configure Mutelist:
|
||||
To configure Advanced Mutelist:
|
||||
|
||||
1. Log into Prowler App
|
||||
2. Navigate to the providers page
|
||||
2. Navigate to the Providers page
|
||||

|
||||
3. Add a provider, then "Configure Muted Findings" button will be enabled in providers page and scans page
|
||||
3. Connect a provider to enable Mutelist configuration
|
||||

|
||||

|
||||
|
||||
|
||||
## Step 2: Configure Mutelist
|
||||
## Step 2: Configure Advanced Mutelist
|
||||
|
||||
1. Open the modal by clicking "Configure Muted Findings" button
|
||||

|
||||
1. Provide a valid Mutelist in `YAML` format. More details about Mutelist [here](/user-guide/cli/tutorials/mutelist)
|
||||
1. Navigate to the Mutelist page from the left navigation menu
|
||||
2. Select the "Advanced" tab
|
||||
3. Provide a valid Mutelist configuration in `YAML` format
|
||||
|
||||
<Note>
|
||||
The YAML format follows the same specification as Prowler CLI. See [CLI Mutelist documentation](/user-guide/cli/tutorials/mutelist) for detailed syntax reference.
|
||||
|
||||
</Note>
|
||||

|
||||
If the YAML configuration is invalid, an error message will be displayed
|
||||

|
||||

|
||||
|
||||
## Step 3: Review the Mutelist
|
||||
## Step 3: Review and Update the Configuration
|
||||
|
||||
1. Once added, the configuration can be removed or updated
|
||||
1. Once added, the configuration can be updated or removed from the Advanced tab
|
||||

|
||||
|
||||
## Step 4: Check muted findings in the scan results
|
||||
## Step 4: Verify Muted Findings in Scan Results
|
||||
|
||||
1. Run a new scan
|
||||
2. Check the muted findings in the scan results
|
||||

|
||||
2. Navigate to the Findings page to verify muted findings
|
||||

|
||||
|
||||
<Note>
|
||||
The Mutelist configuration takes effect on the next scans.
|
||||
The Advanced Mutelist configuration takes effect on subsequent scans. Existing findings are not retroactively muted.
|
||||
|
||||
</Note>
|
||||
## Mutelist Ready To Use Examples
|
||||
## YAML Configuration Examples
|
||||
|
||||
Below are examples for different cloud providers supported by Prowler App. Check how the mutelist works [here](/user-guide/cli/tutorials/mutelist#how-the-mutelist-works).
|
||||
Below are ready-to-use examples for different cloud providers. For detailed syntax and logic explanation, see [CLI Mutelist documentation](/user-guide/cli/tutorials/mutelist#how-the-mutelist-works).
|
||||
|
||||
### AWS Provider
|
||||
|
||||
|
||||
180
docs/user-guide/tutorials/prowler-app-simple-mutelist.mdx
Normal file
180
docs/user-guide/tutorials/prowler-app-simple-mutelist.mdx
Normal file
@@ -0,0 +1,180 @@
|
||||
---
|
||||
title: "Simple Mutelist"
|
||||
---
|
||||
|
||||
import { VersionBadge } from "/snippets/version-badge.mdx";
|
||||
|
||||
<VersionBadge version="5.16.0" />
|
||||
|
||||
Prowler App provides Simple Mutelist, an intuitive way to mute findings directly from the Findings page without writing YAML configuration. This feature streamlines the muting workflow by allowing individual or bulk muting with just a few clicks.
|
||||
|
||||
## What Is Simple Mutelist?
|
||||
|
||||
Simple Mutelist enables users to:
|
||||
|
||||
- **Mute findings directly from the Findings table** using checkbox selection
|
||||
- **Perform bulk muting** of multiple findings at once
|
||||
- **Manage mute rules** through a dedicated interface
|
||||
- **Toggle mute rules on and off** without deleting them
|
||||
- **Edit mute rule justifications** after creation
|
||||
|
||||
<Note>
|
||||
Simple Mutelist creates rules based on the finding's unique identifier (UID). For complex muting patterns based on checks, regions, tags, or regular expressions, use [Advanced Mutelist](/user-guide/tutorials/prowler-app-mute-findings) with YAML configuration.
|
||||
|
||||
</Note>
|
||||
|
||||
## Accessing the Mutelist Page
|
||||
|
||||
To access the Mutelist page:
|
||||
|
||||
1. Click "Mutelist" in the left navigation menu
|
||||
|
||||
The Mutelist page contains two tabs:
|
||||
|
||||
- **Simple:** Displays a table of mute rules created through Simple Mutelist
|
||||
- **Advanced:** Provides YAML-based configuration for complex muting patterns
|
||||
|
||||
## Muting Findings from the Findings Page
|
||||
|
||||
### Muting Individual Findings
|
||||
|
||||
To mute a single finding:
|
||||
|
||||
1. Navigate to the Findings page
|
||||
2. Locate the finding to mute
|
||||
3. Click the actions menu (three dots) on the finding row
|
||||
4. Select "Mute"
|
||||
5. Enter a justification for muting this finding
|
||||
6. Click "Confirm" to create the mute rule
|
||||
|
||||
### Muting Multiple Findings (Bulk Muting)
|
||||
|
||||
To mute multiple findings at once:
|
||||
|
||||
1. Navigate to the Findings page
|
||||
2. Select findings using the checkboxes in the leftmost column
|
||||
3. Click the floating "Mute" button that appears at the bottom of the screen
|
||||
4. Enter a justification that applies to all selected findings
|
||||
5. Click "Confirm" to create mute rules for all selected findings
|
||||
|
||||
<Note>
|
||||
Findings that are already muted display a muted icon instead of a checkbox. These findings cannot be selected for bulk operations.
|
||||
|
||||
</Note>
|
||||
|
||||
## Managing Mute Rules
|
||||
|
||||
### Viewing Mute Rules
|
||||
|
||||
To view all mute rules:
|
||||
|
||||
1. Navigate to the Mutelist page
|
||||
2. Select the "Simple" tab
|
||||
3. The table displays all mute rules with the following information:
|
||||
- **Finding UID:** The unique identifier of the muted finding
|
||||
- **Justification:** The reason provided for muting
|
||||
- **Enabled:** Whether the rule is currently active
|
||||
- **Created:** When the rule was created
|
||||
|
||||
### Enabling and Disabling Mute Rules
|
||||
|
||||
To toggle a mute rule without deleting it:
|
||||
|
||||
1. Navigate to the Mutelist page
|
||||
2. Select the "Simple" tab
|
||||
3. Locate the mute rule
|
||||
4. Use the toggle switch in the "Enabled" column to enable or disable the rule
|
||||
|
||||
<Note>
|
||||
Disabled mute rules remain in the system but do not affect findings. Findings associated with disabled rules will appear as unmuted in subsequent scans.
|
||||
|
||||
</Note>
|
||||
|
||||
### Editing Mute Rules
|
||||
|
||||
To edit a mute rule's justification:
|
||||
|
||||
1. Navigate to the Mutelist page
|
||||
2. Select the "Simple" tab
|
||||
3. Click the actions menu (three dots) on the mute rule row
|
||||
4. Select "Edit"
|
||||
5. Update the justification
|
||||
6. Click "Save" to apply changes
|
||||
|
||||
### Deleting Mute Rules
|
||||
|
||||
To permanently remove a mute rule:
|
||||
|
||||
1. Navigate to the Mutelist page
|
||||
2. Select the "Simple" tab
|
||||
3. Click the actions menu (three dots) on the mute rule row
|
||||
4. Select "Delete"
|
||||
5. Confirm the deletion
|
||||
|
||||
<Warning>
|
||||
Deleting a mute rule is permanent. The finding will appear as unmuted in subsequent scans. To temporarily unmute a finding without losing the rule, disable the rule instead of deleting it.
|
||||
|
||||
</Warning>
|
||||
|
||||
## How Simple Mutelist Works
|
||||
|
||||
Simple Mutelist creates mute rules based on a finding's unique identifier (UID). When a mute rule is created:
|
||||
|
||||
- **Existing findings** matching the UID are immediately marked as muted
|
||||
- **Historical findings** with the same UID are also muted
|
||||
- **Future findings** from subsequent scans are automatically muted if they match the UID
|
||||
|
||||
### Uniqueness Constraint
|
||||
|
||||
Each finding UID can only have one mute rule. Attempting to create a duplicate mute rule for the same finding displays an error message indicating the rule already exists.
|
||||
|
||||
## Simple Mutelist vs. Advanced Mutelist
|
||||
|
||||
| Feature | Simple Mutelist | Advanced Mutelist |
|
||||
| ------------------------ | ----------------------------------------- | ------------------------------------------------------ |
|
||||
| **Configuration method** | Point-and-click interface | YAML configuration file |
|
||||
| **Muting scope** | Individual finding UIDs | Patterns based on checks, regions, resources, and tags |
|
||||
| **Regular expressions** | Not supported | Fully supported |
|
||||
| **Bulk operations** | Checkbox selection in Findings table | YAML wildcards and patterns |
|
||||
| **Best for** | Quick, ad-hoc muting of specific findings | Complex, policy-driven muting rules |
|
||||
|
||||
### When to Use Simple Mutelist
|
||||
|
||||
- Muting specific findings identified during review
|
||||
- Quick suppression of known false positives
|
||||
- Ad-hoc muting without YAML knowledge
|
||||
|
||||
### When to Use Advanced Mutelist
|
||||
|
||||
- Muting all findings for a specific check across regions
|
||||
- Pattern-based muting using regular expressions
|
||||
- Tag-based muting for environment-specific resources
|
||||
- Complex rules with exceptions
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Provide meaningful justifications:** Document why each finding is muted for audit trails and team communication
|
||||
2. **Review muted findings regularly:** Periodically audit mute rules to ensure they remain valid
|
||||
3. **Use disable instead of delete:** When temporarily unmuting findings, disable rules rather than deleting them
|
||||
4. **Combine with Advanced Mutelist:** Use Simple Mutelist for specific findings and Advanced Mutelist for broad patterns
|
||||
5. **Limit bulk muting:** Review findings individually when possible to ensure appropriate justification for each
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Duplicate Rule Error
|
||||
|
||||
If an error indicates a mute rule already exists for a finding:
|
||||
|
||||
1. Navigate to the Mutelist page
|
||||
2. Search for the existing rule in the Simple tab
|
||||
3. Edit the existing rule's justification if needed, or
|
||||
4. Delete the existing rule and create a new one
|
||||
|
||||
### Finding Still Appears Unmuted
|
||||
|
||||
If a muted finding still appears unmuted:
|
||||
|
||||
1. Verify the mute rule exists in the Mutelist page
|
||||
2. Ensure the mute rule is enabled (toggle is on)
|
||||
3. Check that the finding UID matches the mute rule
|
||||
4. Wait for the next scan to see updated muting status on historical findings
|
||||
@@ -2,6 +2,20 @@
|
||||
|
||||
All notable changes to the **Prowler SDK** are documented in this file.
|
||||
|
||||
## [5.17.0] (Prowler UNRELEASED)
|
||||
|
||||
### Added
|
||||
- Add Prowler ThreatScore for the Alibaba Cloud provider [(#9511)](https://github.com/prowler-cloud/prowler/pull/9511)
|
||||
|
||||
### Changed
|
||||
- Update AWS Step Functions service metadata to new format [(#9432)](https://github.com/prowler-cloud/prowler/pull/9432)
|
||||
- Update AWS Route 53 service metadata to new format [(#9406)](https://github.com/prowler-cloud/prowler/pull/9406)
|
||||
- Update AWS SQS service metadata to new format [(#9429)](https://github.com/prowler-cloud/prowler/pull/9429)
|
||||
- Update Azure SQL Server service metadata to new format [(#9627)](https://github.com/prowler-cloud/prowler/pull/9627)
|
||||
|
||||
|
||||
---
|
||||
|
||||
## [5.16.0] (Prowler v5.16.0)
|
||||
|
||||
### Added
|
||||
|
||||
@@ -83,6 +83,9 @@ from prowler.lib.outputs.compliance.mitre_attack.mitre_attack_azure import (
|
||||
AzureMitreAttack,
|
||||
)
|
||||
from prowler.lib.outputs.compliance.mitre_attack.mitre_attack_gcp import GCPMitreAttack
|
||||
from prowler.lib.outputs.compliance.prowler_threatscore.prowler_threatscore_alibaba import (
|
||||
ProwlerThreatScoreAlibaba,
|
||||
)
|
||||
from prowler.lib.outputs.compliance.prowler_threatscore.prowler_threatscore_aws import (
|
||||
ProwlerThreatScoreAWS,
|
||||
)
|
||||
@@ -1039,6 +1042,18 @@ def prowler():
|
||||
)
|
||||
generated_outputs["compliance"].append(cis)
|
||||
cis.batch_write_data_to_file()
|
||||
elif compliance_name == "prowler_threatscore_alibabacloud":
|
||||
filename = (
|
||||
f"{output_options.output_directory}/compliance/"
|
||||
f"{output_options.output_filename}_{compliance_name}.csv"
|
||||
)
|
||||
prowler_threatscore = ProwlerThreatScoreAlibaba(
|
||||
findings=finding_outputs,
|
||||
compliance=bulk_compliance_frameworks[compliance_name],
|
||||
file_path=filename,
|
||||
)
|
||||
generated_outputs["compliance"].append(prowler_threatscore)
|
||||
prowler_threatscore.batch_write_data_to_file()
|
||||
else:
|
||||
filename = (
|
||||
f"{output_options.output_directory}/compliance/"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,7 @@ class _MutableTimestamp:
|
||||
|
||||
timestamp = _MutableTimestamp(datetime.today())
|
||||
timestamp_utc = _MutableTimestamp(datetime.now(timezone.utc))
|
||||
prowler_version = "5.16.0"
|
||||
prowler_version = "5.17.0"
|
||||
html_logo_url = "https://github.com/prowler-cloud/prowler/"
|
||||
square_logo_img = "https://raw.githubusercontent.com/prowler-cloud/prowler/dc7d2d5aeb92fdf12e8604f42ef6472cd3e8e889/docs/img/prowler-logo-black.png"
|
||||
aws_logo = "https://user-images.githubusercontent.com/38561120/235953920-3e3fba08-0795-41dc-b480-9bea57db9f2e.png"
|
||||
|
||||
@@ -146,3 +146,29 @@ class ProwlerThreatScoreKubernetesModel(BaseModel):
|
||||
Muted: bool
|
||||
Framework: str
|
||||
Name: str
|
||||
|
||||
|
||||
class ProwlerThreatScoreAlibabaModel(BaseModel):
|
||||
"""
|
||||
ProwlerThreatScoreAlibabaModel generates a finding's output in Alibaba Cloud Prowler ThreatScore Compliance format.
|
||||
"""
|
||||
|
||||
Provider: str
|
||||
Description: str
|
||||
AccountId: str
|
||||
Region: str
|
||||
AssessmentDate: str
|
||||
Requirements_Id: str
|
||||
Requirements_Description: str
|
||||
Requirements_Attributes_Title: str
|
||||
Requirements_Attributes_Section: str
|
||||
Requirements_Attributes_SubSection: Optional[str] = None
|
||||
Requirements_Attributes_AttributeDescription: str
|
||||
Requirements_Attributes_AdditionalInformation: str
|
||||
Requirements_Attributes_LevelOfRisk: int
|
||||
Requirements_Attributes_Weight: int
|
||||
Status: str
|
||||
StatusExtended: str
|
||||
ResourceId: str
|
||||
ResourceName: str
|
||||
CheckId: str
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
from prowler.config.config import timestamp
|
||||
from prowler.lib.check.compliance_models import Compliance
|
||||
from prowler.lib.outputs.compliance.compliance_output import ComplianceOutput
|
||||
from prowler.lib.outputs.compliance.prowler_threatscore.models import (
|
||||
ProwlerThreatScoreAlibabaModel,
|
||||
)
|
||||
from prowler.lib.outputs.finding import Finding
|
||||
|
||||
|
||||
class ProwlerThreatScoreAlibaba(ComplianceOutput):
|
||||
"""
|
||||
This class represents the Alibaba Cloud Prowler ThreatScore compliance output.
|
||||
|
||||
Attributes:
|
||||
- _data (list): A list to store transformed data from findings.
|
||||
- _file_descriptor (TextIOWrapper): A file descriptor to write data to a file.
|
||||
|
||||
Methods:
|
||||
- transform: Transforms findings into Alibaba Cloud Prowler ThreatScore compliance format.
|
||||
"""
|
||||
|
||||
def transform(
|
||||
self,
|
||||
findings: list[Finding],
|
||||
compliance: Compliance,
|
||||
compliance_name: str,
|
||||
) -> None:
|
||||
"""
|
||||
Transforms a list of findings into Alibaba Cloud Prowler ThreatScore compliance format.
|
||||
|
||||
Parameters:
|
||||
- findings (list): A list of findings.
|
||||
- compliance (Compliance): A compliance model.
|
||||
- compliance_name (str): The name of the compliance model.
|
||||
|
||||
Returns:
|
||||
- None
|
||||
"""
|
||||
for finding in findings:
|
||||
# Get the compliance requirements for the finding
|
||||
finding_requirements = finding.compliance.get(compliance_name, [])
|
||||
for requirement in compliance.Requirements:
|
||||
if requirement.Id in finding_requirements:
|
||||
for attribute in requirement.Attributes:
|
||||
compliance_row = ProwlerThreatScoreAlibabaModel(
|
||||
Provider=finding.provider,
|
||||
Description=compliance.Description,
|
||||
AccountId=finding.account_uid,
|
||||
Region=finding.region,
|
||||
AssessmentDate=str(timestamp),
|
||||
Requirements_Id=requirement.Id,
|
||||
Requirements_Description=requirement.Description,
|
||||
Requirements_Attributes_Title=attribute.Title,
|
||||
Requirements_Attributes_Section=attribute.Section,
|
||||
Requirements_Attributes_SubSection=attribute.SubSection,
|
||||
Requirements_Attributes_AttributeDescription=attribute.AttributeDescription,
|
||||
Requirements_Attributes_AdditionalInformation=attribute.AdditionalInformation,
|
||||
Requirements_Attributes_LevelOfRisk=attribute.LevelOfRisk,
|
||||
Requirements_Attributes_Weight=attribute.Weight,
|
||||
Status=finding.status,
|
||||
StatusExtended=finding.status_extended,
|
||||
ResourceId=finding.resource_uid,
|
||||
ResourceName=finding.resource_name,
|
||||
CheckId=finding.check_id,
|
||||
Muted=finding.muted,
|
||||
Framework=compliance.Framework,
|
||||
Name=compliance.Name,
|
||||
)
|
||||
self._data.append(compliance_row)
|
||||
# Add manual requirements to the compliance output
|
||||
for requirement in compliance.Requirements:
|
||||
if not requirement.Checks:
|
||||
for attribute in requirement.Attributes:
|
||||
compliance_row = ProwlerThreatScoreAlibabaModel(
|
||||
Provider=compliance.Provider.lower(),
|
||||
Description=compliance.Description,
|
||||
AccountId="",
|
||||
Region="",
|
||||
AssessmentDate=str(timestamp),
|
||||
Requirements_Id=requirement.Id,
|
||||
Requirements_Description=requirement.Description,
|
||||
Requirements_Attributes_Title=attribute.Title,
|
||||
Requirements_Attributes_Section=attribute.Section,
|
||||
Requirements_Attributes_SubSection=attribute.SubSection,
|
||||
Requirements_Attributes_AttributeDescription=attribute.AttributeDescription,
|
||||
Requirements_Attributes_AdditionalInformation=attribute.AdditionalInformation,
|
||||
Requirements_Attributes_LevelOfRisk=attribute.LevelOfRisk,
|
||||
Requirements_Attributes_Weight=attribute.Weight,
|
||||
Status="MANUAL",
|
||||
StatusExtended="Manual check",
|
||||
ResourceId="manual_check",
|
||||
ResourceName="Manual check",
|
||||
CheckId="manual",
|
||||
Muted=False,
|
||||
Framework=compliance.Framework,
|
||||
Name=compliance.Name,
|
||||
)
|
||||
self._data.append(compliance_row)
|
||||
@@ -1,30 +1,39 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "route53_dangling_ip_subdomain_takeover",
|
||||
"CheckTitle": "Check if Route53 Records contains dangling IPs.",
|
||||
"CheckType": [],
|
||||
"CheckTitle": "Route53 A record does not point to a dangling IP address",
|
||||
"CheckType": [
|
||||
"Software and Configuration Checks/AWS Security Best Practices/Network Reachability",
|
||||
"TTPs/Initial Access",
|
||||
"Effects/Data Exposure"
|
||||
],
|
||||
"ServiceName": "route53",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "high",
|
||||
"ResourceType": "Other",
|
||||
"Description": "Check if Route53 Records contains dangling IPs.",
|
||||
"Risk": "When an ephemeral AWS resource such as an Elastic IP (EIP) is released into the Amazon's Elastic IP pool, an attacker may acquire the EIP resource and effectively control the domain/subdomain associated with that EIP in your Route 53 DNS records.",
|
||||
"ResourceType": "AwsRoute53HostedZone",
|
||||
"Description": "**Route 53 `A` records** (non-alias) that use literal IPs are evaluated for **public AWS addresses** not currently assigned to resources in the account. Entries that match AWS ranges yet lack ownership are identified as potential **dangling IP targets**.",
|
||||
"Risk": "**Dangling DNS `A` records** pointing to released AWS IPs enable **subdomain takeover**. An attacker who later obtains that IP can:\n- Redirect or alter content (integrity)\n- Capture credentials/cookies (confidentiality)\n- Disrupt or impersonate services (availability)",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://support.icompaas.com/support/solutions/articles/62000233461-ensure-route53-records-contains-dangling-ips-",
|
||||
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Route53/dangling-dns-records.html",
|
||||
"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-deleting.html"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "aws route53 change-resource-record-sets --hosted-zone-id <resource_id>",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Route53/dangling-dns-records.html",
|
||||
"Terraform": ""
|
||||
"CLI": "aws route53 change-resource-record-sets --hosted-zone-id <example_resource_id> --change-batch '{\"Changes\":[{\"Action\":\"UPSERT\",\"ResourceRecordSet\":{\"Name\":\"<example_resource_name>\",\"Type\":\"A\",\"AliasTarget\":{\"HostedZoneId\":\"<ALIAS_TARGET_HOSTED_ZONE_ID>\",\"DNSName\":\"<ALIAS_TARGET_DNS_NAME>\",\"EvaluateTargetHealth\":false}}}]}'",
|
||||
"NativeIaC": "```yaml\n# CloudFormation: convert A record to an Alias so it no longer points to a dangling IP\nResources:\n <example_resource_name>:\n Type: AWS::Route53::RecordSet\n Properties:\n HostedZoneId: <example_resource_id>\n Name: <example_resource_name>\n Type: A\n AliasTarget:\n HostedZoneId: <ALIAS_TARGET_HOSTED_ZONE_ID> # CRITICAL: use Alias to an AWS resource instead of an IP\n DNSName: <ALIAS_TARGET_DNS_NAME> # CRITICAL: target AWS resource DNS (e.g., ALB/CloudFront)\n EvaluateTargetHealth: false\n```",
|
||||
"Other": "1. Open AWS Console > Route 53 > Hosted zones\n2. Select the hosted zone and locate the failing non-alias A record\n3. If not needed: click Delete and confirm\n4. If needed: select the record, click Edit, enable Alias, choose the correct AWS resource (e.g., ALB/CloudFront), then Save changes\n5. Wait for propagation (~60s) and re-run the check",
|
||||
"Terraform": "```hcl\n# Terraform: convert A record to Alias to avoid dangling public IPs\nresource \"aws_route53_record\" \"<example_resource_name>\" {\n zone_id = \"<example_resource_id>\"\n name = \"<example_resource_name>\"\n type = \"A\"\n\n alias { # CRITICAL: Alias to AWS resource (no direct IP)\n name = \"<ALIAS_TARGET_DNS_NAME>\" # e.g., dualstack.<alb>.amazonaws.com\n zone_id = \"<ALIAS_TARGET_HOSTED_ZONE_ID>\"\n evaluate_target_health = false\n }\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Ensure that any dangling DNS records are deleted from your Amazon Route 53 public hosted zones in order to maintain the integrity and authenticity of your domains/subdomains and to protect against domain hijacking attacks.",
|
||||
"Url": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-deleting.html"
|
||||
"Text": "Remove or update any record that points to an unassigned IP. Avoid hard-coding AWS public IPs in `A` records; use **aliases/CNAMEs** to managed endpoints. Enforce **asset lifecycle** decommissioning, routine DNS-asset reconciliation, and **change control** with monitoring to prevent and detect drift.",
|
||||
"Url": "https://hub.prowler.com/check/route53_dangling_ip_subdomain_takeover"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"forensics-ready"
|
||||
"internet-exposed"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
|
||||
@@ -1,29 +1,40 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "route53_domains_privacy_protection_enabled",
|
||||
"CheckTitle": "Enable Privacy Protection for for a Route53 Domain.",
|
||||
"CheckType": [],
|
||||
"CheckTitle": "Route 53 domain has admin contact privacy protection enabled",
|
||||
"CheckType": [
|
||||
"Software and Configuration Checks/AWS Security Best Practices",
|
||||
"Effects/Data Exposure",
|
||||
"Sensitive Data Identifications/PII"
|
||||
],
|
||||
"ServiceName": "route53",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "Other",
|
||||
"Description": "Enable Privacy Protection for for a Route53 Domain.",
|
||||
"Risk": "Without privacy protection enabled, ones personal information is published to the public WHOIS database.",
|
||||
"RelatedUrl": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-privacy-protection.html",
|
||||
"Description": "**Route 53 domain** administrative contact has **privacy protection** enabled, so WHOIS queries return redacted or proxy details.\n\nEvaluates whether contact data is hidden instead of publicly listed.",
|
||||
"Risk": "**Public WHOIS contact data** exposes names, emails, phones, and addresses, enabling:\n- **Phishing/social engineering** of the registrar\n- **SIM-swap** or account takeover\n- **Domain hijacking**, affecting DNS integrity/availability\nIt also increases spam and targeted harassment.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-privacy-protection.html",
|
||||
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Route53/privacy-protection.html",
|
||||
"https://support.icompaas.com/support/solutions/articles/62000233459-enable-privacy-protection-for-for-a-route53-domain-"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "aws route53domains update-domain-contact-privacy --domain-name domain.com --registrant-privacy",
|
||||
"CLI": "aws route53domains update-domain-contact-privacy --domain-name <DOMAIN_NAME> --admin-privacy",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Route53/privacy-protection.html",
|
||||
"Terraform": ""
|
||||
"Other": "1. Open the AWS Console and go to Route 53\n2. Click Registered domains and select <DOMAIN_NAME>\n3. Click Edit in Contact information\n4. Enable Privacy protection (ensures Admin contact privacy is on)\n5. Save changes",
|
||||
"Terraform": "```hcl\nresource \"aws_route53domains_registered_domain\" \"<example_resource_name>\" {\n domain_name = \"<example_resource_name>\"\n admin_privacy = true # Critical: enables admin contact privacy to pass the check\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Ensure default Privacy is enabled.",
|
||||
"Url": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-privacy-protection.html"
|
||||
"Text": "Enable **WHOIS privacy** for all contacts (admin, registrant, tech) to minimize exposure. Apply **defense in depth**: use dedicated, monitored contact emails, enforce **transfer lock** and **MFA** on registrar access, and regularly review settings. *If a TLD lacks privacy*, provide minimal, role-based contact details.",
|
||||
"Url": "https://hub.prowler.com/check/route53_domains_privacy_protection_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"internet-exposed"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
|
||||
@@ -1,29 +1,37 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "route53_domains_transferlock_enabled",
|
||||
"CheckTitle": "Enable Transfer Lock for a Route53 Domain.",
|
||||
"CheckType": [],
|
||||
"CheckTitle": "Route 53 domain has Transfer Lock enabled",
|
||||
"CheckType": [
|
||||
"Software and Configuration Checks/AWS Security Best Practices",
|
||||
"TTPs/Initial Access/Unauthorized Access"
|
||||
],
|
||||
"ServiceName": "route53",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"Severity": "high",
|
||||
"ResourceType": "Other",
|
||||
"Description": "Enable Transfer Lock for a Route53 Domain.",
|
||||
"Risk": "Without transfer lock enabled, a domain name could be incorrectly moved to a new registrar.",
|
||||
"RelatedUrl": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-lock.html",
|
||||
"Description": "**Route 53 registered domains** are assessed for a transfer-lock state, indicated by the `clientTransferProhibited` status on the domain.",
|
||||
"Risk": "Without **transfer lock**, a domain can be illicitly moved to another registrar, enabling **domain hijacking**. Attackers could alter DNS, redirect traffic, harvest credentials, and disrupt email and apps-compromising **confidentiality**, **integrity**, and **availability**.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-lock.html"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "aws route53domains enable-domain-transfer-lock --domain-name DOMAIN",
|
||||
"CLI": "aws route53domains enable-domain-transfer-lock --domain-name <example_domain_name>",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
"Other": "1. Open the AWS Management Console and go to Route 53\n2. In the left pane, select Registered domains\n3. Click the domain name <example_domain_name>\n4. In Actions, choose Turn on transfer lock\n5. Confirm to enable the lock",
|
||||
"Terraform": "```hcl\nresource \"aws_route53domains_registered_domain\" \"<example_resource_name>\" {\n domain_name = \"<example_domain_name>\"\n transfer_lock = true # Enables transfer lock (sets clientTransferProhibited)\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Ensure transfer lock is enabled.",
|
||||
"Url": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-lock.html"
|
||||
"Text": "Enable **transfer lock** on domains to prevent unauthorized registrar moves. Enforce **least privilege** on domain management, require **MFA**, and monitor status changes. *For planned transfers*, remove the lock only under approved change control and re-enable immediately afterward.",
|
||||
"Url": "https://hub.prowler.com/check/route53_domains_transferlock_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"identity-access"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
|
||||
@@ -1,30 +1,37 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "route53_public_hosted_zones_cloudwatch_logging_enabled",
|
||||
"CheckTitle": "Check if Route53 public hosted zones are logging queries to CloudWatch Logs.",
|
||||
"CheckType": [],
|
||||
"CheckTitle": "Route53 public hosted zone has query logging enabled to a CloudWatch Logs log group",
|
||||
"CheckType": [
|
||||
"Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis",
|
||||
"Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices"
|
||||
],
|
||||
"ServiceName": "route53",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AwsRoute53HostedZone",
|
||||
"Description": "Check if Route53 public hosted zones are logging queries to CloudWatch Logs.",
|
||||
"Risk": "If logs are not enabled, monitoring of service use and threat analysis is not possible.",
|
||||
"RelatedUrl": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/monitoring-hosted-zones-with-cloudwatch.html",
|
||||
"Description": "**Route 53 public hosted zones** have **DNS query logging** enabled to **CloudWatch Logs**, recording resolver requests for the zone and writing events to an associated log group.",
|
||||
"Risk": "Missing **DNS query logs** removes visibility into domain use, weakening detection of:\n- **Data exfiltration** via DNS\n- **Malware C2/DGA** patterns\n- **Hijacking or misconfigurations**\nThis degrades **incident response**, threatens data **confidentiality** and **integrity**, and slows **availability** troubleshooting.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/monitoring-hosted-zones-with-cloudwatch.html",
|
||||
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Route53/enable-query-logging.html"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "aws route53 create-query-logging-config --hosted-zone-id <zone_id> --cloud-watch-logs-log-group-arn <log_group_arn>",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Route53/enable-query-logging.html",
|
||||
"Terraform": ""
|
||||
"CLI": "aws route53 create-query-logging-config --hosted-zone-id <HOSTED_ZONE_ID> --cloud-watch-logs-log-group-arn <LOG_GROUP_ARN>",
|
||||
"NativeIaC": "```yaml\n# CloudFormation: Enable query logging for a public hosted zone\nResources:\n <example_resource_name>:\n Type: AWS::Route53::HostedZone\n Properties:\n Name: <example_domain_name>\n QueryLoggingConfig:\n CloudWatchLogsLogGroupArn: <example_log_group_arn> # Critical: enables Route53 query logging to this CloudWatch Logs group\n```",
|
||||
"Other": "1. Open the AWS Console and go to Route 53 > Hosted zones\n2. Select the public hosted zone\n3. Choose Query logging > Enable\n4. Select the target CloudWatch Logs log group and click Save\n5. If prompted, allow Route 53 to write to the log group (approve the CloudWatch Logs resource policy)",
|
||||
"Terraform": "```hcl\n# Enable Route53 query logging for a public hosted zone\nresource \"aws_route53_query_log\" \"example\" {\n zone_id = \"<example_resource_id>\" # Critical: target hosted zone\n cloudwatch_log_group_arn = \"<example_log_group_arn>\" # Critical: delivers logs to this CloudWatch Logs group\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable CloudWatch logs and define metrics and uses cases for the events recorded.",
|
||||
"Url": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/monitoring-hosted-zones-with-cloudwatch.html"
|
||||
"Text": "Enable **Route 53 query logging** for public zones to a centralized **CloudWatch Logs** group. Apply **least privilege** to log delivery, set **retention** and **metric filters/alerts**, and stream to your **SIEM**. Use **defense in depth** by correlating DNS logs with network and endpoint telemetry and regularly review baselines.",
|
||||
"Url": "https://hub.prowler.com/check/route53_public_hosted_zones_cloudwatch_logging_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"forensics-ready"
|
||||
"logging"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
|
||||
@@ -1,26 +1,35 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "sqs_queues_not_publicly_accessible",
|
||||
"CheckTitle": "Check if SQS queues have policy set as Public",
|
||||
"CheckType": [],
|
||||
"CheckTitle": "SQS queue policy does not allow public access",
|
||||
"CheckType": [
|
||||
"Software and Configuration Checks/AWS Security Best Practices/Network Reachability",
|
||||
"Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices",
|
||||
"TTPs/Initial Access/Unauthorized Access",
|
||||
"Effects/Data Exposure"
|
||||
],
|
||||
"ServiceName": "sqs",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:aws:sqs:region:account-id:queue",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "critical",
|
||||
"ResourceType": "AwsSqsQueue",
|
||||
"Description": "Check if SQS queues have policy set as Public",
|
||||
"Risk": "Sensitive information could be disclosed",
|
||||
"RelatedUrl": "https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-basic-examples-of-sqs-policies.html",
|
||||
"Description": "Amazon SQS queue policies are assessed for **public access**. The finding highlights queues with `Allow` statements using a wildcard `Principal` without restrictive conditions, compared to queues that only grant access to the owning account or explicitly trusted principals.",
|
||||
"Risk": "**Public SQS access** can expose message data (**confidentiality**), enable unauthorized send/receive or tampering (**integrity**), and allow purge/delete operations that disrupt processing (**availability**). It may also trigger unbounded message ingestion, causing cost spikes and consumer overload.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SQS/sqs-queue-exposed.html",
|
||||
"https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-basic-examples-of-sqs-policies.html"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SQS/sqs-queue-exposed.html",
|
||||
"Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-sqs-queue-policy-is-not-public-by-only-allowing-specific-services-or-principals-to-access-it#terraform"
|
||||
"CLI": "aws sqs set-queue-attributes --queue-url <example_queue_url> --attributes Policy='{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"<example_account_id>\"},\"Action\":\"sqs:*\",\"Resource\":\"<example_queue_arn>\"}]}'",
|
||||
"NativeIaC": "```yaml\n# CloudFormation: Restrict SQS policy to a specific principal (not public)\nResources:\n QueuePolicy:\n Type: AWS::SQS::QueuePolicy\n Properties:\n Queues:\n - \"<example_queue_url>\"\n PolicyDocument:\n Version: \"2012-10-17\"\n Statement:\n - Effect: Allow\n Principal:\n AWS: \"<example_account_id>\" # CRITICAL: restrict access to a specific account (removes public \"*\")\n Action: \"sqs:*\"\n Resource: \"<example_queue_arn>\"\n```",
|
||||
"Other": "1. Open the Amazon SQS console and select the queue\n2. Go to Permissions (Access policy) and click Edit\n3. In the JSON policy, replace any \"Principal\": \"*\" with \"Principal\": { \"AWS\": \"<your_account_id>\" } or remove those public statements\n4. Save changes",
|
||||
"Terraform": "```hcl\n# Restrict SQS policy to a specific principal (not public)\nresource \"aws_sqs_queue_policy\" \"<example_resource_name>\" {\n queue_url = \"<example_queue_url>\"\n policy = jsonencode({\n Version = \"2012-10-17\"\n Statement = [{\n Effect = \"Allow\"\n Principal = { AWS = \"<example_account_id>\" } # CRITICAL: restrict to a specific principal (removes public \"*\")\n Action = \"sqs:*\"\n Resource = \"<example_queue_arn>\"\n }]\n })\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Review service with overly permissive policies. Adhere to Principle of Least Privilege.",
|
||||
"Url": "https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-basic-examples-of-sqs-policies.html"
|
||||
"Text": "Apply **least privilege** on SQS resource policies:\n- Avoid `Principal: *`; grant access only to specific accounts, roles, or services\n- Add restrictive conditions to tightly scope access\n- Prefer private connectivity and defense-in-depth controls\n- Review policies and audit activity regularly to prevent drift",
|
||||
"Url": "https://hub.prowler.com/check/sqs_queues_not_publicly_accessible"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
|
||||
@@ -1,26 +1,35 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "sqs_queues_server_side_encryption_enabled",
|
||||
"CheckTitle": "Check if SQS queues have Server Side Encryption enabled",
|
||||
"CheckType": [],
|
||||
"CheckTitle": "SQS queue has server-side encryption enabled",
|
||||
"CheckType": [
|
||||
"Software and Configuration Checks/AWS Security Best Practices",
|
||||
"Industry and Regulatory Standards/AWS Foundational Security Best Practices",
|
||||
"Effects/Data Exposure"
|
||||
],
|
||||
"ServiceName": "sqs",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:aws:sqs:region:account-id:queue",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AwsSqsQueue",
|
||||
"Description": "Check if SQS queues have Server Side Encryption enabled",
|
||||
"Risk": "If not enabled sensitive information in transit is not protected.",
|
||||
"RelatedUrl": "https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-sse-existing-queue.html",
|
||||
"Description": "**Amazon SQS queues** are evaluated for **server-side encryption** configured with a **KMS key** (`SSE-KMS`) protecting message bodies at rest.\n\nQueues without an associated KMS key are identified.",
|
||||
"Risk": "Without **KMS-backed SSE**, message bodies lack tenant-controlled keys and detailed audit. Secrets, tokens, or PII in messages become easier to access through **privilege misuse**, misconfiguration, or unintended integrations, reducing **confidentiality** and limiting containment since you cannot revoke access via key disable/rotation.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-server-side-encryption.html",
|
||||
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SQS/queue-encrypted-with-kms-customer-master-keys.html",
|
||||
"https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-sse-existing-queue.html"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "aws sqs set-queue-attributes --queue-url <QUEUE_URL> --attributes KmsMasterKeyId=<KEY>",
|
||||
"NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/general_16-encrypt-sqs-queue#cloudformation",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SQS/queue-encrypted-with-kms-customer-master-keys.html",
|
||||
"Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_16-encrypt-sqs-queue#terraform"
|
||||
"CLI": "aws sqs set-queue-attributes --queue-url <QUEUE_URL> --attributes KmsMasterKeyId=<KMS_KEY_ID_OR_ALIAS>",
|
||||
"NativeIaC": "```yaml\n# CloudFormation: Enable SSE-KMS for an SQS queue\nResources:\n <example_resource_name>:\n Type: AWS::SQS::Queue\n Properties:\n KmsMasterKeyId: alias/aws/sqs # Critical: sets a KMS key, enabling SSE-KMS so the queue reports a kms_key_id\n```",
|
||||
"Other": "1. In the AWS Console, go to Amazon SQS > Queues\n2. Select the queue and click Edit\n3. Expand Encryption\n4. Set Server-side encryption to Enabled\n5. For AWS KMS key, select alias/aws/sqs (or choose a specific KMS key)\n6. Click Save",
|
||||
"Terraform": "```hcl\n# Enable SSE-KMS for an SQS queue\nresource \"aws_sqs_queue\" \"<example_resource_name>\" {\n kms_master_key_id = \"alias/aws/sqs\" # Critical: sets a KMS key, enabling SSE-KMS so the queue reports a kms_key_id\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable Encryption. Use a CMK where possible. It will provide additional management and privacy benefits",
|
||||
"Url": "https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-sse-existing-queue.html"
|
||||
"Text": "Enable **SSE-KMS** on all queues using a **customer-managed KMS key**.\n- Apply **least privilege** to key and queue policies; restrict `Encrypt/Decrypt`\n- Enforce key rotation and separation of duties\n- Tune data key reuse for security vs. cost\n- Monitor key and queue access to support **defense in depth**",
|
||||
"Url": "https://hub.prowler.com/check/sqs_queues_server_side_encryption_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
|
||||
@@ -1,28 +1,33 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "stepfunctions_statemachine_logging_enabled",
|
||||
"CheckTitle": "Step Functions state machines should have logging enabled",
|
||||
"CheckTitle": "Step Functions state machine has logging enabled",
|
||||
"CheckType": [
|
||||
"Software and Configuration Checks/AWS Security Best Practices"
|
||||
"Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis"
|
||||
],
|
||||
"ServiceName": "stepfunctions",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:aws:states:{region}:{account-id}:stateMachine/{stateMachine-id}",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AwsStepFunctionStateMachine",
|
||||
"Description": "This control checks if AWS Step Functions state machines have logging enabled. The control fails if the state machine doesn't have the loggingConfiguration property defined.",
|
||||
"Risk": "Without logging enabled, important operational data may be lost, making it difficult to troubleshoot issues, monitor performance, and ensure compliance with auditing requirements.",
|
||||
"RelatedUrl": "https://docs.aws.amazon.com/step-functions/latest/dg/logging.html",
|
||||
"Description": "**AWS Step Functions state machines** are configured to emit **execution logs** to CloudWatch Logs via a defined `loggingConfiguration` with a `level` set above `OFF`.",
|
||||
"Risk": "Without **execution logs**, workflow failures and anomalies are **undetectable**, increasing MTTR and risking silent data loss. Missing audit trails weaken **integrity** oversight and complicate **forensics**, enabling misuse of invoked services to go unnoticed and creating **compliance** gaps.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://docs.aws.amazon.com/step-functions/latest/dg/logging.html",
|
||||
"https://docs.aws.amazon.com/securityhub/latest/userguide/stepfunctions-controls.html#stepfunctions-1",
|
||||
"https://support.icompaas.com/support/solutions/articles/62000233757-ensure-step-functions-state-machines-should-have-logging-enabled"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "aws stepfunctions update-state-machine --state-machine-arn <state-machine-arn> --logging-configuration file://logging-config.json",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/stepfunctions-controls.html#stepfunctions-1",
|
||||
"Terraform": "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sfn_state_machine#logging_configuration"
|
||||
"NativeIaC": "```yaml\nResources:\n <example_resource_name>:\n Type: AWS::StepFunctions::StateMachine\n Properties:\n RoleArn: arn:aws:iam::<account-id>:role/<example_role_name>\n DefinitionString: |\n {\"StartAt\":\"Pass\",\"States\":{\"Pass\":{\"Type\":\"Pass\",\"End\":true}}}\n LoggingConfiguration:\n Destinations:\n - CloudWatchLogsLogGroup:\n LogGroupArn: arn:aws:logs:<region>:<account-id>:log-group:<log-group-name>:* # Critical: target CloudWatch Logs group\n Level: ERROR # Critical: enables logging (not OFF)\n```",
|
||||
"Other": "1. Open AWS Console > Step Functions > State machines\n2. Select the state machine and click Edit\n3. In Logging, enable logging\n4. Choose an existing CloudWatch Logs log group\n5. Set Level to Error (or All)\n6. Save changes",
|
||||
"Terraform": "```hcl\nresource \"aws_sfn_state_machine\" \"<example_resource_name>\" {\n name = \"<example_resource_name>\"\n role_arn = \"arn:aws:iam::<account-id>:role/<example_role_name>\"\n definition = jsonencode({ StartAt = \"Pass\", States = { Pass = { Type = \"Pass\", End = true } } })\n\n logging_configuration {\n log_destination = \"arn:aws:logs:<region>:<account-id>:log-group:<log-group-name>:*\" # Critical: CloudWatch Logs destination\n level = \"ERROR\" # Critical: enables logging\n }\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Configure logging for your Step Functions state machines to ensure that operational data is captured and available for debugging, monitoring, and auditing purposes.",
|
||||
"Url": "https://docs.aws.amazon.com/step-functions/latest/dg/logging.html"
|
||||
"Text": "Enable CloudWatch logging on all state machines at an appropriate `level` (e.g., `ERROR` or `ALL`) and send logs to a protected log group. Apply **least privilege** to log write/read, set **retention**, and avoid sensitive data unless required using `includeExecutionData`. Use X-Ray tracing for **defense in depth**.",
|
||||
"Url": "https://hub.prowler.com/check/stepfunctions_statemachine_logging_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
|
||||
@@ -1,29 +1,42 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "sqlserver_auditing_enabled",
|
||||
"CheckTitle": "Ensure that SQL Servers have an audit policy configured",
|
||||
"CheckTitle": "SQL Server has an auditing policy configured",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sqlserver",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "SQLServer",
|
||||
"Description": "Ensure that there is an audit policy configured",
|
||||
"Risk": "Audit policies are used to store logs associated to the SQL server (for instance, successful/unsuccesful log in attempts). These logs may be useful to detect anomalies or to perform an investigation in case a security incident is detected",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/azure/sql-database/sql-database-auditing",
|
||||
"Severity": "high",
|
||||
"ResourceType": "microsoft.sql/servers",
|
||||
"Description": "**Azure SQL Server** auditing is assessed at the server level to confirm audit logging is active. Configurations with any auditing policy state set to `Disabled` indicate auditing is not configured for the server and its databases.",
|
||||
"Risk": "Without **SQL auditing**, visibility into logins, privilege changes, and query activity is lost. Stealthy data exfiltration and tampering can go undetected, impacting **confidentiality** and **integrity**. Absent audit trails hinder **forensics**, slow incident response, and weaken compliance evidence.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://www.linkedin.com/learning/microsoft-azure-database-administrator-associate-dp-300-cert-prep-by-microsoft-press/configure-server-and-database-audits",
|
||||
"https://irzu.org/research/auditing-azure-sql-microsoft-qa/",
|
||||
"https://learn.microsoft.com/is-is/azure/azure-sql/database/auditing-overview?view=azuresql&viewFallbackFrom=azuresql-vm",
|
||||
"https://www.mssqltips.com/sqlservertip/6732/azure-sql-database-auditing/",
|
||||
"https://connectioncloudsupport.zendesk.com/hc/en-us/articles/4402652204441-Auditing-for-Azure-SQL-Database-and-Azure-Synapse-Analytics",
|
||||
"https://docs.prowler.com/checks/azure/azure-logging-policies/bc_azr_logging_2",
|
||||
"https://docs.prowler.com/checks/azure/azure-logging-policies/bc_azr_logging_2#terraform",
|
||||
"https://docs.microsoft.com/en-us/azure/sql-database/sql-database-auditing",
|
||||
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Sql/auditing.html"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "Set-AzureRmSqlServerAuditingPolicy -ResourceGroupName <RESOURCE_GROUP_NAME> -ServerName <SERVER_NAME> -AuditType <AUDIT_TYPE> -StorageAccountName <STORAGE_ACCOUNT_NAME>",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://docs.prowler.com/checks/azure/azure-logging-policies/bc_azr_logging_2",
|
||||
"Terraform": "https://docs.prowler.com/checks/azure/azure-logging-policies/bc_azr_logging_2#terraform"
|
||||
"CLI": "az sql server audit-policy update --resource-group <RESOURCE_GROUP_NAME> --name <SERVER_NAME> --state Enabled --storage-account <STORAGE_ACCOUNT_NAME>",
|
||||
"NativeIaC": "```bicep\n// Enable server-level auditing to an existing Storage Account\nparam sqlServerName string = \"<example_resource_name>\"\nparam storageAccountName string = \"<example_resource_name>\"\n\nresource sql 'Microsoft.Sql/servers@2021-11-01' existing = {\n name: sqlServerName\n}\n\nresource sa 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {\n name: storageAccountName\n}\n\nresource audit 'Microsoft.Sql/servers/auditingSettings@2021-11-01' = {\n name: 'default'\n parent: sql\n properties: {\n state: 'Enabled' // Critical: turns on auditing\n storageEndpoint: 'https://${sa.name}.blob.core.windows.net/' // Critical: audit log destination\n storageAccountAccessKey: listKeys(sa.id, '2023-01-01').keys[0].value // Critical: grants write access to logs\n }\n}\n```",
|
||||
"Other": "1. In Azure Portal, go to SQL servers and select your server\n2. Under Security, click Auditing\n3. Set Auditing to On\n4. Select Storage as the destination and choose a Storage account\n5. Click Save",
|
||||
"Terraform": "```hcl\n# Enable server-level auditing to Azure Storage\nresource \"azurerm_mssql_server_extended_auditing_policy\" \"<example_resource_name>\" {\n server_id = \"<example_resource_id>\"\n storage_endpoint = \"https://<STORAGE_ACCOUNT_NAME>.blob.core.windows.net/\" # Critical: audit log destination\n storage_account_access_key = \"<STORAGE_ACCOUNT_KEY>\" # Critical: allows writing audit logs\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Create an audit policy for the SQL server",
|
||||
"Url": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Sql/auditing.html"
|
||||
"Text": "Enable server-level **auditing** and send logs to a centralized, tamper-resistant store with defined retention. Enforce **least privilege** and **separation of duties** for log access, integrate with monitoring for alerts, and periodically validate coverage. Use database-level auditing only for specific exceptions.",
|
||||
"Url": "https://hub.prowler.com/check/sqlserver_auditing_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"logging"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
|
||||
@@ -1,29 +1,38 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "sqlserver_auditing_retention_90_days",
|
||||
"CheckTitle": "Ensure that 'Auditing' Retention is 'greater than 90 days'",
|
||||
"CheckTitle": "SQL server has auditing enabled with retention greater than 90 days",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sqlserver",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "SQLServer",
|
||||
"Description": "SQL Server Audit Retention should be configured to be greater than 90 days.",
|
||||
"Risk": "Audit Logs can be used to check for anomalies and give insight into suspected breaches or misuse of information and access.",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/azure/sql-database/sql-database-auditing",
|
||||
"Severity": "high",
|
||||
"ResourceType": "microsoft.sql/servers",
|
||||
"Description": "**Azure SQL Server auditing** settings are evaluated to ensure **auditing is enabled** and log retention is greater than `90` days. It considers the auditing policy state and the configured `retention_days` value.",
|
||||
"Risk": "Without adequate retention or with auditing disabled, **activity trails expire too soon**, limiting detection and investigation of **unauthorized access, data exfiltration, and privilege abuse**. This weakens **confidentiality** and **integrity** and slows incident response.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://learn.microsoft.com/en-us/purview/audit-log-retention-policies",
|
||||
"https://docs.prowler.com/checks/azure/azure-logging-policies/bc_azr_logging_3",
|
||||
"https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/auditing-retention.html#",
|
||||
"https://docs.microsoft.com/en-us/azure/sql-database/sql-database-auditing"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "Set-AzSqlServerAudit -ResourceGroupName resource_group_name -ServerName SQL_Server_name -RetentionInDays 100 -LogAnalyticsTargetState Enabled -WorkspaceResourceId '/subscriptions/subscription_ID/resourceGroups/insights-integration/providers/Microsoft.OperationalInsights/workspaces/workspace_name'",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/auditing-retention.html#",
|
||||
"Terraform": "https://docs.prowler.com/checks/azure/azure-logging-policies/bc_azr_logging_3"
|
||||
"CLI": "Set-AzSqlServerAudit -ResourceGroupName <example_resource_name> -ServerName <example_resource_name> -RetentionInDays 91 -LogAnalyticsTargetState Enabled -WorkspaceResourceId <example_resource_id>",
|
||||
"NativeIaC": "```bicep\n// Enable server-level auditing with retention > 90 days\nresource audit 'Microsoft.Sql/servers/auditingSettings@2021-02-01-preview' = {\n name: '<example_resource_name>/default'\n properties: {\n state: 'Enabled' // Critical: turns auditing ON\n retentionDays: 91 // Critical: > 90 days\n isAzureMonitorTargetEnabled: true // Critical: send to Log Analytics\n workspaceResourceId: '<example_resource_id>' // Critical: target workspace\n }\n}\n```",
|
||||
"Other": "1. In Azure Portal, go to SQL servers and select <example_resource_name>\n2. Under Security, click Auditing\n3. Set Auditing to On\n4. Destination: select Log Analytics workspace and choose your workspace\n5. Set Retention (days) to 91\n6. Click Save",
|
||||
"Terraform": "```hcl\n# Enable server-level auditing with retention > 90 days\nresource \"azurerm_mssql_server_extended_auditing_policy\" \"audit\" {\n server_id = \"<example_resource_id>\"\n log_monitoring_enabled = true # Critical: enable Log Analytics target\n retention_in_days = 91 # Critical: > 90 days\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "1. Go to SQL servers 2. For each server instance 3. Click on Auditing 4. If storage is selected, expand Advanced properties 5. Set the Retention (days) setting greater than 90 days or 0 for unlimited retention. 6. Select Save",
|
||||
"Url": "https://learn.microsoft.com/en-us/purview/audit-log-retention-policies"
|
||||
"Text": "Enable **server-level auditing** and set retention above `90` days, aligned with policy needs. Store logs in **tamper-resistant, centralized storage**, restrict access with **least privilege**, and integrate alerting and review. Apply **defense in depth** with continuous monitoring.",
|
||||
"Url": "https://hub.prowler.com/check/sqlserver_auditing_retention_90_days"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"logging",
|
||||
"forensics-ready"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
|
||||
@@ -1,29 +1,36 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "sqlserver_azuread_administrator_enabled",
|
||||
"CheckTitle": "Ensure that SQL Servers have an Azure Active Directory administrator",
|
||||
"CheckTitle": "SQL Server has an Azure Active Directory administrator configured",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sqlserver",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "SQLServer",
|
||||
"Description": "Ensure that there is an Azure Active Directory administrator configured",
|
||||
"Risk": "Azure Active Directory provides a centralized way of managing identities. Using local SQL administrator identites makes it more difficult to manage user accounts. In addition, from Azure Active Directory, security policies can be enforced to users in centralized way.",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/azure/sql-database/sql-database-aad-authentication",
|
||||
"ResourceType": "microsoft.sql/servers",
|
||||
"Description": "Azure SQL Server is configured with a **Microsoft Entra (Azure AD) administrator** at the server scope, indicated by `administrator_type` set to `ActiveDirectory`.",
|
||||
"Risk": "Without a **Microsoft Entra admin**, the server can't use Entra identities, pushing reliance on **SQL authentication**. This weakens confidentiality and integrity: no MFA/conditional access, harder offboarding and auditing, and compromised passwords can enable unauthorized data access and privilege escalation.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-azure-active-directory-admin-is-configured#terraform",
|
||||
"https://docs.microsoft.com/en-us/azure/sql-database/sql-database-aad-authentication",
|
||||
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Sql/active-directory-admin.html"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "az sql server ad-admin create --resource-group resource_group_name --server server_name --display-name display_name --object-id user_object_id",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Sql/active-directory-admin.html",
|
||||
"Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-azure-active-directory-admin-is-configured#terraform"
|
||||
"CLI": "az sql server ad-admin create --resource-group <RESOURCE_GROUP> --server <SERVER_NAME> --display-name <AAD_ADMIN_NAME> --object-id <AAD_OBJECT_ID>",
|
||||
"NativeIaC": "```bicep\n// Configure Microsoft Entra (Azure AD) admin on an existing SQL Server\nresource aadAdmin 'Microsoft.Sql/servers/administrators@2021-11-01' = {\n name: '<example_resource_name>/ActiveDirectory' // serverName/ActiveDirectory\n properties: {\n administratorType: 'ActiveDirectory' // CRITICAL: ensures admin type is AAD\n login: '<AAD_ADMIN_NAME>' // CRITICAL: AAD admin display name\n sid: '<AAD_OBJECT_ID>' // CRITICAL: AAD object (GUID)\n tenantId: '<TENANT_ID>' // CRITICAL: Tenant where the AAD object exists\n }\n}\n```",
|
||||
"Other": "1. In Azure Portal, go to SQL servers and select <SERVER_NAME>\n2. Select Active Directory admin\n3. Click Set admin\n4. Select the desired Microsoft Entra user or group and click Select\n5. Click Save",
|
||||
"Terraform": "```hcl\n# Set Microsoft Entra (Azure AD) admin on an existing SQL Server\nresource \"azurerm_mssql_active_directory_administrator\" \"<example_resource_name>\" {\n server_id = \"<example_resource_id>\" # CRITICAL: target SQL server resource ID\n login = \"<AAD_ADMIN_NAME>\" # CRITICAL: AAD admin display name\n object_id = \"<AAD_OBJECT_ID>\" # CRITICAL: AAD object (GUID)\n tenant_id = \"<TENANT_ID>\" # CRITICAL: Tenant where the AAD object exists\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable an Azure Active Directory administrator",
|
||||
"Url": ""
|
||||
"Text": "Assign a **Microsoft Entra administrator** (prefer a security group) at the server level and manage access via Entra groups. Enforce **least privilege**, require **MFA/conditional access**, and use **managed identities** for services. *If feasible*, adopt Entra-only authentication and phase out shared SQL logins.",
|
||||
"Url": "https://hub.prowler.com/check/sqlserver_azuread_administrator_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"identity-access"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
|
||||
@@ -1,29 +1,39 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "sqlserver_microsoft_defender_enabled",
|
||||
"CheckTitle": "Ensure that Microsoft Defender for SQL is set to 'On' for critical SQL Servers",
|
||||
"CheckTitle": "SQL Server has Microsoft Defender for SQL enabled",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sqlserver",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "SQLServer",
|
||||
"Description": "Ensure that Microsoft Defender for SQL is set to 'On' for critical SQL Servers",
|
||||
"Risk": "Microsoft Defender for SQL is a unified package for advanced SQL security capabilities. Microsoft Defender is available for Azure SQL Database, Azure SQL Managed classifying sensitive data, surfacing and mitigating potential database vulnerabilities, and detecting anomalous activities that could indicate a threat to your database. It provides a single go-to location for enabling and managing these capabilities.",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/azure/azure-sql/database/azure-defender-for-sql?view=azuresql",
|
||||
"Severity": "high",
|
||||
"ResourceType": "microsoft.sql/servers",
|
||||
"Description": "**Azure SQL Server** instances are evaluated for the server-level **security alert policy** of **Microsoft Defender for SQL**, expecting the policy state to be `Enabled`.",
|
||||
"Risk": "Without **Defender for SQL**, anomalous logins, SQL injection patterns, and risky configurations may go undetected, enabling data exfiltration (**confidentiality**), unauthorized changes (**integrity**), and disruptive queries or ransomware (**availability**).",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://www.azadvertizer.net/azpolicyadvertizer/7fe3b40f-802b-4cdd-8bd4-fd799c948cc2.html",
|
||||
"https://docs.microsoft.com/en-us/azure/azure-sql/database/azure-defender-for-sql?view=azuresql",
|
||||
"https://learn.microsoft.com/en-us/azure/defender-for-cloud/defender-for-sql-usage",
|
||||
"https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/SecurityCenter/defender-azure-sql.html",
|
||||
"https://learn.microsoft.com/en-us/azure/defender-for-cloud/policy-reference"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/SecurityCenter/defender-azure-sql.html",
|
||||
"Terraform": ""
|
||||
"CLI": "az sql server threat-policy update --resource-group <RESOURCE_GROUP> --server <SERVER_NAME> --state Enabled",
|
||||
"NativeIaC": "```bicep\nparam serverName string = '<example_resource_name>'\n\nresource securityAlert 'Microsoft.Sql/servers/securityAlertPolicies@2021-11-01' = {\n name: '${serverName}/Default'\n properties: {\n state: 'Enabled' // Critical: enables the server's security alert policy (Defender for SQL)\n }\n}\n```",
|
||||
"Other": "1. Sign in to the Azure portal > SQL servers > select <SERVER_NAME>\n2. Under Security, select Microsoft Defender for SQL (or Microsoft Defender for Cloud)\n3. Toggle to On (Enable) and click Save",
|
||||
"Terraform": "```hcl\nresource \"azurerm_mssql_server_security_alert_policy\" \"<example_resource_name>\" {\n server_id = \"<example_resource_id>\"\n state = \"Enabled\" # Critical: enables the server's security alert policy (Defender for SQL)\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "1. Go to SQL servers For each production SQL server instance: 2. Click Microsoft Defender for Cloud 3. Click Enable Microsoft Defender for SQL",
|
||||
"Url": "https://learn.microsoft.com/en-us/azure/defender-for-cloud/defender-for-sql-usage"
|
||||
"Text": "Enable **Microsoft Defender for SQL** across all servers and managed instances, preferably at subscription scope. Apply **least privilege**, restrict public exposure, and integrate alerts with your SOC. Regularly review **vulnerability assessment** results and harden findings as part of **defense in depth**.",
|
||||
"Url": "https://hub.prowler.com/check/sqlserver_microsoft_defender_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"logging",
|
||||
"forensics-ready"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "Microsoft Defender for SQL is a paid feature and will incur additional cost for each SQL server."
|
||||
|
||||
@@ -1,29 +1,40 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "sqlserver_recommended_minimal_tls_version",
|
||||
"CheckTitle": "Ensure SQL server has a recommended minimal TLS version required.",
|
||||
"CheckTitle": "SQL server enforces minimal TLS version 1.2 or 1.3",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sqlserver",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "SQLServer",
|
||||
"Description": "Ensure that SQL Server instances are configured with the recommended minimal TLS version to maintain secure connections.",
|
||||
"Risk": "Using outdated or weak TLS versions can expose SQL Server instances to vulnerabilities, increasing the risk of data breaches and unauthorized access.",
|
||||
"RelatedUrl": "https://learn.microsoft.com/en-us/azure/azure-sql/database/connectivity-settings?view=azuresql&tabs=azure-portal#configure-minimum-tls-version",
|
||||
"ResourceType": "microsoft.sql/servers",
|
||||
"Description": "**Azure SQL logical servers** are assessed for the configured **minimum TLS version** for client connections. The finding determines whether the minimal accepted version aligns with recommended modern values such as `1.2` or `1.3`.",
|
||||
"Risk": "Without a modern minimum, clients can negotiate **weak TLS** or be downgraded, enabling **MITM** and decryption. This jeopardizes **confidentiality** (credential/data exposure) and **integrity** (query tampering), and may disrupt **availability** via session resets during handshake interference.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://argonsys.com/microsoft-cloud/library/preparing-for-the-deprecation-of-tls-1-0-and-1-1-in-azure-databases/",
|
||||
"https://githubissues.com/MicrosoftDocs/azure-docs/117817",
|
||||
"https://stackoverflow.com/questions/66102487/jdbc-cant-connect-to-sql-server-azure-sql-database",
|
||||
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Sql/db-minimum-tls-version-check.html",
|
||||
"https://learn.microsoft.com/en-us/azure/azure-sql/database/connectivity-settings?view=azuresql&tabs=azure-portal#configure-minimum-tls-version",
|
||||
"https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/minimal-tls-version-configure?view=azuresql",
|
||||
"https://solutions.microsoft.xtivia.com/blog/azure-deprecating-tls-1-0-and-1-1/"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "az sql server update -n sql-server-name -g sql-server-group --set minimalTlsVersion=<version>",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
"CLI": "az sql server update -n <SQL_SERVER_NAME> -g <RESOURCE_GROUP> --set minimalTlsVersion=\"1.2\"",
|
||||
"NativeIaC": "```bicep\n// Update Azure SQL logical server to enforce minimum TLS 1.2\nresource sqlServer 'Microsoft.Sql/servers@2021-11-01' = {\n name: '<example_resource_name>'\n location: resourceGroup().location\n properties: {\n minimalTlsVersion: '1.2' // Critical: Enforces TLS 1.2+ for client connections\n }\n}\n```",
|
||||
"Other": "1. In the Azure portal, go to SQL servers and select your server\n2. Open Networking > Connectivity\n3. Set Minimum TLS Version to 1.2 (or 1.3)\n4. Click Save",
|
||||
"Terraform": "```hcl\n# Enforce minimum TLS 1.2 on Azure SQL logical server\nresource \"azurerm_mssql_server\" \"<example_resource_name>\" {\n name = \"<example_resource_name>\"\n resource_group_name = \"<example_resource_name>\"\n location = \"<example_location>\"\n version = \"12.0\"\n administrator_login = \"<example_admin>\"\n administrator_login_password = \"<example_password>\"\n\n minimum_tls_version = \"1.2\" # Critical: Enforces TLS 1.2+ for client connections\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "1. Go to Azure SQL Server 2. Navigate to 'Security' -> 'Networking' 3. Select 'Connectivity' 4. Update the TLS version in the field 'Minimum TLS version' to a recommended minimal version (e.g., TLS 1.2).",
|
||||
"Url": "https://learn.microsoft.com/en-us/azure/azure-sql/database/connectivity-settings?view=azuresql&tabs=azure-portal#configure-minimum-tls-version"
|
||||
"Text": "Set the **minimum TLS** to `1.2` or higher (prefer `1.3` when supported). Upgrade client libraries and OS trust stores; remove legacy protocols and weak ciphers to prevent downgrades. Validate compatibility before enforcement and monitor connections for outdated TLS. Uphold **encryption in transit** and **defense in depth**.",
|
||||
"Url": "https://hub.prowler.com/check/sqlserver_recommended_minimal_tls_version"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"encryption"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "Verify support for the TLS version from the application side before changing the minimal version."
|
||||
|
||||
@@ -1,29 +1,36 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "sqlserver_tde_encrypted_with_cmk",
|
||||
"CheckTitle": "Ensure SQL server's Transparent Data Encryption (TDE) protector is encrypted with Customer-managed key",
|
||||
"CheckTitle": "SQL server uses a customer-managed key for the TDE protector and all databases have TDE enabled",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sqlserver",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "SQLServer",
|
||||
"Description": "Transparent Data Encryption (TDE) with Customer-managed key support provides increased transparency and control over the TDE Protector, increased security with an HSM-backed external service, and promotion of separation of duties.",
|
||||
"Risk": "Customer-managed key support for Transparent Data Encryption (TDE) allows user control of TDE encryption keys and restricts who can access them and when. Azure Key Vault, Azure cloud-based external key management system, is the first key management service where TDE has integrated support for Customer-managed keys. With Customer-managed key support, the database encryption key is protected by an asymmetric key stored in the Key Vault. The asymmetric key is set at the server level and inherited by all databases under that server",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/sql/relational-databases/security/encryption/transparent-data-encryption-byok-azure-sql",
|
||||
"Severity": "critical",
|
||||
"ResourceType": "microsoft.sql/servers",
|
||||
"Description": "**Azure SQL Server** uses **Transparent Data Encryption** with a **customer-managed key** in Azure Key Vault, and each database has TDE `Enabled`",
|
||||
"Risk": "Without **TDE with CMK**, data at rest may be unencrypted or controlled by service keys, weakening **confidentiality** and **key custody**. Attackers or insiders could read backups, snapshots, or stolen disks, and you cannot enforce **rotation**, **revocation**, or **separation of duties**, raising compliance and incident response risks.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/use-byok-for-transparent-data-encryption.html#",
|
||||
"https://learn.microsoft.com/en-us/azure/azure-sql/database/transparent-data-encryption-byok-overview?view=azuresql",
|
||||
"https://docs.microsoft.com/en-us/sql/relational-databases/security/encryption/transparent-data-encryption-byok-azure-sql"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "az sql server tde-key set --resource-group resourceName --server dbServerName --server-key-type {AzureKeyVault} --kid keyIdentifier",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/use-byok-for-transparent-data-encryption.html#",
|
||||
"Terraform": ""
|
||||
"CLI": "",
|
||||
"NativeIaC": "```bicep\n// Add the Key Vault key to the SQL server\nresource serverKey 'Microsoft.Sql/servers/keys@2021-11-01' = {\n name: '<example_resource_name>/<example_resource_name>'\n properties: {\n serverKeyType: 'AzureKeyVault' // critical: use a customer-managed key from Azure Key Vault\n uri: 'https://<example_resource_name>.vault.azure.net/keys/<example_resource_name>/<example_resource_id>' // critical: KID of the Key Vault key\n }\n}\n\n// Set the server TDE protector to the Key Vault key (CMK)\nresource encryptionProtector 'Microsoft.Sql/servers/encryptionProtector@2021-11-01' = {\n name: '<example_resource_name>/current'\n properties: {\n serverKeyType: 'AzureKeyVault' // critical: switches protector from service-managed to CMK\n serverKeyName: '<example_resource_name>' // critical: reference the key added above\n }\n}\n\n// Ensure TDE is enabled on the database\nresource dbTde 'Microsoft.Sql/servers/databases/transparentDataEncryption@2014-04-01' = {\n name: '<example_resource_name>/<example_resource_name>/current'\n properties: {\n status: 'Enabled' // critical: turns on TDE for the database\n }\n}\n```",
|
||||
"Other": "1. In the Azure portal, go to SQL servers > select <server>\n2. Under Security, open Transparent data encryption\n3. Select Customer-managed key and choose the key from Azure Key Vault, then Save\n4. For each database on this server: go to SQL databases > select <database> > Transparent data encryption\n5. Set Status to On and Save",
|
||||
"Terraform": "```hcl\n# Set the SQL Server TDE protector to a Key Vault CMK\nresource \"azurerm_sql_server_key\" \"<example_resource_name>\" {\n server_id = \"<example_resource_id>\"\n key_vault_key_id = \"<key_identifier>\" # critical: KID of the Key Vault key to use as TDE protector\n}\n\n# Ensure TDE is enabled on the database\nresource \"azurerm_sql_database_transparent_data_encryption\" \"<example_resource_name>\" {\n resource_group_name = \"<example_resource_name>\"\n server_name = \"<example_resource_name>\"\n database_name = \"<example_resource_name>\"\n enabled = true # critical: turns on TDE for the database\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "1. Go to SQL servers For the desired server instance 2. Click On Transparent data encryption 3. Set Transparent data encryption to Customer-managed key 4. Browse through your key vaults to Select an existing key or create a new key in the Azure Key Vault. 5. Check Make selected key the default TDE protector",
|
||||
"Url": "https://learn.microsoft.com/en-us/azure/azure-sql/database/transparent-data-encryption-byok-overview?view=azuresql"
|
||||
"Text": "Use a **customer-managed TDE protector** in Azure Key Vault or Managed HSM and ensure TDE is `Enabled` for every database.\n- Apply **least privilege** to key access\n- Enable **rotation** and monitor key use\n- Protect keys with soft-delete and purge protection\n- Enforce via **policy** and maintain key backups for restores",
|
||||
"Url": "https://hub.prowler.com/check/sqlserver_tde_encrypted_with_cmk"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"encryption"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "Once TDE protector is encrypted with a Customer-managed key, it transfers entire responsibility of respective key management on to you, and hence you should be more careful about doing any operations on the particular key in order to keep data from corresponding SQL server and Databases hosted accessible. When deploying Customer Managed Keys, it is prudent to ensure that you also deploy an automated toolset for managing these keys (this should include discovery and key rotation), and Keys should be stored in an HSM or hardware backed keystore, such as Azure Key Vault. As far as toolsets go, check with your cryptographic key provider, as they may well provide one as an add-on to their service."
|
||||
|
||||
@@ -1,29 +1,36 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "sqlserver_tde_encryption_enabled",
|
||||
"CheckTitle": "Ensure SQL server's Transparent Data Encryption (TDE) protector is encrypted",
|
||||
"CheckTitle": "SQL database has Transparent Data Encryption (TDE) enabled",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sqlserver",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "SQLServer",
|
||||
"Description": "Enable Transparent Data Encryption on every SQL server.",
|
||||
"Risk": "Azure SQL Database transparent data encryption helps protect against the threat of malicious activity by performing real-time encryption and decryption of the database, associated backups, and transaction log files at rest without requiring changes to the application.",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/sql/relational-databases/security/encryption/transparent-data-encryption-with-azure-sql-database",
|
||||
"Severity": "critical",
|
||||
"ResourceType": "microsoft.sql/servers/databases",
|
||||
"Description": "**Azure SQL user databases** have **Transparent Data Encryption** (`TDE`) enabled, ensuring encryption of database files, backups, and transaction logs at rest.\n\n*The `master` system database is excluded from evaluation.*",
|
||||
"Risk": "Without **TDE**, data at rest remains unencrypted:\n- Stolen backups, snapshots, or compromised storage enable offline data disclosure\n- Attackers with substrate access can bypass DB auth, harming **confidentiality** and enabling **exfiltration**",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://docs.microsoft.com/en-us/sql/relational-databases/security/encryption/transparent-data-encryption-with-azure-sql-database",
|
||||
"https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/data-encryption.html#",
|
||||
"https://learn.microsoft.com/en-us/azure/azure-sql/database/transparent-data-encryption-byok-overview?view=azuresql"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "az sql db tde set --resource-group resourceGroup --server dbServerName --database dbName --status Enabled",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/data-encryption.html#",
|
||||
"Terraform": ""
|
||||
"CLI": "az sql db tde set --resource-group <RESOURCE_GROUP> --server <SERVER_NAME> --database <DATABASE_NAME> --status Enabled",
|
||||
"NativeIaC": "```bicep\n// Enable TDE on an existing Azure SQL Database\nresource tde 'Microsoft.Sql/servers/databases/transparentDataEncryption@2021-11-01' = {\n name: '<example_server_name>/<example_database_name>/current'\n properties: {\n state: 'Enabled' // critical: enables Transparent Data Encryption (TDE)\n }\n}\n```",
|
||||
"Other": "1. In Azure Portal, go to SQL databases and select the target database (not master)\n2. Under Settings, open Transparent data encryption\n3. Set Transparent data encryption to On (Enabled) and click Save",
|
||||
"Terraform": "```hcl\nresource \"azurerm_mssql_database\" \"<example_resource_name>\" {\n name = \"<example_resource_name>\"\n server_id = \"<example_resource_id>\"\n\n transparent_data_encryption_enabled = true # critical: enables TDE\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "1. Go to SQL databases 2. For each DB instance 3. Click on Transparent data encryption 4. Set Data encryption to On",
|
||||
"Url": "https://learn.microsoft.com/en-us/azure/azure-sql/database/transparent-data-encryption-byok-overview?view=azuresql"
|
||||
"Text": "Enable **TDE** on all Azure SQL user databases. Prefer **customer-managed keys** in Key Vault or Managed HSM for control, rotation, and revocation. Apply **least privilege** and **separation of duties** to key access, enforce via **policy**, and monitor key/audit logs. *Maintain key backups and lifecycle to prevent availability loss.*",
|
||||
"Url": "https://hub.prowler.com/check/sqlserver_tde_encryption_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"encryption"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
|
||||
@@ -1,29 +1,38 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "sqlserver_unrestricted_inbound_access",
|
||||
"CheckTitle": "Ensure no Azure SQL Databases allow ingress from 0.0.0.0/0 (ANY IP)",
|
||||
"CheckTitle": "Azure SQL Server does not have firewall rules allowing 0.0.0.0-255.255.255.255",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sqlserver",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "critical",
|
||||
"ResourceType": "SQLServer",
|
||||
"Description": "Ensure that there are no firewall rules allowing traffic from 0.0.0.0-255.255.255.255",
|
||||
"Risk": "Azure SQL servers provide a firewall that, by default, blocks all Internet connections. When the rule (0.0.0.0-255.255.255.255) is used, the server can be accessed by any source from the Internet, incrementing significantly the attack surface of the SQL Server. It is recommended to use more granular firewall rules.",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/azure/sql-database/sql-database-vnet-service-endpoint-rule-overview",
|
||||
"ResourceType": "microsoft.sql/servers",
|
||||
"Description": "**Azure SQL Server** server-level firewall rules are evaluated for an entry that allows the entire IPv4 space (`0.0.0.0` to `255.255.255.255`).\n\nThe finding identifies presence of this Internet-wide rule on the server firewall.",
|
||||
"Risk": "An Internet-wide rule permits unsolicited access from any host, enabling mass scanning, brute force, and exploitation of weak configurations.\n- Confidentiality: unauthorized data access/exfiltration\n- Integrity: malicious data/DDL changes\n- Availability: resource abuse or DoS via excessive connections",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_4#terraform",
|
||||
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Sql/unrestricted-sql-database-access.html",
|
||||
"https://docs.microsoft.com/en-us/azure/sql-database/sql-database-vnet-service-endpoint-rule-overview",
|
||||
"https://www.developerload.com/how-to-disable-firewall-in-azure-sql-database",
|
||||
"https://eitanblumin.com/sql-vulnerability-assessment-tool-rules-reference-list/"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "az sql server firewall-rule delete --resource-group resource_group_name --server sql_server_name --name rule_name",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Sql/unrestricted-sql-database-access.html",
|
||||
"Terraform": "https://docs.prowler.com/checks/azure/azure-networking-policies/bc_azr_networking_4#terraform"
|
||||
"CLI": "az sql server firewall-rule delete --resource-group <RESOURCE_GROUP> --server <SERVER_NAME> --name <RULE_NAME>",
|
||||
"NativeIaC": "```bicep\n// Update the firewall rule to not allow the entire Internet\nresource sqlServer 'Microsoft.Sql/servers@2021-11-01' existing = {\n name: '<example_resource_name>'\n}\n\nresource restricted 'Microsoft.Sql/servers/firewallRules@2021-11-01' = {\n name: '${sqlServer.name}/<example_resource_name>'\n properties: {\n startIpAddress: '<START_IP>' // Critical: not 0.0.0.0; restricts start IP\n endIpAddress: '<END_IP>' // Critical: not 255.255.255.255; restricts end IP\n }\n}\n```",
|
||||
"Other": "1. In the Azure portal, go to SQL servers and select your server\n2. Open Security > Networking\n3. Under Firewall rules, find any rule with Start IP 0.0.0.0 and End IP 255.255.255.255\n4. Select the rule and click Delete\n5. Click Save",
|
||||
"Terraform": "```hcl\n# Replace any allow-all firewall rule with a restricted range\nresource \"azurerm_mssql_firewall_rule\" \"<example_resource_name>\" {\n name = \"<example_resource_name>\"\n server_id = \"<example_resource_id>\"\n start_ip_address = \"<START_IP>\" # Critical: not 0.0.0.0\n end_ip_address = \"<END_IP>\" # Critical: not 255.255.255.255\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Remove firewall rules allowing all sources and, instead, use more granular rules",
|
||||
"Url": ""
|
||||
"Text": "Remove the all-open rule and enforce **least privilege**.\n- Restrict access to specific IPs/ranges\n- Prefer **private endpoints** or VNet rules to avoid Internet exposure\n- Layer controls (NSGs, Azure Firewall)\n- Avoid broad exceptions like `Allow Azure services` and never use `0.0.0.0/0`",
|
||||
"Url": "https://hub.prowler.com/check/sqlserver_unrestricted_inbound_access"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"internet-exposed"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
|
||||
@@ -1,29 +1,40 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "sqlserver_va_emails_notifications_admins_enabled",
|
||||
"CheckTitle": "Ensure that Vulnerability Assessment (VA) setting 'Also send email notifications to admins and subscription owners' is set for each SQL Server",
|
||||
"CheckTitle": "SQL Server has Vulnerability Assessment enabled and email notifications to subscription admins configured",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sqlserver",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "SQLServer",
|
||||
"Description": "Enable Vulnerability Assessment (VA) setting 'Also send email notifications to admins and subscription owners'.",
|
||||
"Risk": "VA scan reports and alerts will be sent to admins and subscription owners by enabling setting 'Also send email notifications to admins and subscription owners'. This may help in reducing time required for identifying risks and taking corrective measures.",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/azure/sql-database/sql-vulnerability-assessment",
|
||||
"ResourceType": "microsoft.sql/servers",
|
||||
"Description": "**Azure SQL Server** Vulnerability Assessment configuration, specifically whether recurring scans are set to email results to subscription admins/owners via `Also send email notifications to admins and subscription owners`.",
|
||||
"Risk": "Without these notifications, findings may go unnoticed, delaying fixes. Prolonged exposure of misconfigurations and weak permissions threatens data **confidentiality** and **integrity**, can affect **availability**, and slows **incident response** and audit readiness.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Sql/enable-email-alerts-for-administrators-and-subscription-owners.html",
|
||||
"https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-va-setting-also-send-email-notifications-to-admins-and-subscription-owners-is-set-for-an-sql-server/",
|
||||
"https://learn.microsoft.com/en-us/azure/defender-for-cloud/sql-azure-vulnerability-assessment-enable",
|
||||
"https://guides.spectralops.io/docs/d9_azu_mon_25",
|
||||
"https://learn.microsoft.com/en-us/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview",
|
||||
"https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-va-setting-also-send-email-notifications-to-admins-and-subscription-owners-is-set-for-an-sql-server#terraform",
|
||||
"https://docs.microsoft.com/en-us/azure/sql-database/sql-vulnerability-assessment"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-va-setting-also-send-email-notifications-to-admins-and-subscription-owners-is-set-for-an-sql-server#terraform"
|
||||
"CLI": "az rest --method put --url \"https://management.azure.com/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.Sql/servers/<SERVER_NAME>/vulnerabilityAssessments/default?api-version=2021-11-01\" --body '{\"properties\":{\"storageContainerPath\":\"https://<STORAGE_ACCOUNT>.blob.core.windows.net/<CONTAINER>\",\"storageAccountAccessKey\":\"<STORAGE_KEY>\",\"recurringScans\":{\"isEnabled\":true,\"emailSubscriptionAdmins\":true}}}'",
|
||||
"NativeIaC": "```bicep\n// Enable VA at server level with classic storage and email to subscription admins\nresource sqlServer 'Microsoft.Sql/servers@2021-11-01' existing = {\n name: '<example_resource_name>'\n}\n\nresource va 'Microsoft.Sql/servers/vulnerabilityAssessments@2021-11-01' = {\n name: 'default'\n parent: sqlServer\n properties: {\n storageContainerPath: 'https://<example_resource_name>.blob.core.windows.net/<example_resource_name>' // Critical: required so the check detects VA configured\n storageAccountAccessKey: '<example_resource_id>'\n recurringScans: {\n isEnabled: true\n emailSubscriptionAdmins: true // Critical: sends scan reports to subscription admins to PASS the check\n }\n }\n}\n```",
|
||||
"Other": "1. In Azure Portal, go to SQL servers and open <SERVER_NAME>\n2. Under Security, select Vulnerability assessment (classic)\n3. Select a Storage account container and click Save (ensures a storage container path)\n4. Enable Recurring scans\n5. Enable Send scan reports to subscription admins\n6. Click Save",
|
||||
"Terraform": "```hcl\n# Enable VA at server level and email subscription admins\nresource \"azurerm_mssql_server_security_alert_policy\" \"<example_resource_name>\" {\n server_id = \"<example_resource_id>\"\n state = \"Enabled\"\n}\n\nresource \"azurerm_mssql_server_vulnerability_assessment\" \"<example_resource_name>\" {\n server_security_alert_policy_id = azurerm_mssql_server_security_alert_policy.<example_resource_name>.id\n storage_container_path = \"https://<example_resource_name>.blob.core.windows.net/<example_resource_name>\" # Critical: required so the check detects VA configured\n storage_account_access_key = \"<example_resource_id>\"\n\n recurring_scans {\n enabled = true\n email_subscription_admins = true # Critical: sends scan reports to subscription admins to PASS the check\n }\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "1. Go to SQL servers 2. Select a server instance 3. Click on Security Center 4. Select Configure next to Enabled at subscription-level 5. In Section Vulnerability Assessment Settings, configure Storage Accounts if not already 6. Check/enable 'Also send email notifications to admins and subscription owners' 7. Click Save",
|
||||
"Url": "https://learn.microsoft.com/en-us/azure/defender-for-cloud/sql-azure-vulnerability-assessment-enable"
|
||||
"Text": "Enable VA email alerts for admins/owners (`Also send...`) so findings reach accountable staff promptly.\n\n- Route to a monitored security group and SIEM\n- Review recipients regularly; remove stale accounts\n- Apply **least privilege** and maintain recurring scans for **defense in depth**",
|
||||
"Url": "https://hub.prowler.com/check/sqlserver_va_emails_notifications_admins_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"vulnerabilities"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "Enabling the Microsoft Defender for SQL features will incur additional costs for each SQL server."
|
||||
|
||||
@@ -1,29 +1,42 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "sqlserver_va_periodic_recurring_scans_enabled",
|
||||
"CheckTitle": "Ensure that Vulnerability Assessment (VA) setting 'Periodic recurring scans' is set to 'on' for each SQL server",
|
||||
"CheckTitle": "SQL Server has Vulnerability Assessment periodic recurring scans enabled",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sqlserver",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "SQLServer",
|
||||
"Description": "Enable Vulnerability Assessment (VA) Periodic recurring scans for critical SQL servers and corresponding SQL databases.",
|
||||
"Risk": "VA setting 'Periodic recurring scans' schedules periodic (weekly) vulnerability scanning for the SQL server and corresponding Databases. Periodic and regular vulnerability scanning provides risk visibility based on updated known vulnerability signatures and best practices.",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/azure/sql-database/sql-vulnerability-assessment",
|
||||
"ResourceType": "microsoft.sql/servers",
|
||||
"Description": "**Azure SQL servers** are evaluated for **Vulnerability Assessment** configuration and whether **periodic recurring scans** are scheduled (e.g., weekly) for the server and its databases.\n\nServers with Vulnerability Assessment missing or scans not scheduled are identified.",
|
||||
"Risk": "Without scheduled scans, new misconfigurations and vulnerable settings can persist unnoticed, weakening **confidentiality** and **integrity**. Attackers can exploit stale permissions, unsafe firewall rules, or unpatched features to read or alter data and pivot to other resources.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-va-setting-periodic-recurring-scans-is-enabled-on-a-sql-server#terraform",
|
||||
"https://docs.microsoft.com/en-us/azure/sql-database/sql-vulnerability-assessment",
|
||||
"https://www.pulumi.com/registry/packages/azure/api-docs/mssql/servervulnerabilityassessment/",
|
||||
"https://docs.datadoghq.com/security/default_rules/def-000-s27/",
|
||||
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Sql/periodic-vulnerability-scans.html",
|
||||
"https://learn.microsoft.com/en-us/azure/defender-for-cloud/sql-azure-vulnerability-assessment-enable",
|
||||
"https://faun.pub/enable-azure-sql-server-vulnerability-assessment-using-terraform-abdffc6307a6",
|
||||
"https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-va-setting-periodic-recurring-scans-is-enabled-on-a-sql-server/",
|
||||
"https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/periodic-vulnerability-scans.html#"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/periodic-vulnerability-scans.html#",
|
||||
"Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-va-setting-periodic-recurring-scans-is-enabled-on-a-sql-server#terraform"
|
||||
"CLI": "az rest --method put --url https://management.azure.com/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.Sql/servers/<SERVER_NAME>/vulnerabilityAssessments/Default?api-version=2023-08-01-preview --body '{\"properties\":{\"storageContainerPath\":\"https://<STORAGE_ACCOUNT>.blob.core.windows.net/<CONTAINER>/\",\"storageAccountAccessKey\":\"<ACCESS_KEY>\",\"recurringScans\":{\"isEnabled\":true}}}'",
|
||||
"NativeIaC": "```bicep\n// Enable classic VA with recurring scans on an existing SQL Server\nresource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' existing = {\n name: '<example_resource_name>'\n}\n\nresource va 'Microsoft.Sql/servers/vulnerabilityAssessments@2023-08-01-preview' = {\n name: 'Default'\n parent: sqlServer\n properties: {\n storageContainerPath: 'https://<example_storage_account>.blob.core.windows.net/<example_container>/' // CRITICAL: Required so VA is considered configured\n storageAccountAccessKey: '<example_access_key>'\n recurringScans: {\n isEnabled: true // CRITICAL: Enables periodic recurring scans\n }\n }\n}\n```",
|
||||
"Other": "1. In Azure Portal, go to SQL servers > select <your server>\n2. Under Security, open Vulnerability assessment (classic configuration)\n3. Set Storage container to an existing blob container and Save\n4. Turn Recurring scans to On\n5. Click Save to apply",
|
||||
"Terraform": "```hcl\n# Server VA with periodic recurring scans enabled\nresource \"azurerm_mssql_server_vulnerability_assessment\" \"<example_resource_name>\" {\n server_security_alert_policy_id = \"<example_resource_id>\"\n storage_container_path = \"https://<example_storage_account>.blob.core.windows.net/<example_container>/\" # Required so VA is configured\n storage_account_access_key = \"<example_access_key>\"\n\n recurring_scans {\n enabled = true # CRITICAL: Enables periodic recurring scans\n }\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "1. Go to SQL servers 2. For each server instance 3. Click on Security Center 4. In Section Vulnerability Assessment Settings, set Storage Account if not already 5. Toggle 'Periodic recurring scans' to ON. 6. Click Save",
|
||||
"Url": "https://learn.microsoft.com/en-us/azure/defender-for-cloud/sql-azure-vulnerability-assessment-enable"
|
||||
"Text": "Enable **recurring Vulnerability Assessment scans** at server scope and ensure results are retained securely (*express configuration or secured storage*). Apply **least privilege**, maintain baselines, and promptly remediate findings. Automate alerting and periodic reviews as part of **defense in depth** and change management.",
|
||||
"Url": "https://hub.prowler.com/check/sqlserver_va_periodic_recurring_scans_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"vulnerabilities"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "Enabling the Azure Defender for SQL feature will incur additional costs for each SQL server."
|
||||
|
||||
@@ -1,29 +1,36 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "sqlserver_va_scan_reports_configured",
|
||||
"CheckTitle": "Ensure that Vulnerability Assessment (VA) setting 'Send scan reports to' is configured for a SQL server",
|
||||
"CheckTitle": "SQL server has Vulnerability Assessment enabled and scan report recipients configured",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sqlserver",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "SQLServer",
|
||||
"Description": "Configure 'Send scan reports to' with email addresses of concerned data owners/stakeholders for a critical SQL servers.",
|
||||
"Risk": "Vulnerability Assessment (VA) scan reports and alerts will be sent to email addresses configured at 'Send scan reports to'. This may help in reducing time required for identifying risks and taking corrective measures",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/azure/sql-database/sql-vulnerability-assessment",
|
||||
"ResourceType": "microsoft.sql/servers",
|
||||
"Description": "**Azure SQL Server** vulnerability assessment uses **recurring scans** and emails results to designated recipients. This evaluates that VA is enabled and that `Send scan reports to` (or subscription admin notifications) is configured so scan reports are delivered.",
|
||||
"Risk": "If VA reports aren't sent to responsible owners, findings can be missed, delaying fixes. Attackers may exploit misconfigurations, excessive permissions, or outdated settings, leading to data exposure (C), unauthorized changes (I), and potential service disruption (A).",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://learn.microsoft.com/en-us/azure/defender-for-cloud/sql-azure-vulnerability-assessment-enable",
|
||||
"https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-va-setting-send-scan-reports-to-is-configured-for-a-sql-server#terraform",
|
||||
"https://docs.microsoft.com/en-us/azure/sql-database/sql-vulnerability-assessment"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-va-setting-send-scan-reports-to-is-configured-for-a-sql-server#terraform"
|
||||
"NativeIaC": "```bicep\n// Configure VA (classic) on a SQL Server and set recipients\nresource sqlServer 'Microsoft.Sql/servers@2021-11-01' existing = {\n name: '<example_resource_name>'\n}\n\nresource va 'Microsoft.Sql/servers/vulnerabilityAssessments@2021-11-01' = {\n name: 'Default'\n parent: sqlServer\n properties: {\n storageContainerPath: 'https://<example_storage_account>.blob.core.windows.net/<example_container>' // CRITICAL: enables VA classic by setting storage container\n storageAccountAccessKey: '<example_storage_key>'\n recurringScans: {\n isEnabled: true\n emailSubscriptionAdmins: true // CRITICAL: configures scan report recipients (subscription admins)\n }\n }\n}\n```",
|
||||
"Other": "1. In Azure Portal, go to SQL servers and select <your server>\n2. Under Security, open Vulnerability assessment\n3. Select a Storage account and Container, then Save\n4. In Recurring scans, turn On and enable Send to subscription admins (or add at least one email)\n5. Save",
|
||||
"Terraform": "```hcl\n# Enable VA (classic) on a SQL Server and configure recipients\nresource \"azurerm_mssql_server_vulnerability_assessment\" \"<example_resource_name>\" {\n server_id = \"<example_resource_id>\"\n storage_container_path = \"https://<example_storage_account>.blob.core.windows.net/<example_container>\" # CRITICAL: enables VA classic by setting storage container\n storage_account_access_key = \"<example_storage_key>\"\n\n recurring_scans {\n enabled = true\n email_subscription_admins = true # CRITICAL: configures scan report recipients (subscription admins)\n }\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "1. Go to SQL servers 2. Select a server instance 3. Select Microsoft Defender for Cloud 4. Select Configure next to Enablement status 5. Set Microsoft Defender for SQL to On 6. Under Vulnerability Assessment Settings, select a Storage Account 7. Set Periodic recurring scans to On 8. Under Send scan reports to, provide email addresses for data owners and stakeholders 9. Click Save",
|
||||
"Url": "https://learn.microsoft.com/en-us/azure/defender-for-cloud/sql-azure-vulnerability-assessment-enable"
|
||||
"Text": "Enable **Vulnerability Assessment**, keep **recurring scans** active, and configure `Send scan reports to` with accountable security owners or subscription admins. Integrate notifications with central alerting, apply **least privilege** to recipients, and enforce SLAs to triage and remediate findings promptly.",
|
||||
"Url": "https://hub.prowler.com/check/sqlserver_va_scan_reports_configured"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"vulnerabilities"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "Enabling the Microsoft Defender for SQL features will incur additional costs for each SQL server."
|
||||
|
||||
@@ -1,29 +1,37 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "sqlserver_vulnerability_assessment_enabled",
|
||||
"CheckTitle": "Ensure that Vulnerability Assessment (VA) is enabled on a SQL server by setting a Storage Account",
|
||||
"CheckTitle": "SQL server has vulnerability assessment enabled with storage container configured",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sqlserver",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "SQLServer",
|
||||
"Description": "Enable Vulnerability Assessment (VA) service scans for critical SQL servers and corresponding SQL databases.",
|
||||
"Risk": "The Vulnerability Assessment service scans databases for known security vulnerabilities and highlights deviations from best practices, such as misconfigurations, excessive permissions, and unprotected sensitive data. Results of the scan include actionable steps to resolve each issue and provide customized remediation scripts where applicable. Additionally, an assessment report can be customized by setting an acceptable baseline for permission configurations, feature configurations, and database settings.",
|
||||
"RelatedUrl": "https://docs.microsoft.com/en-us/azure/sql-database/sql-vulnerability-assessment",
|
||||
"ResourceType": "microsoft.sql/servers",
|
||||
"Description": "**Azure SQL Server** has **Vulnerability Assessment** configured with a defined location to persist assessment reports and scan results",
|
||||
"Risk": "Without **Vulnerability Assessment**, misconfigurations and excessive permissions can go unnoticed.\n\nAdversaries may exploit weak server or database settings to escalate privileges, exfiltrate data, or alter records, degrading confidentiality and integrity.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/vulnerability-assessment-sql-servers.html#",
|
||||
"https://learn.microsoft.com/en-us/azure/defender-for-cloud/sql-azure-vulnerability-assessment-enable",
|
||||
"https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-vulnerability-assessment-va-is-enabled-on-a-sql-server-by-setting-a-storage-account",
|
||||
"https://docs.microsoft.com/en-us/azure/sql-database/sql-vulnerability-assessment"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "Update-AzSqlServerVulnerabilityAssessmentSetting -ResourceGroupName resource_group_name -ServerName Server_Name -StorageAccountName Storage_Name_from_same_subscription_and_same_Location -ScanResultsContainerName vulnerability-assessment -RecurringScansInterval Weekly -EmailSubscriptionAdmins $true -NotificationEmail @('mail1@mail.com' , 'mail2@mail.com')",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/azure/Sql/vulnerability-assessment-sql-servers.html#",
|
||||
"Terraform": "https://docs.prowler.com/checks/azure/azure-general-policies/ensure-that-vulnerability-assessment-va-is-enabled-on-a-sql-server-by-setting-a-storage-account"
|
||||
"CLI": "Update-AzSqlServerVulnerabilityAssessmentSetting -ResourceGroupName <RESOURCE_GROUP> -ServerName <SERVER_NAME> -StorageAccountName <STORAGE_ACCOUNT_NAME> -ScanResultsContainerName <CONTAINER_NAME>",
|
||||
"NativeIaC": "```bicep\n// Configure VA (classic) at the SQL Server level\nresource sqlServerVA 'Microsoft.Sql/servers/vulnerabilityAssessments@2021-11-01' = {\n name: '<example_resource_name>/default'\n properties: {\n storageContainerPath: 'https://<example_resource_name>.blob.core.windows.net/<example_resource_name>' // CRITICAL: sets the storage container path to enable VA\n }\n}\n```",
|
||||
"Other": "1. In the Azure portal, go to SQL servers and open <SERVER_NAME>\n2. Under Security, select Microsoft Defender for SQL (or Defender for Cloud > Microsoft Defender for SQL)\n3. In Vulnerability assessment settings, click Configure\n4. Select the Storage account and the target Container\n5. Save\n\nVerification: Open the server's Vulnerability assessment blade and confirm a storage container is shown.",
|
||||
"Terraform": "```hcl\n# Enable server security alert policy (required by VA)\nresource \"azurerm_mssql_server_security_alert_policy\" \"<example_resource_name>\" {\n resource_group_name = \"<example_resource_name>\"\n server_name = \"<example_resource_name>\"\n state = \"Enabled\"\n}\n\n# Configure VA (classic) with storage container\nresource \"azurerm_mssql_server_vulnerability_assessment\" \"<example_resource_name>\" {\n server_security_alert_policy_id = azurerm_mssql_server_security_alert_policy.<example_resource_name>.id\n storage_container_path = \"https://<example_resource_name>.blob.core.windows.net/<example_resource_name>\" # CRITICAL: sets storage container path so the check passes\n storage_account_access_key = \"<example_resource_name>\"\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "1. Go to SQL servers 2. Select a server instance 3. Click on Security Center 4. Select Configure next to Enabled at subscription-level 5. In Section Vulnerability Assessment Settings, Click Select Storage account 6. Choose Storage Account (Existing or Create New). Click Ok 7. Click Save",
|
||||
"Url": "https://learn.microsoft.com/en-us/azure/defender-for-cloud/sql-azure-vulnerability-assessment-enable"
|
||||
"Text": "Enable and standardize **Vulnerability Assessment** across SQL servers and databases, retaining scan results in a secure repository. Run scans routinely, review findings, set `baselines`, and remediate promptly. Apply **least privilege** to report access and integrate results into change management for **defense in depth**.",
|
||||
"Url": "https://hub.prowler.com/check/sqlserver_vulnerability_assessment_enabled"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"Categories": [
|
||||
"vulnerabilities"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "Enabling the Microsoft Defender for SQL features will incur additional costs for each SQL server."
|
||||
|
||||
@@ -90,7 +90,7 @@ maintainers = [{name = "Prowler Engineering", email = "engineering@prowler.com"}
|
||||
name = "prowler"
|
||||
readme = "README.md"
|
||||
requires-python = ">3.9.1,<3.13"
|
||||
version = "5.16.0"
|
||||
version = "5.17.0"
|
||||
|
||||
[project.scripts]
|
||||
prowler = "prowler.__main__:prowler"
|
||||
|
||||
Reference in New Issue
Block a user