ark-pentest-issue-resolver について
特定の CVE が示されていない場合に、Ark プラットフォームの一般的なペネトレーションテスト指摘を調査・対処するセキュリティスキルです。代表的な脆弱性ごとに検出パターン、Ark 固有の確認箇所、緩和例を示します。
主な機能
- 01一般的なセキュリティ問題の検出パターン
- 02OWASP 関連の指摘に対する緩和例
- 03Ark のコードと設定の確認指針
- 04アクセス制御と認証の問題への対応
- 05ログ、データ露出、リクエストリスクの指針
活用シーン
- 01CVE のないペネトレーションテスト指摘の初期調査
- 02Ark サービスのインジェクションやアクセス制御の確認
- 03セキュリティ設定と機密データ処理の点検
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mckinsey/ agents-at-scale-ark --skill ark-pentest-issue-resolverインストール後、Claude Code で/ark-pentest-issue-resolverを入力して読み込まれたか確認します。
詳細
Ark のペネトレーションテスト問題の解決
Ark プラットフォームで見つかった、一般的なペネトレーションテストの問題に対する検出パターン、緩和策、修正方法を提供します。
このスキルを使用するタイミング
次の場合にこのスキルを使用します:
- ユーザーが特定の CVE を挙げずに、ペネトレーションテストの指摘事項を報告した場合
- セキュリティ監査で OWASP Top 10 の脆弱性が見つかった場合
- 「XSS」「SQL インジェクション」「CSRF」などの問題についてユーザーが言及した場合
- 一般的なセキュリティ設定の誤りを特定して修正する必要がある場合
注:特定の CVE が挙げられていない場合、このスキルは ark-security-patcher エージェントによって使用されます。標準的なペネトレーションテストの指摘事項を特定し、解決するのに役立ちます。
よくあるペネトレーションテストの問題
1. SQL インジェクション
説明:攻撃者がユーザー入力を通じて、悪意のある SQL クエリを注入できる状態です。
検出パターン:
# VULNERABLE: Direct string concatenation
query = f"SELECT * FROM users WHERE username = '{username}'"
# VULNERABLE: String formatting
query = "SELECT * FROM users WHERE id = %s" % user_id
緩和策:
# SECURE: Use parameterized queries
cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
# SECURE: Use ORM with parameter binding
User.objects.filter(username=username)
# SECURE: Use sqlalchemy with bound parameters
session.query(User).filter(User.username == username)
Ark における確認箇所:
- Python サービスを確認します:
services/ark-api/、executor サービス - 次の項目を検索します:
cursor.execute、db.query、SQL 文字列の連結 - すべてのデータベースクエリで、パラメーター化されたステートメントが使用されていることを確認します
2. クロスサイトスクリプティング(XSS)
説明:攻撃者が、他のユーザーが閲覧するウェブページに悪意のある JavaScript を注入できる状態です。
種類:
- 反射型 XSS:URL/リクエスト内の悪意のあるスクリプトが、レスポンスに反映されます
- 格納型 XSS:悪意のあるスクリプトがデータベースに保存され、ユーザーに表示されます
- DOM ベース XSS:クライアント側の JavaScript に脆弱性があります
検出パターン:
// VULNERABLE: Direct innerHTML manipulation
element.innerHTML = userInput;
// VULNERABLE: Unescaped template rendering
return `<div>${userInput}</div>`;
// VULNERABLE: dangerouslySetInnerHTML in React
<div dangerouslySetInnerHTML={{__html: userInput}} />
緩和策:
// SECURE: Use textContent
element.textContent = userInput;
// SECURE: Use React/Vue built-in escaping
return <div>{userInput}</div>
// SECURE: Sanitize HTML if HTML input is required
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(userInput);
// SECURE: Set Content-Security-Policy header
Content-Security-Policy: default-src 'self'; script-src 'self'
Ark における確認箇所:
- 次の項目を確認します:
ark-dashboard/、docs/(Next.js アプリケーション) - 次の項目を検索します:
dangerouslySetInnerHTML、innerHTML、エスケープされていないテンプレート - Next.js の設定で、適切な Content-Security-Policy ヘッダーが設定されていることを確認します
- React コンポーネント内のすべてのユーザー入力がエスケープされていることを確認します
3. クロスサイトリクエストフォージェリ(CSRF)
説明:攻撃者がユーザーをだまして、認証済みアプリケーション上で意図しない操作を実行させる状態です。
検出パターン:
// VULNERABLE: No CSRF token validation
http.HandleFunc("/api/delete", func(w http.ResponseWriter, r *http.Request) {
// Directly processes DELETE without token
deleteUser(r.FormValue("id"))
})
緩和策:
// SECURE: Use CSRF middleware
import "github.com/gorilla/csrf"
csrfMiddleware := csrf.Protect(
[]byte("32-byte-long-auth-key"),
csrf.Secure(true),
)
http.ListenAndServe(":8000", csrfMiddleware(router))
// SECURE: Verify CSRF token
token := r.Header.Get("X-CSRF-Token")
if !csrf.Validate(token, session) {
http.Error(w, "Invalid CSRF token", http.StatusForbidden)
return
}
// SECURE: Use SameSite cookie attribute
http.SetCookie(w, &http.Cookie{
Name: "session",
Value: sessionID,
SameSite: http.SameSiteStrictMode,
Secure: true,
HttpOnly: true,
})
Ark における確認箇所:
- Go operator API エンドポイント、Python API サービスを確認します
- CSRF 保護のない、状態を変更するエンドポイント(POST、PUT、DELETE)を検索します
- Cookie で
SameSite=StrictまたはSameSite=Laxが使用されていることを確認します - 状態を変更する API ルートに CSRF ミドルウェアを追加します
4. 安全でない直接オブジェクト参照(IDOR)
説明:アプリケーションが、適切な認可チェックなしに内部実装オブジェクト(ID)を公開している状態です。
検出パターン:
# VULNERABLE: No authorization check
@app.route('/api/user/<user_id>')
def get_user(user_id):
return User.query.get(user_id) # Any authenticated user can access any user
# VULNERABLE: Predictable IDs
@app.route('/api/document/<int:doc_id>')
def get_document(doc_id):
return Document.query.get(doc_id) # Sequential IDs are guessable
緩和策:
# SECURE: Check authorization
@app.route('/api/user/<user_id>')
def get_user(user_id):
user = User.query.get(user_id)
if user.id != current_user.id and not current_user.is_admin:
abort(403, "Unauthorized")
return user
# SECURE: Use UUIDs instead of sequential IDs
import uuid
user_id = uuid.uuid4()
# SECURE: Implement resource ownership check
def check_ownership(resource_id, user_id):
resource = Resource.query.get(resource_id)
if resource.owner_id != user_id:
raise PermissionDenied()
Ark における確認箇所:
- Python サービスおよび Go operator のすべての REST API エンドポイントを確認します
- URL パス内の ID の直接参照、認可チェックの欠如を検索します
- すべてのリソースアクセスで、ユーザー権限がチェックされていることを確認します
- リソース識別子に UUID を使用することを検討します
5. セキュリティ設定の誤り
説明:安全でないデフォルト設定、不完全なセットアップ、公開されたクラウドストレージ、誤って設定された HTTP ヘッダーなどです。
よくある問題:
セキュリティヘッダーの欠如
検出:
curl -I https://ark-dashboard.example.com | grep -E "X-Frame-Options|X-Content-Type-Options|Strict-Transport-Security"
緩和策:
// Add security headers middleware
func securityHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Frame-Options", "DENY")
w.Header().Set("X-Content-Type-Options", "nosniff")
w.Header().Set("X-XSS-Protection", "1; mode=block")
w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
w.Header().Set("Content-Security-Policy", "default-src 'self'")
w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
next.ServeHTTP(w, r)
})
}
// Next.js configuration (next.config.js)
module.exports = {
async headers() {
return [
{
source: '/:path*',
headers: [
{ key: 'X-Frame-Options', value: 'DENY' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'X-XSS-Protection', value: '1; mode=block' },
{ key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' },
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
],
},
]
},
}
本番環境でのデバッグモードの有効化
検出:
grep -r "DEBUG.*=.*true" .
grep -r "NODE_ENV.*development" .
緩和策:
- 本番環境で
DEBUG=falseを設定します NODE_ENV=productionを設定します- エラーレスポンスからスタックトレースを削除します
- 本番環境で詳細なロギングを無効にします
6. 機密データの漏えい
説明:アプリケーションが、ログ、エラーメッセージ、安全でない通信を通じて機密データを公開している状態です。
検出パターン:
# VULNERABLE: Logging sensitive data
logger.info(f"User {username} logged in with password {password}")
# VULNERABLE: Exposing secrets in error messages
raise Exception(f"Database connection failed: {db_password}")
# VULNERABLE: Sensitive data in URLs
redirect(f"/reset-password?token={reset_token}")
緩和策:
# SECURE: Never log sensitive data
logger.info(f"User {username} logged in successfully")
# SECURE: Generic error messages
raise Exception("Database connection failed")
logger.error("DB error", exc_info=True) # Full details only in logs
# SECURE: Use POST for sensitive data
# POST /reset-password with token in body
# SECURE: Mask sensitive data
def mask_credit_card(card_number):
return f"****-****-****-{card_number[-4:]}"
環境変数:
# VULNERABLE: Hardcoded secrets
API_KEY = "sk_live_abc123xyz"
# SECURE: Use environment variables
API_KEY = os.getenv("API_KEY")
# SECURE: Use Kubernetes secrets
apiVersion: v1
kind: Secret
metadata:
name: ark-secrets
type: Opaque
data:
api-key: <base64-encoded-value>
Ark における確認箇所:
- すべてのログ出力文とエラーハンドラーを確認します
- ハードコードされたシークレット、API キー、パスワードを検索します
- すべての通信で TLS/HTTPS が使用されていることを確認します
- 機密性の高い設定には Kubernetes Secrets を使用します
7. 認証の不備
説明:認証情報の詰め込み攻撃、ブルートフォース攻撃、セッションハイジャックを許す、脆弱な認証メカニズムです。
よくある問題:
脆弱なパスワード要件
緩和策:
import re
def validate_password(password):
"""Enforce strong password policy"""
if len(password) < 12:
return False, "Password must be at least 12 characters"
if not re.search(r"[A-Z]", password):
return False, "Password must contain uppercase letter"
if not re.search(r"[a-z]", password):
return False, "Password must contain lowercase letter"
if not re.search(r"[0-9]", password):
return False, "Password must contain number"
if not re.search(r"[!@#$%^&*]", password):
return False, "Password must contain special character"
return True, "Password is valid"
ログイン時のレート制限の欠如
緩和策:
import "golang.org/x/time/rate"
// Rate limiter: 5 requests per minute per IP
var limiter = rate.NewLimiter(rate.Every(time.Minute/5), 5)
func loginHandler(w http.ResponseWriter, r *http.Request) {
if !limiter.Allow() {
http.Error(w, "Too many requests", http.StatusTooManyRequests)
return
}
// Process login
}
安全でないセッション管理
緩和策:
// SECURE: Generate cryptographically secure session IDs
import "crypto/rand"
func generateSessionID() (string, error) {
b := make([]byte, 32)
if _, err := rand.Read(b); err != nil {
return "", err
}
return base64.URLEncoding.EncodeToString(b), nil
}
// SECURE: Set secure cookie attributes
http.SetCookie(w, &http.Cookie{
Name: "session_id",
Value: sessionID,
Path: "/",
MaxAge: 3600,
HttpOnly: true, // Prevent JavaScript access
Secure: true, // Only send over HTTPS
SameSite: http.SameSiteStrictMode,
})
8. アクセス制御の不備
説明:ユーザーが意図された権限の範囲外の操作を実行できます。
検出パターン:
# VULNERABLE: No permission check
@app.route('/api/admin/users', methods=['DELETE'])
def delete_user():
user_id = request.json['user_id']
User.query.filter_by(id=user_id).delete()
緩和策:
# SECURE: Role-based access control (RBAC)
from functools import wraps
def require_role(*roles):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.is_authenticated:
abort(401)
if current_user.role not in roles:
abort(403, "Insufficient permissions")
return f(*args, **kwargs)
return decorated_function
return decorator
@app.route('/api/admin/users', methods=['DELETE'])
@require_role('admin', 'superuser')
def delete_user():
user_id = request.json['user_id']
User.query.filter_by(id=user_id).delete()
Kubernetes RBAC(Ark オペレーター向け):
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: ark-operator
rules:
- apiGroups: ["ark.example.com"]
resources: ["models", "prompts"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
Ark のコンテキスト:
- 確認:すべての API エンドポイントで認可チェックが行われていること
- 検証:Kubernetes RBAC ルールが適切な範囲に設定されていること
- 実装:最小権限の原則
- テスト:水平方向の権限昇格(ユーザー A がユーザー B のリソースにアクセスする)
9. ログ記録とモニタリングの不備
説明:ログ記録とモニタリングが不足していると、攻撃が検知されないままになります。
緩和策:
import logging
import structlog
# Configure structured logging
logger = structlog.get_logger()
# Log security events
def log_security_event(event_type, user_id, details):
logger.info(
"security_event",
event_type=event_type,
user_id=user_id,
details=details,
timestamp=datetime.utcnow().isoformat()
)
# Examples of what to log
log_security_event("login_success", user.id, {"ip": request.remote_addr})
log_security_event("login_failure", username, {"ip": request.remote_addr})
log_security_event("password_change", user.id, {})
log_security_event("permission_denied", user.id, {"resource": resource_id})
log_security_event("admin_action", user.id, {"action": "delete_user", "target": target_id})
記録するイベント:
- 認証の成功と失敗
- 認可の失敗
- 入力検証の失敗
- 管理操作
- リソースへのアクセス(特に機密性の高いリソース)
- データの変更
- セキュリティ設定の変更
10. サーバーサイドリクエストフォージェリ(SSRF)
説明:攻撃者がサーバーをだまして、内部リソースにリクエストを送信させます。
検出パターン:
# VULNERABLE: Direct use of user-provided URL
import requests
url = request.args.get('url')
response = requests.get(url) # Can access internal resources!
緩和策:
# SECURE: Validate and whitelist URLs
import ipaddress
from urllib.parse import urlparse
ALLOWED_DOMAINS = ['api.example.com', 'cdn.example.com']
def is_safe_url(url):
try:
parsed = urlparse(url)
# Only allow HTTP/HTTPS
if parsed.scheme not in ['http', 'https']:
return False
# Check against whitelist
if parsed.hostname not in ALLOWED_DOMAINS:
return False
# Resolve hostname and check it's not internal
ip = socket.gethostbyname(parsed.hostname)
if ipaddress.ip_address(ip).is_private:
return False
return True
except Exception:
return False
# Use the validator
url = request.args.get('url')
if not is_safe_url(url):
abort(400, "Invalid URL")
response = requests.get(url)
Ark のコンテキスト:
- 確認:ユーザー入力から URL を取得する API がないか
- 検索対象:ユーザーが指定した URL を使用する
requests.get、http.Get、fetch - 実装:外部 API 呼び出しに URL ホワイトリストを適用
11. XML 外部エンティティ(XXE)
説明:攻撃者が XML に外部エンティティを含め、ファイルを読み取ったり、DoS を引き起こしたりできます。
検出パターン:
# VULNERABLE: Unsafe XML parsing
import xml.etree.ElementTree as ET
tree = ET.parse(xml_file) # Vulnerable to XXE
緩和策:
# SECURE: Disable external entity processing
import defusedxml.ElementTree as ET
tree = ET.parse(xml_file) # Safe from XXE
# SECURE: Configure parser to disable DTDs
from lxml import etree
parser = etree.XMLParser(resolve_entities=False, no_network=True, dtd_validation=False)
tree = etree.parse(xml_file, parser)
12. 安全でないデシリアライゼーション
説明:信頼できないデータがデシリアライズされ、リモートコード実行につながる可能性があります。
検出パターン:
# VULNERABLE: Pickle deserialization of untrusted data
import pickle
data = pickle.loads(untrusted_data) # Can execute arbitrary code!
# VULNERABLE: YAML unsafe loading
import yaml
data = yaml.load(untrusted_yaml) # Can execute Python code
緩和策:
# SECURE: Use JSON instead of pickle
import json
data = json.loads(untrusted_data)
# SECURE: Use safe YAML loading
import yaml
data = yaml.safe_load(untrusted_yaml)
# SECURE: If pickle is necessary, use HMAC verification
import hmac
import hashlib
def serialize_with_hmac(obj, secret_key):
serialized = pickle.dumps(obj)
signature = hmac.new(secret_key, serialized, hashlib.sha256).digest()
return signature + serialized
def deserialize_with_hmac(data, secret_key):
signature = data[:32]
serialized = data[32:]
expected_signature = hmac.new(secret_key, serialized, hashlib.sha256).digest()
if not hmac.compare_digest(signature, expected_signature):
raise ValueError("Invalid signature")
return pickle.loads(serialized)
13. パストラバーサル
説明:攻撃者が ../ の並びを使用して、意図されたディレクトリの外にあるファイルにアクセスします。
検出パターン:
# VULNERABLE: Direct file path from user input
filename = request.args.get('file')
with open(f'/var/www/uploads/{filename}', 'r') as f: # Can access ../../../../etc/passwd
content = f.read()
緩和策:
# SECURE: Validate and sanitize file paths
import os
from pathlib import Path
UPLOAD_DIR = '/var/www/uploads'
def safe_file_path(filename):
# Remove any directory components
filename = os.path.basename(filename)
# Build full path
full_path = os.path.join(UPLOAD_DIR, filename)
# Resolve to absolute path and verify it's within UPLOAD_DIR
full_path = os.path.abspath(full_path)
if not full_path.startswith(os.path.abspath(UPLOAD_DIR)):
raise ValueError("Invalid file path")
return full_path
# Use the validator
filename = request.args.get('file')
safe_path = safe_file_path(filename)
with open(safe_path, 'r') as f:
content = f.read()
14. コマンドインジェクション
説明:攻撃者が任意のシステムコマンドを実行できます。
検出パターン:
# VULNERABLE: Direct command execution with user input
import os
filename = request.args.get('file')
os.system(f'ls -l {filename}') # Can inject: file.txt; rm -rf /
# VULNERABLE: Shell=True with user input
import subprocess
subprocess.call(f'ping {host}', shell=True)
緩和策:
# SECURE: Use subprocess with list of arguments (no shell)
import subprocess
filename = request.args.get('file')
subprocess.run(['ls', '-l', filename], check=True, capture_output=True)
# SECURE: Validate and sanitize input
import shlex
def safe_command(user_input):
# Whitelist allowed characters
if not re.match(r'^[a-zA-Z0-9._-]+$', user_input):
raise ValueError("Invalid input")
return user_input
# SECURE: Use libraries instead of shell commands
# Instead of: os.system('tar -czf archive.tar.gz files/')
import tarfile
with tarfile.open('archive.tar.gz', 'w:gz') as tar:
tar.add('files/')
Ark のコンテキスト:
- 確認:シェルコマンドを実行するコード(特にエグゼキューター内)がないか
- 検索対象:
os.system、subprocess.call、shell=True - 検証:すべての外部コマンドでシェル文字列ではなく引数リストを使用していること
15. レート制限の欠如
説明:ブルートフォース、DoS、リソース枯渇攻撃を防ぐ対策がありません。
緩和策:
# Python with Flask-Limiter
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
limiter = Limiter(
app,
key_func=get_remote_address,
default_limits=["200 per day", "50 per hour"]
)
@app.route("/api/login", methods=["POST"])
@limiter.limit("5 per minute")
def login():
# Login logic
pass
// Go with rate limiting middleware
import "golang.org/x/time/rate"
func rateLimitMiddleware(next http.Handler) http.Handler {
limiter := rate.NewLimiter(rate.Every(time.Second), 10) // 10 req/sec
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !limiter.Allow() {
http.Error(w, "Rate limit exceeded", http.StatusTooManyRequests)
return
}
next.ServeHTTP(w, r)
})
}
Kubernetes ネットワークポリシー:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: rate-limit-policy
spec:
podSelector:
matchLabels:
app: ark-api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: ingress-controller
ワークフロー:ペネトレーションテストの問題を解決する
ステップ 1:問題のカテゴリを特定する
報告された問題を上記のいずれかのカテゴリに対応付けます。
- SQL インジェクション → データベースクエリ
- XSS → ユーザー入力の表示
- CSRF → 状態を変更する API エンドポイント
- IDOR → 認可なしでのリソースアクセス
- セキュリティ設定の不備 → ヘッダー、デバッグモード、デフォルト設定
- 機密データの露出 → ログ、エラーメッセージ、データ送信
- 認証の不備 → パスワードポリシー、セッション管理
- アクセス制御の不備 → 権限チェック、RBAC
- ログ記録の不備 → セキュリティイベントの記録
- SSRF → 外部 URL の取得
- XXE → XML の解析
- 安全でないデシリアライゼーション → Pickle、YAML の読み込み
- パストラバーサル → ファイルシステムへのアクセス
- コマンドインジェクション → システムコマンドの実行
- レート制限の欠如 → API の保護
ステップ 2:脆弱なパターンを検索する
grep/ripgrep を使用して、脆弱なコードパターンを検索します。
# SQL Injection
grep -r "cursor.execute.*%" .
grep -r "query.*format" .
# XSS
grep -r "innerHTML" .
grep -r "dangerouslySetInnerHTML" .
# Command Injection
grep -r "os.system" .
grep -r "shell=True" .
# Path Traversal
grep -r "open.*request" .
# Insecure Deserialization
grep -r "pickle.loads" .
grep -r "yaml.load" .
ステップ 3:Ark への影響を分析する
影響を受ける Ark コンポーネントを検討します。
- Go オペレーター:
ark/- コントローラー、Webhook、API サーバー - Python サービス:
services/- エグゼキューターサービス、API エンドポイント - Node.js アプリケーション:
ark-dashboard/、docs/、ark-cli/ - Kubernetes リソース:デプロイ設定、RBAC、ネットワークポリシー
ステップ 4:緩和策を提示する
ユーザーに以下を提示します。
- 見つかった脆弱なコードパターン
- 各パターンに推奨される修正
- テスト戦略
- 変更によって発生する可能性のある破壊的変更
実装する前に、ユーザーの承認を待ちます。
ステップ 5:修正を実装する
上記のカテゴリから適切な緩和策を適用します:
- 脆弱なコードパターンを更新する
- セキュリティミドルウェア/バリデーターを追加する
- セキュリティヘッダーを設定する
- 必要に応じて依存関係を更新する
ステップ 6:修正をテストする
# Run existing tests
make test
# Security-specific tests
# - Test with malicious input
# - Verify security headers
# - Check authorization enforcement
# - Validate input sanitization
ステップ 7:セキュリティの背景情報を添えて PR を作成する
以下を記録します:
- 見つかった脆弱性
- 発見された場所(ファイル、行番号)
- 修正のために変更した内容
- 修正を検証する方法
- 互換性を損なう変更
Ark 固有のセキュリティ上の考慮事項
Kubernetes Operator のセキュリティ
CRD の検証:
// Add validation to CRD specs
// +kubebuilder:validation:Pattern=^[a-zA-Z0-9-]+$
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Name string `json:"name"`
最小権限の原則に基づく RBAC:
# Only grant necessary permissions
rules:
- apiGroups: ["ark.example.com"]
resources: ["models"]
verbs: ["get", "list"] # Not "delete" or "*"
Python サービスのセキュリティ
入力の検証:
from pydantic import BaseModel, validator
class PromptRequest(BaseModel):
prompt: str
max_tokens: int
@validator('prompt')
def validate_prompt(cls, v):
if len(v) > 10000:
raise ValueError('Prompt too long')
return v
@validator('max_tokens')
def validate_max_tokens(cls, v):
if v < 1 or v > 4096:
raise ValueError('Invalid max_tokens')
return v
Node.js / Next.js のセキュリティ
環境変数:
// Only expose NEXT_PUBLIC_ vars to client
// next.config.js
module.exports = {
env: {
// Server-side only
DATABASE_URL: process.env.DATABASE_URL,
},
publicRuntimeConfig: {
// Client-side accessible
API_URL: process.env.NEXT_PUBLIC_API_URL,
},
}
Docker のセキュリティ
非 root ユーザー:
# Run as non-root user
RUN addgroup -g 1001 -S appuser && \
adduser -u 1001 -S appuser -G appuser
USER appuser
最小限のベースイメージ:
# Use distroless or alpine
FROM gcr.io/distroless/python3
# OR
FROM python:3.11-alpine
セキュリティ修正のテスト
手動テストのチェックリスト
- 悪意のある入力でテストする(SQL インジェクションのペイロード)
- XSS のペイロードでテストする(
<script>alert('XSS')</script>) - パストラバーサルでテストする(
../../../../etc/passwd) - 認可の回避をテストする(ユーザー A がユーザー B のデータにアクセスする)
- レート制限をテストする(過剰なリクエスト)
- セキュリティヘッダーが存在することを確認する
- エラーメッセージから機密データが漏えいしないことを確認する
- HTTPS/TLS が強制されていることを確認する
自動セキュリティテスト
# Static analysis
bandit -r services/ # Python
gosec ./... # Go
npm audit # Node.js
# Dependency scanning
safety check # Python
go list -json -m all | nancy sleuth # Go
npm audit fix # Node.js
# Container scanning
trivy image ark-operator:latest
一般的なペネトレーションテスト報告書のキーワード
ペネトレーションテスト報告書で以下の用語を見つけたら、適切なカテゴリに対応付けます:
- 「入力検証が不十分」 → SQL インジェクション、XSS、コマンドインジェクション、パストラバーサル
- 「セキュリティヘッダーがない」 → セキュリティ設定の不備(#5)
- 「機密情報の漏えい」 → 機密データの露出(#6)
- 「CSRF 対策がない」 → CSRF(#3)
- 「アクセス制御の不備」 → IDOR(#4)またはアクセス制御の不備(#8)
- 「認証が弱い」 → 認証の不備(#7)
- 「セッション管理が安全でない」 → 認証の不備(#7)
- 「サーバーサイドリクエストフォージェリ」 → SSRF(#10)
- 「XML 外部エンティティインジェクション」 → XXE(#11)
- 「デシリアライゼーションが安全でない」 → デシリアライゼーションの不備(#12)
- 「ディレクトリトラバーサル」 → パストラバーサル(#13)
- 「OS コマンドインジェクション」 → コマンドインジェクション(#14)
- 「レート制限がない」 → レート制限の欠如(#15)
- 「情報漏えい」 → 機密データの露出(#6)
- 「ログ記録が不十分」 → ログ記録と監視の不足(#9)
重要な注意事項
- セキュリティ修正を実装する前に、必ずユーザーの承認を得てください
- 十分にテストしてください。セキュリティ修正によって機能が損なわれることがあります
- コミットメッセージと PR で、脆弱性を明確に記録してください
- API や動作を変更する際は、後方互換性を考慮してください
- 重大度に応じて優先順位を付けてください:Critical > High > Medium > Low
- 多層防御:複数層のセキュリティ制御を適用してください
- 最小権限の原則:必要最小限の権限を付与してください