omamori 0.1.1 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +0 -3
- data/Gemfile.lock +12 -12
- data/README.md +32 -4
- data/README_ja.md +32 -4
- data/lib/omamori/ai_analysis_engine/diff_splitter.rb +14 -19
- data/lib/omamori/ai_analysis_engine/gemini_client.rb +4 -3
- data/lib/omamori/ai_analysis_engine/prompt_manager.rb +93 -42
- data/lib/omamori/config.rb +21 -0
- data/lib/omamori/core_runner.rb +383 -157
- data/lib/omamori/version.rb +1 -1
- metadata +44 -24
- data/demo_/ai_analysis_vulnerability.rb +0 -28
- data/demo_/csrf_vulnerability.rb +0 -31
- data/demo_/eval_vulnerability.rb +0 -29
- data/demo_/idor_vulnerability.rb +0 -39
- data/demo_/insecure_cookie_vulnerability.rb +0 -25
- data/demo_/open_redirect_vulnerability.rb +0 -22
- data/demo_/static_analysis_vulnerability.rb +0 -18
- data/demo_/xss_vulnerability.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bafa258377208d15c678d88752804be6963159d28b83c13958de28bdd8bf8fa7
|
4
|
+
data.tar.gz: 9739ae26075e9e5c0f2f87eafd68f2ed6cce0baee719a4c31c1042e8b1c8abf9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 373c41e264bc7548b3b4f37a526ed98fcefdd6a51fc6eaa8571b18d7688e131b4852c7e4ce839c7cdd43e540c3bf83b7466a1a66c29cea7c5d6e03dcd59f5cac
|
7
|
+
data.tar.gz: 102078caed02ab830885759ddf21bc8430b15c6a829a5f4ed7c1fcca99360ac707bb938ab19a8f2f9a5ed8ad2ccd86427acfaecc1da6d55a48c27338ae753454
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
omamori (0.1.
|
4
|
+
omamori (0.1.4)
|
5
|
+
brakeman (~> 7.0)
|
6
|
+
bundler-audit (~> 0.9.2)
|
5
7
|
colorize (~> 0.8)
|
6
8
|
dotenv (~> 2.0)
|
9
|
+
ruby-gemini-api (~> 0.1.1)
|
7
10
|
|
8
11
|
GEM
|
9
12
|
remote: https://rubygems.org/
|
@@ -15,7 +18,7 @@ GEM
|
|
15
18
|
bundler (>= 1.2.0, < 3)
|
16
19
|
thor (~> 1.0)
|
17
20
|
colorize (0.8.1)
|
18
|
-
diff-lcs (1.6.
|
21
|
+
diff-lcs (1.6.2)
|
19
22
|
dotenv (2.8.1)
|
20
23
|
faraday (2.13.1)
|
21
24
|
faraday-net_http (>= 2.0, < 3.5)
|
@@ -25,8 +28,8 @@ GEM
|
|
25
28
|
multipart-post (~> 2.0)
|
26
29
|
faraday-net_http (3.4.0)
|
27
30
|
net-http (>= 0.5.0)
|
28
|
-
json (2.
|
29
|
-
language_server-protocol (3.17.0.
|
31
|
+
json (2.12.0)
|
32
|
+
language_server-protocol (3.17.0.5)
|
30
33
|
lint_roller (1.1.0)
|
31
34
|
logger (1.7.0)
|
32
35
|
multipart-post (2.4.1)
|
@@ -47,14 +50,14 @@ GEM
|
|
47
50
|
rspec-mocks (~> 3.13.0)
|
48
51
|
rspec-core (3.13.3)
|
49
52
|
rspec-support (~> 3.13.0)
|
50
|
-
rspec-expectations (3.13.
|
53
|
+
rspec-expectations (3.13.4)
|
51
54
|
diff-lcs (>= 1.2.0, < 2.0)
|
52
55
|
rspec-support (~> 3.13.0)
|
53
|
-
rspec-mocks (3.13.
|
56
|
+
rspec-mocks (3.13.4)
|
54
57
|
diff-lcs (>= 1.2.0, < 2.0)
|
55
58
|
rspec-support (~> 3.13.0)
|
56
|
-
rspec-support (3.13.
|
57
|
-
rubocop (1.75.
|
59
|
+
rspec-support (3.13.3)
|
60
|
+
rubocop (1.75.6)
|
58
61
|
json (~> 2.3)
|
59
62
|
language_server-protocol (~> 3.17.0.2)
|
60
63
|
lint_roller (~> 1.1.0)
|
@@ -68,7 +71,7 @@ GEM
|
|
68
71
|
rubocop-ast (1.44.1)
|
69
72
|
parser (>= 3.3.7.2)
|
70
73
|
prism (~> 1.4)
|
71
|
-
ruby-gemini-api (0.1.
|
74
|
+
ruby-gemini-api (0.1.1)
|
72
75
|
faraday (~> 2.0)
|
73
76
|
faraday-multipart (~> 1.0)
|
74
77
|
json (~> 2.0)
|
@@ -84,14 +87,11 @@ PLATFORMS
|
|
84
87
|
x86_64-linux
|
85
88
|
|
86
89
|
DEPENDENCIES
|
87
|
-
brakeman (~> 7.0)
|
88
90
|
bundler (~> 2.0)
|
89
|
-
bundler-audit (~> 0.9.2)
|
90
91
|
omamori!
|
91
92
|
rake (~> 13.0)
|
92
93
|
rspec (~> 3.0)
|
93
94
|
rubocop (~> 1.0)
|
94
|
-
ruby-gemini-api (~> 0.1.0)
|
95
95
|
|
96
96
|
BUNDLED WITH
|
97
97
|
2.5.17
|
data/README.md
CHANGED
@@ -15,11 +15,12 @@ Running the analysis multiple times may help reduce false negatives.
|
|
15
15
|
|
16
16
|
## Features
|
17
17
|
|
18
|
-
- Scan staged changes (`git diff --staged`)
|
18
|
+
- Scan staged changes (`git diff --staged`), the entire codebase, or specified files and directories for security risks.
|
19
19
|
- Integrates with static analysis tools like Brakeman and Bundler-Audit.
|
20
20
|
- Utilizes the Gemini API for advanced code analysis to detect vulnerabilities.
|
21
21
|
- Supports multiple report formats (console, HTML, JSON).
|
22
22
|
- Configurable via a `.omamorirc` file.
|
23
|
+
- Exclusion of files and directories via a `.omamoriignore` file (except in `diff` mode).
|
23
24
|
|
24
25
|
## Installation
|
25
26
|
|
@@ -51,7 +52,7 @@ To generate an initial configuration file (`.omamorirc`), run:
|
|
51
52
|
omamori init
|
52
53
|
```
|
53
54
|
|
54
|
-
Edit the generated `.omamorirc`
|
55
|
+
Edit the generated `.omamorirc` and `.omamoriignore` files to configure your Gemini API key, preferred model, checks to perform, and files/directories to exclude from scanning, and other settings.
|
55
56
|
|
56
57
|
### Scanning
|
57
58
|
|
@@ -66,6 +67,7 @@ Scan the entire codebase:
|
|
66
67
|
```bash
|
67
68
|
omamori scan --all
|
68
69
|
```
|
70
|
+
This mode respects the `.omamoriignore` file.
|
69
71
|
|
70
72
|
Specify output format (console, html, json):
|
71
73
|
|
@@ -74,6 +76,22 @@ bundle exec omamori scan --format html
|
|
74
76
|
bundle exec omamori scan --all --format json
|
75
77
|
```
|
76
78
|
|
79
|
+
### Scan Specific Files/Directories
|
80
|
+
|
81
|
+
You can specify particular files or directories to scan:
|
82
|
+
|
83
|
+
```bash
|
84
|
+
omamori scan <file_path1> <file_path2> ... <directory_path1> ...
|
85
|
+
```
|
86
|
+
|
87
|
+
Example:
|
88
|
+
|
89
|
+
```bash
|
90
|
+
omamori scan app/controllers/users_controller.rb app/models/user.rb config/routes.rb lib/
|
91
|
+
```
|
92
|
+
|
93
|
+
This mode respects the `.omamoriignore` file.
|
94
|
+
|
77
95
|
### AI Analysis Only
|
78
96
|
|
79
97
|
To perform only AI analysis without running static analysis tools, use the `--ai` option:
|
@@ -96,7 +114,7 @@ Here's a detailed breakdown of the configuration options:
|
|
96
114
|
# You can also set this via the GEMINI_API_KEY environment variable
|
97
115
|
api_key: YOUR_GEMINI_API_KEY # Replace with your actual API key
|
98
116
|
|
99
|
-
# Gemini Model to use (optional, default: gemini-
|
117
|
+
# Gemini Model to use (optional, default: gemini-2.5-flash-preview-04-17)
|
100
118
|
model: gemini-2.5-flash-preview-04-17
|
101
119
|
|
102
120
|
# Security checks to enable (optional, default: all implemented checks)
|
@@ -128,7 +146,7 @@ model: gemini-2.5-flash-preview-04-17
|
|
128
146
|
```
|
129
147
|
|
130
148
|
* `api_key`: Your API key for accessing the Gemini API. Can also be set via the `GEMINI_API_KEY` environment variable.
|
131
|
-
* `model`: The Gemini model to use for AI analysis. Defaults to `gemini-
|
149
|
+
* `model`: The Gemini model to use for AI analysis. Defaults to `gemini-2.5-flash-preview-04-17`.
|
132
150
|
* `checks`: Configure which types of security checks to enable. By default, all implemented checks are enabled. You can selectively enable/disable checks here (e.g., `xss: true`, `csrf: false`).
|
133
151
|
* `prompt_templates`: Define custom prompt templates for AI analysis.
|
134
152
|
* `report`: Configure report output settings.
|
@@ -139,6 +157,16 @@ model: gemini-2.5-flash-preview-04-17
|
|
139
157
|
* `bundler_audit`: Additional command-line options for Bundler-Audit.
|
140
158
|
* `language`: Language setting for the details provided in AI analysis reports. Defaults to English (`en`).
|
141
159
|
|
160
|
+
## .omamoriignore File
|
161
|
+
|
162
|
+
The `.omamoriignore` file allows you to exclude specific files and directories from the scan target. Its behavior is similar to a `.gitignore` file, but with the following considerations:
|
163
|
+
|
164
|
+
* **Effective Modes:** It is only effective in `--all` mode or when scanning specified files/directories.
|
165
|
+
* **Ineffective Mode:** In `diff` mode (i.e., `omamori scan` without arguments), the `.omamoriignore` file is ignored. This is because `diff` mode only targets changes retrieved by `git diff`.
|
166
|
+
* **Format:** Each line specifies one pattern. Lines starting with `#` are treated as comments. It is recommended to append a `/` to directory patterns (e.g., `vendor/`). Patterns are evaluated using simple prefix matching (e.g., `config/initializers` matches `config/initializers/devise.rb`). Wildcards (`*`) are not currently supported.
|
167
|
+
|
168
|
+
When you run the `omamori init` command, a `.omamoriignore` file pre-filled with patterns for common files and directories to ignore in a Rails project will be generated. You can edit this file as needed.
|
169
|
+
|
142
170
|
## Demo Files
|
143
171
|
|
144
172
|
The `demo` directory contains example files with known vulnerabilities that can be used to demonstrate Omamori's capabilities.
|
data/README_ja.md
CHANGED
@@ -13,11 +13,12 @@ AI解析は静的解析で診断できない脆弱性を発見することがで
|
|
13
13
|
|
14
14
|
## 特徴
|
15
15
|
|
16
|
-
- ステージされた変更(`git diff --staged
|
16
|
+
- ステージされた変更(`git diff --staged`)、コードベース全体、または指定されたファイルやディレクトリをスキャンしてセキュリティリスクを検出
|
17
17
|
- BrakemanやBundler-Auditなどの静的解析ツールと連携
|
18
18
|
- Gemini APIを活用し、AIによる高度なコード脆弱性検出
|
19
19
|
- 複数のレポート形式に対応(コンソール、HTML、JSON)
|
20
20
|
- `.omamorirc`ファイルによる柔軟な設定が可能
|
21
|
+
- `.omamoriignore`ファイルによるスキャン対象からの除外機能(`diff`モードを除く)
|
21
22
|
|
22
23
|
## インストール
|
23
24
|
|
@@ -49,7 +50,7 @@ gem install omamori
|
|
49
50
|
omamori init
|
50
51
|
```
|
51
52
|
|
52
|
-
生成された`.omamorirc`ファイルを編集して、Gemini API
|
53
|
+
生成された`.omamorirc`ファイルと`.omamoriignore`ファイルを編集して、Gemini APIキー、使用するモデル、実行するチェック項目、スキャン対象から除外するファイル/ディレクトリなどを設定します。
|
53
54
|
|
54
55
|
### スキャン
|
55
56
|
|
@@ -64,6 +65,7 @@ omamori scan
|
|
64
65
|
```bash
|
65
66
|
omamori scan --all
|
66
67
|
```
|
68
|
+
このモードでは`.omamoriignore`ファイルが有効になります。
|
67
69
|
|
68
70
|
出力形式を指定(コンソール、HTML、JSON):
|
69
71
|
|
@@ -72,6 +74,22 @@ bundle exec omamori scan --format html
|
|
72
74
|
bundle exec omamori scan --all --format json
|
73
75
|
```
|
74
76
|
|
77
|
+
### ファイル/ディレクトリ指定スキャン
|
78
|
+
|
79
|
+
特定のファイルやディレクトリを指定してスキャンを実行します。
|
80
|
+
|
81
|
+
```bash
|
82
|
+
omamori scan <ファイルパス1> <ファイルパス2> ... <ディレクトリパス1> ...
|
83
|
+
```
|
84
|
+
|
85
|
+
例:
|
86
|
+
|
87
|
+
```bash
|
88
|
+
omamori scan app/controllers/users_controller.rb app/models/user.rb config/routes.rb lib/
|
89
|
+
```
|
90
|
+
|
91
|
+
このモードでは`.omamoriignore`ファイルが有効になります。
|
92
|
+
|
75
93
|
### AI解析のみ実施
|
76
94
|
|
77
95
|
静的解析ツールを使わず、AI解析のみを実行するには、`--ai`オプションを使用します:
|
@@ -94,7 +112,7 @@ omamori scan --ai
|
|
94
112
|
# 環境変数GEMINI_API_KEYで設定することも可能
|
95
113
|
api_key: YOUR_GEMINI_API_KEY # 実際のAPIキーに置き換えてください
|
96
114
|
|
97
|
-
# 使用するGeminiモデル(任意、デフォルト: gemini-
|
115
|
+
# 使用するGeminiモデル(任意、デフォルト: gemini-2.5-flash-preview-04-17)
|
98
116
|
model: gemini-2.5-flash-preview-04-17
|
99
117
|
|
100
118
|
# 有効化するセキュリティチェック(任意、デフォルトは全チェック)
|
@@ -126,7 +144,7 @@ model: gemini-2.5-flash-preview-04-17
|
|
126
144
|
```
|
127
145
|
|
128
146
|
- `api_key`: Gemini APIへのアクセスキー。環境変数`GEMINI_API_KEY`でも設定可能。
|
129
|
-
- `model`: AI解析に使用するGeminiモデル。デフォルトは`gemini-
|
147
|
+
- `model`: AI解析に使用するGeminiモデル。デフォルトは`gemini-2.5-flash-preview-04-17`。
|
130
148
|
- `checks`: 実行するセキュリティチェックの設定。特定のチェックを有効/無効にできます(例:`xss: true`, `csrf: false`)。
|
131
149
|
- `prompt_templates`: AI解析用のカスタムプロンプトテンプレートを設定。
|
132
150
|
- `report`: レポート出力に関する設定。
|
@@ -135,6 +153,16 @@ model: gemini-2.5-flash-preview-04-17
|
|
135
153
|
- `static_analysers`: 静的解析ツール(Brakeman、Bundler-Auditなど)の追加オプション設定。
|
136
154
|
- `language`: AI解析結果の詳細説明文の言語設定。デフォルトは英語(`en`)。
|
137
155
|
|
156
|
+
## .omamoriignore ファイル
|
157
|
+
|
158
|
+
`.omamoriignore`ファイルを使用すると、特定のファイルやディレクトリをスキャン対象から除外できます。これは`.gitignore`ファイルと似たような働きをしますが、以下の点に注意してください。
|
159
|
+
|
160
|
+
* **有効なモード:** `--all` モード、またはファイル/ディレクトリを指定してスキャンする場合にのみ有効です。
|
161
|
+
* **無効なモード:** `diff` モード(引数なしの `omamori scan`)では、`.omamoriignore` ファイルは無視されます。これは、`git diff` で取得された変更点のみを対象とするためです。
|
162
|
+
* **書式:** 1行に1つのパターンを記述します。`#` で始まる行はコメントとして扱われます。ディレクトリを指定する場合は、末尾に `/` を付けることを推奨します (例: `vendor/`)。単純な前方一致で評価されます。 (例: `config/initializers` は `config/initializers/devise.rb` にマッチします)ワイルドカード (`*`) は現時点ではサポートされていません。
|
163
|
+
|
164
|
+
`omamori init` コマンドを実行すると、一般的なRailsプロジェクトで無視すべきファイルやディレクトリのパターンが記述された`.omamoriignore`ファイルが生成されます。必要に応じてこのファイルを編集してください。
|
165
|
+
|
138
166
|
## デモファイル
|
139
167
|
|
140
168
|
`demo`ディレクトリには、Omamoriの機能をデモンストレーションするための既知の脆弱性を含むサンプルファイルが置かれています。
|
@@ -1,12 +1,8 @@
|
|
1
|
-
#
|
1
|
+
# lib/omamori/ai_analysis_engine/diff_splitter.rb
|
2
2
|
|
3
3
|
module Omamori
|
4
4
|
module AIAnalysisEngine
|
5
5
|
class DiffSplitter
|
6
|
-
# TODO: Determine appropriate chunk size based on token limits
|
7
|
-
# Gemini 1.5 Pro has a large context window (1 million tokens),
|
8
|
-
# but splitting might still be necessary for very large inputs
|
9
|
-
# or to manage cost/latency.
|
10
6
|
DEFAULT_CHUNK_SIZE = 8000 # Characters as a proxy for tokens
|
11
7
|
|
12
8
|
def initialize(chunk_size: DEFAULT_CHUNK_SIZE)
|
@@ -17,8 +13,8 @@ module Omamori
|
|
17
13
|
chunks = []
|
18
14
|
current_chunk = ""
|
19
15
|
content.each_line do |line|
|
20
|
-
if (current_chunk.length + line.length) > @chunk_size
|
21
|
-
chunks << current_chunk
|
16
|
+
if (current_chunk.length + line.length) > @chunk_size && !current_chunk.empty?
|
17
|
+
chunks << current_chunk
|
22
18
|
current_chunk = line
|
23
19
|
else
|
24
20
|
current_chunk += line
|
@@ -28,30 +24,29 @@ module Omamori
|
|
28
24
|
chunks
|
29
25
|
end
|
30
26
|
|
31
|
-
|
27
|
+
# Updated to accept file_path keyword argument
|
28
|
+
def process_in_chunks(content, gemini_client, json_schema, prompt_manager, risks_to_check, model: "gemini-2.5-flash-preview-04-17", file_path: nil)
|
32
29
|
all_results = []
|
33
30
|
chunks = split(content)
|
34
31
|
|
35
|
-
puts "Splitting content into #{chunks.size} chunks
|
32
|
+
puts "[DEBUG Omamori DiffSplitter] Splitting content into #{chunks.size} chunks for file: #{file_path || 'N/A'}"
|
36
33
|
|
37
34
|
chunks.each_with_index do |chunk, index|
|
38
|
-
puts "Processing chunk #{index + 1}/#{chunks.size}
|
39
|
-
|
40
|
-
|
35
|
+
puts "[DEBUG Omamori DiffSplitter] Processing chunk #{index + 1}/#{chunks.size} for file: #{file_path || 'N/A'}"
|
36
|
+
# Pass file_path (potentially modified for chunks) to build_prompt
|
37
|
+
chunk_file_path_info = if file_path
|
38
|
+
chunks.size > 1 ? "#{file_path} (chunk #{index + 1}/#{chunks.size})" : file_path
|
39
|
+
end
|
40
|
+
prompt = prompt_manager.build_prompt(chunk, risks_to_check, json_schema, file_path: chunk_file_path_info)
|
41
|
+
result = gemini_client.analyze(prompt, json_schema, model: model) # This call to analyze is correct
|
41
42
|
all_results << result
|
42
|
-
# TODO: Handle potential rate limits or errors between chunks
|
43
43
|
end
|
44
|
-
|
45
|
-
# TODO: Combine results from all chunks
|
46
44
|
combine_results(all_results)
|
47
45
|
end
|
48
46
|
|
49
47
|
private
|
50
48
|
|
51
49
|
def combine_results(results)
|
52
|
-
# This is a placeholder. Combining results from multiple AI responses
|
53
|
-
# requires careful consideration of overlapping findings, context, etc.
|
54
|
-
# For now, just flatten the list of security risks.
|
55
50
|
combined_risks = results.flat_map do |result|
|
56
51
|
result && result["security_risks"] ? result["security_risks"] : []
|
57
52
|
end
|
@@ -59,4 +54,4 @@ module Omamori
|
|
59
54
|
end
|
60
55
|
end
|
61
56
|
end
|
62
|
-
end
|
57
|
+
end
|
@@ -10,15 +10,16 @@ module Omamori
|
|
10
10
|
@client = nil # Initialize client later
|
11
11
|
end
|
12
12
|
|
13
|
-
def analyze(prompt, json_schema, model: "gemini-
|
13
|
+
def analyze(prompt, json_schema, model: "gemini-2.5-flash-preview-04-17")
|
14
14
|
# Ensure the client is initialized
|
15
15
|
client
|
16
16
|
|
17
17
|
begin
|
18
|
-
response =
|
18
|
+
response = client.generate_content(
|
19
19
|
prompt,
|
20
20
|
model: model,
|
21
|
-
response_schema: json_schema # Use response_schema for Structured Output
|
21
|
+
response_schema: json_schema, # Use response_schema for Structured Output
|
22
|
+
temperature: 0.0
|
22
23
|
)
|
23
24
|
|
24
25
|
# Debug: Inspect the response object
|
@@ -1,60 +1,93 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Omamori
|
4
2
|
module AIAnalysisEngine
|
5
3
|
class PromptManager
|
6
4
|
# TODO: Load prompt templates from config file
|
7
5
|
DEFAULT_PROMPT_TEMPLATE = <<~TEXT
|
8
|
-
You are a security expert specializing in Ruby. Analyze the following code and detect any potential security risks.
|
6
|
+
You are a security expert specializing in Ruby. Analyze the following code and detect any potential security risks. Think step by step.
|
9
7
|
Focus particularly on identifying the following types of vulnerabilities: %{risk_list}
|
10
8
|
Report any detected risks in the format specified by the following JSON Schema:
|
11
9
|
%{json_schema}
|
12
10
|
If no risks are found, output an empty list for the "security_risks" array.
|
13
11
|
Please provide your response in %{language}.
|
12
|
+
#{"File context (if available): %{file_path}" if ENV['OMAMORI_DEBUG_PROMPT']}
|
14
13
|
|
15
14
|
【Code to Analyze】:
|
16
15
|
%{code_content}
|
17
16
|
TEXT
|
18
17
|
|
18
|
+
# dangerous_eval の説明、脆弱なRubyコード例、検出ステップ(導入文付き)を定義する文字列
|
19
|
+
dangerous_eval_prompt = <<~PROMPT
|
20
|
+
Dangerous Code Execution (eval, exec): Dynamic code execution using untrusted input, allowing arbitrary code injection.
|
21
|
+
|
22
|
+
**Vulnerable Ruby Code Examples:**
|
23
|
+
```ruby
|
24
|
+
# Direct eval of user input (e.g., from HTTP parameters like params[:user_code])
|
25
|
+
result = eval(params[:user_code])
|
26
|
+
|
27
|
+
# User input embedded in evaluated string (String interpolation)
|
28
|
+
log_message = "User action: \#{params[:action]}"
|
29
|
+
# Even if log_message seems harmless, injecting code like "'); malicious_code; # " might be possible
|
30
|
+
eval("log('\#{log_message}')") # Note: Interpolation inside eval string needs care with escaping
|
31
|
+
|
32
|
+
# OS Command injection via system() or backticks (`) using user input
|
33
|
+
# Assumes params[:directory] or params[:filename] comes directly from user input
|
34
|
+
output = `ls \#{params[:directory]}` # User input determines command executed
|
35
|
+
system("process_file.sh \#{params[:filename]}") # User input determines command argument
|
36
|
+
|
37
|
+
# Dynamic method invocation using send() or public_send() with user-controlled method names or arguments
|
38
|
+
# Assumes params[:method_name] or params[:argument] comes from user input
|
39
|
+
target_object = SomeClass.new
|
40
|
+
target_object.send(params[:method_name], params[:argument]) # User can potentially call dangerous methods
|
41
|
+
|
42
|
+
# Using instance_eval or class_eval with user-provided code strings
|
43
|
+
user_script = params[:custom_script]
|
44
|
+
some_object.instance_eval(user_script) # Executes arbitrary Ruby code in the object's context
|
45
|
+
To detect code vulnerable to Dangerous Code Execution like the examples provided above, perform the following detection steps:
|
46
|
+
|
47
|
+
Search for methods enabling dynamic code execution in Ruby code (e.g., eval, instance_eval, class_eval, send, public_send, system, exec, backticks `).
|
48
|
+
Check if arguments passed to these methods originate from or are directly influenced by external untrusted input (e.g., HTTP request parameters params, data from files, network responses). Look for patterns similar to the vulnerable Ruby examples shown above.
|
49
|
+
Verify if user input is rigorously sanitized or validated specifically to prevent code injection vectors before being used in these methods. Standard escaping for HTML (like XSS prevention) is not sufficient here. Check if execution is restricted only to a predefined, absolutely safe allowlist of commands or methods if dynamic execution cannot be avoided.
|
50
|
+
Assess if safer alternatives exist that can achieve the same functionality without dynamic code execution. Examples include using Hash lookups for dispatching actions, case statements based on input values, leveraging safe templating engines, or using specific library functions designed for the task instead of generic execution methods.
|
51
|
+
PROMPT
|
19
52
|
|
20
53
|
RISK_PROMPTS = {
|
21
|
-
xss: "Cross-Site Scripting (XSS): A vulnerability where user input is not properly escaped and is embedded into HTML or JavaScript, leading to arbitrary script execution in the victim
|
22
|
-
csrf: "Cross-Site Request Forgery (CSRF): An attack that forces an authenticated user to perform unwanted actions via forged requests.
|
23
|
-
idor: "Insecure Direct Object Reference (IDOR): Occurs when object identifiers (e.g., IDs) are exposed and access control is missing, allowing unauthorized access to other users
|
24
|
-
open_redirect: "Open Redirect: Redirecting users to external URLs based on user-supplied input without proper validation. Check
|
25
|
-
ssrf: "Server-Side Request Forgery (SSRF): The server makes HTTP requests to an arbitrary destination supplied by the user, potentially exposing internal resources or metadata.",
|
26
|
-
session_fixation: "Session Fixation: The server accepts a pre-supplied session ID, allowing an attacker to hijack the session after authentication. Look for
|
27
|
-
inappropriate_cookie_attributes: "Insecure Cookie Attributes: Missing HttpOnly, Secure, or SameSite flags, which may lead to session theft or CSRF.",
|
28
|
-
insufficient_encryption: "Insufficient Encryption: Use of weak algorithms (e.g., MD5, SHA1) or lack of encryption for sensitive data. Check for insecure hash functions or plain-text handling.",
|
29
|
-
insecure_deserialization_rce: "Insecure Deserialization leading to RCE: Deserializing untrusted data can lead to arbitrary code execution. Detect unsafe use of deserialization functions without validation.",
|
30
|
-
directory_traversal: "Directory Traversal: Allows attackers to access files outside the intended directory using ../ patterns. Check for path manipulation and missing canonicalization.",
|
31
|
-
dangerous_eval: "Dangerous Code Execution (eval, exec): Dynamic code execution using untrusted input, allowing arbitrary code injection.",
|
32
|
-
inappropriate_file_permissions: "Insecure File Permissions: Files or directories with overly permissive modes (e.g., 777), allowing unauthorized read/write/execute access.",
|
33
|
-
temporary_backup_file_leak: "Temporary or Backup File Exposure: Sensitive files like .bak, .tmp, or ~ versions are publicly accessible due to poor file handling.",
|
34
|
-
overly_detailed_errors: "Excessive Error Information Disclosure: Stack traces or internal error messages exposed to users, leaking implementation details.",
|
35
|
-
csp_not_set: "Missing Content Security Policy (CSP): Absence of CSP headers increases risk of XSS. Look for missing Content-Security-Policy header.",
|
36
|
-
mime_sniffing_vulnerability: "MIME Sniffing Vulnerability: Missing X-Content-Type-Options: nosniff header can allow browsers to misinterpret content types.",
|
37
|
-
clickjacking_vulnerability: "Clickjacking Protection Missing: Absence of X-Frame-Options or frame-ancestors directive allows malicious framing of pages.",
|
38
|
-
auto_index_exposure: "Auto Indexing Enabled: Directory listing is active, exposing files and internal structure to users.",
|
39
|
-
inappropriate_password_policy: "Weak Password Policy: Inadequate rules such as short length, lack of complexity, or missing brute-force protections.",
|
40
|
-
two_factor_auth_missing: "Missing Two-Factor Authentication (2FA): Lack of secondary authentication factor for sensitive operations.",
|
41
|
-
race_condition: "Race Condition: Concurrent access without proper locking can lead to inconsistent states or privilege escalation.",
|
42
|
-
server_error_information_exposure: "Server Error Information Exposure: Internal errors (e.g., 500) reveal stack traces or server information in responses.",
|
43
|
-
dependency_trojan_package: "Dependency Trojan Package Risk: Installation of malicious or typosquatted packages from untrusted sources.",
|
44
|
-
api_overexposure: "Excessive API Exposure: Public APIs exposed without authentication, leading to data leakage or unauthorized access.",
|
45
|
-
security_middleware_disabled: "Security Middleware Disabled: Important protections (e.g., CSRF tokens, input sanitization) are turned off or removed.",
|
46
|
-
security_header_inconsistency: "Security Header Inconsistency: Inconsistent or missing security headers across environments or routes.",
|
47
|
-
excessive_login_attempts: "Excessive Login Attempts Allowed: Lack of rate limiting allows brute-force login attempts.",
|
48
|
-
inappropriate_cache_settings: "Insecure Cache Settings: Sensitive pages are cached publicly (e.g., with Cache-Control: public), risking data leakage.",
|
49
|
-
secret_key_committed: "Secret Key Committed to Repository: Credentials, JWT secrets, or API keys are hardcoded or pushed to version control.",
|
50
|
-
third_party_script_validation_missing:
|
51
|
-
over_logging: "Over-Logging: Logging sensitive information such as passwords, tokens, or personal data.",
|
52
|
-
fail_open_design: "Fail-Open Design: On error or exception, access is granted instead of safely denied.",
|
53
|
-
environment_differences: "Uncontrolled Environment Differences: Security settings differ between development and production without strict controls.",
|
54
|
-
audit_log_missing: "Missing Audit Logging: Lack of logging for critical actions or authorization checks prevents accountability.",
|
55
|
-
time_based_side_channel: "Time-Based Side Channel: Execution time differences can leak secrets (e.g., timing attacks in string comparison)."
|
54
|
+
xss: "Cross-Site Scripting (XSS): A vulnerability where user input is not properly escaped and is embedded into HTML or JavaScript, leading to arbitrary script execution in the victim's browser. Detection steps: 1) Identify where user input is output to HTML/JS context. 2) Check if proper encoding/escaping is applied (e.g., html_safe, raw, sanitize, escape_javascript). 3) Look for unsafe methods that bypass default Rails escaping (html_safe, raw, <%==). 4) Examine JavaScript that incorporates user input via template interpolation. 5) Check for improper content-type headers that might enable XSS. 6) Verify if user input is passed to eval(), setTimeout(), document.write() or DOM manipulation functions. 7) Look for attribute injection possibilities where user input sets HTML attributes.",
|
55
|
+
csrf: "Cross-Site Request Forgery (CSRF): An attack that forces an authenticated user to perform unwanted actions via forged requests. Detection steps: 1) Check if CSRF protection is disabled globally or for specific controllers/actions (skip_before_action :verify_authenticity_token). 2) Look for APIs or endpoints that handle state-changing operations (POST, PUT, DELETE methods). 3) Verify if authenticity tokens are properly validated for forms and AJAX requests. 4) Check if the application relies solely on cookies for authentication without additional CSRF protection. 5) Look for custom CSRF protection implementations that might be incomplete. 6) Verify if SameSite cookie attributes are properly set. 7) Check if the application validates the Origin or Referer header for cross-origin requests.",
|
56
|
+
idor: "Insecure Direct Object Reference (IDOR): Occurs when object identifiers (e.g., IDs) are exposed and access control is missing, allowing unauthorized access to other users' data. Detection steps: 1) Identify endpoints that access data using user-supplied identifiers (e.g., params[:id]). 2) Check if proper authorization checks exist before accessing the data (e.g., current_user.orders vs Order.find). 3) Look for functions retrieving data without verifying the current user's ownership or access rights. 4) Check for sequential or predictable IDs that can be enumerated. 5) Verify if sensitive operations verify resource ownership before modifications. 6) Look for authorization checks that can be bypassed through parameter manipulation. 7) Examine APIs that return data based on user-supplied identifiers.",
|
57
|
+
open_redirect: "Open Redirect: Redirecting users to external URLs based on user-supplied input without proper validation. Detection steps: 1) Identify redirect methods or functions (redirect_to, headers['Location'], response.redirect, etc.). 2) Check if the redirect URL or destination can be controlled by user input. 3) Verify if there is proper validation of the redirect URL to prevent external redirects. 4) Look for validation patterns that only check for URL prefixes that could be bypassed. 5) Check if the code restricts redirects to only allowed domains or uses relative paths. 6) Watch for URL manipulation techniques that might bypass validation (using //, additional domains in path, URL encoding).",
|
58
|
+
ssrf: "Server-Side Request Forgery (SSRF): The server makes HTTP requests to an arbitrary destination supplied by the user, potentially exposing internal resources or metadata. Detection steps: 1) Identify code that makes network requests (HTTP, TCP, etc.). 2) Check if the URL or destination can be influenced by user input. 3) Verify if there is proper validation of user-supplied URLs or IPs to prevent access to internal resources. 4) Look for use of libraries like Net::HTTP, open-uri, rest-client, faraday, or HTTP clients where the URL is constructed dynamically. 5) Check if the code restricts requests to only allowed domains or IP ranges.",
|
59
|
+
session_fixation: "Session Fixation: The server accepts a pre-supplied session ID, allowing an attacker to hijack the session after authentication. Detection steps: 1) Check if the application regenerates session IDs upon authentication (reset_session, new session creation). 2) Look for login methods that don't rotate session identifiers. 3) Examine session management code for proper session invalidation after login/logout. 4) Verify if the application accepts externally provided session identifiers. 5) Check if cookie settings include proper security flags (HttpOnly, Secure, SameSite). 6) Examine how session state is maintained across privilege changes (e.g., becoming admin). 7) Look for custom session handling that bypasses Rails' built-in protection mechanisms.",
|
60
|
+
inappropriate_cookie_attributes: "Insecure Cookie Attributes: Missing HttpOnly, Secure, or SameSite flags, which may lead to session theft or CSRF. Detection steps: 1) Examine cookie configuration in session store settings. 2) Check for explicit cookie setting in controllers with cookies[:name] assignments. 3) Verify if sensitive cookies have the HttpOnly flag to prevent JavaScript access. 4) Check if cookies transmitting sensitive data have the Secure flag to prevent transmission over HTTP. 5) Verify if cookies have appropriate SameSite attribute (Strict, Lax, or None with Secure) to prevent CSRF and information leakage. 6) Look for custom session management that might not set proper cookie attributes. 7) Check if cookie expiration times are appropriate for the sensitivity of the data they contain.",
|
61
|
+
insufficient_encryption: "Insufficient Encryption: Use of weak algorithms (e.g., MD5, SHA1) or lack of encryption for sensitive data. Check for insecure hash functions or plain-text handling. Detection steps: 1) Identify code handling sensitive data (passwords, API keys, PII). 2) Check if data at rest (database) or in transit (network) is encrypted. 3) Identify algorithms used for hashing/encryption (e.g., Digest::MD5, Digest::SHA1). 4) Verify if algorithms meet current security standards (e.g., bcrypt, scrypt, SHA-256+ for hashing; AES for encryption). 5) Check secure management of encryption keys.",
|
62
|
+
insecure_deserialization_rce: "Insecure Deserialization leading to RCE: Deserializing untrusted data can lead to arbitrary code execution. Detect unsafe use of deserialization functions without validation. Detection steps: 1) Locate code performing deserialization (e.g., Marshal.load, YAML.load, JSON.parse). 2) Determine if the input data comes from untrusted sources (user input, network). 3) Verify if the data is validated or sanitized before deserialization. 4) Check if safe alternatives are used (e.g., YAML.safe_load, JSON.parse with appropriate options). 5) Analyze custom deserializers for vulnerabilities.",
|
63
|
+
directory_traversal: "Directory Traversal: Allows attackers to access files outside the intended directory using ../ patterns. Check for path manipulation and missing canonicalization. Detection steps: 1) Identify code accessing the file system using paths derived from user input. 2) Check if user input influencing file paths is sanitized (e.g., removing '../'). 3) Verify if path canonicalization functions (e.g., File.expand_path, Pathname#cleanpath) are used correctly. 4) Ensure the final path is validated to be within the intended base directory before access.",
|
64
|
+
dangerous_eval: "Dangerous Code Execution (eval, exec): Dynamic code execution using untrusted input, allowing arbitrary code injection. Detection steps: 1) Search for methods enabling dynamic code execution (eval, instance_eval, class_eval, send, public_send, system, exec, ` ``). 2) Check if arguments passed to these methods originate from or are influenced by user input. 3) Verify if user input is rigorously sanitized or validated before use, or if execution is restricted to safe, predefined commands/methods. 4) Assess if safer alternatives can replace dynamic execution.",
|
65
|
+
inappropriate_file_permissions: "Insecure File Permissions: Files or directories with overly permissive modes (e.g., 777), allowing unauthorized read/write/execute access. Detection steps: 1) Find code that creates files/directories or changes permissions (e.g., FileUtils.chmod, File.chmod, Dir.mkdir with mode). 2) Examine the permission modes being set (e.g., 0777, 0666). 3) Evaluate if permissions follow the principle of least privilege, especially avoiding world-writable (o+w) or world-readable (o+r) for sensitive files. 4) Check permissions of configuration files, log files, and uploaded files.",
|
66
|
+
temporary_backup_file_leak: "Temporary or Backup File Exposure: Sensitive files like .bak, .tmp, or ~ versions are publicly accessible due to poor file handling. Detection steps: 1) Identify logic creating temporary or backup files. 2) Check if common backup extensions (.bak, .tmp, ~, .old) are used. 3) Verify these files are not created within web-accessible directories. 4) Ensure temporary/backup files are securely deleted after use. 5) Check if .gitignore excludes these file patterns.",
|
67
|
+
overly_detailed_errors: "Excessive Error Information Disclosure: Stack traces or internal error messages exposed to users, leaking implementation details. Detection steps: 1) Examine error handling code (rescue blocks, error page rendering). 2) Check error messages displayed to users in the production environment. 3) Verify that stack traces, internal paths, database queries, or configuration details are not included in user-facing errors. 4) Confirm framework settings disable detailed errors in production (e.g., Rails `config.consider_all_requests_local = false`). 5) Ensure generic errors are shown to users, while details are logged server-side.",
|
68
|
+
csp_not_set: "Missing Content Security Policy (CSP): Absence of CSP headers increases risk of XSS. Look for missing Content-Security-Policy header. Detection steps: 1) Identify code setting HTTP response headers (middleware, controllers). 2) Check for the presence of the `Content-Security-Policy` header. 3) If missing or policy is overly permissive (e.g., includes 'unsafe-inline', 'unsafe-eval', '*'), report as risk. 4) Check framework CSP configuration mechanisms (e.g., Rails `config.content_security_policy`).",
|
69
|
+
mime_sniffing_vulnerability: "MIME Sniffing Vulnerability: Missing X-Content-Type-Options: nosniff header can allow browsers to misinterpret content types. Detection steps: 1) Identify code setting HTTP response headers. 2) Check for the presence of the `X-Content-Type-Options` header. 3) If the header is missing or its value is not exactly `nosniff`, report as risk. 4) Check framework defaults or security middleware for automatic inclusion.",
|
70
|
+
clickjacking_vulnerability: "Clickjacking Protection Missing: Absence of X-Frame-Options or frame-ancestors directive allows malicious framing of pages. Detection steps: 1) Identify code setting HTTP response headers. 2) Check for the `X-Frame-Options` header (e.g., `DENY`, `SAMEORIGIN`). 3) Alternatively, check for the `frame-ancestors` directive in the `Content-Security-Policy` header (e.g., `'none'`, `'self'`). 4) If neither is present or configured securely, report as risk. 5) Check framework defaults or security middleware.",
|
71
|
+
auto_index_exposure: "Auto Indexing Enabled: Directory listing is active, exposing files and internal structure to users. Detection steps: 1) Review web server configuration files (Nginx, Apache). 2) Look for directives enabling directory listing (e.g., Apache `Options +Indexes`, Nginx `autoindex on`). 3) Check if directory listing is unintentionally enabled for specific locations. 4) If the application framework serves static files, ensure its directory listing feature is disabled.",
|
72
|
+
inappropriate_password_policy: "Weak Password Policy: Inadequate rules such as short length, lack of complexity, or missing brute-force protections. Detection steps: 1) Locate code related to password setting/changing. 2) Check validation logic for minimum length, complexity requirements (character types). 3) Verify if checks against common weak passwords (dictionaries, patterns) exist. 4) Look for enforcement of password history (reuse prevention) and expiration. 5) Check for related brute-force protection (see `excessive_login_attempts`).",
|
73
|
+
two_factor_auth_missing: "Missing Two-Factor Authentication (2FA): Lack of secondary authentication factor for sensitive operations. Detection steps: 1) Identify login process and code for sensitive operations (e.g., profile change, payment). 2) Check if a second factor (SMS, TOTP, key) is required beyond the password. 3) Look for 2FA setup and management features. 4) Determine if 2FA is mandatory or optional for users.",
|
74
|
+
race_condition: "Race Condition: Concurrent access without proper locking can lead to inconsistent states or privilege escalation. Detection steps: 1) Identify code accessing shared resources (database records, files, cache). 2) Find sections where multiple threads/processes might read/write concurrently. 3) Look for non-atomic check-then-act patterns. 4) Verify use of proper locking mechanisms (database transactions, Mutex, file locks). 5) Focus on critical operations like balance updates, inventory control.",
|
75
|
+
server_error_information_exposure: "Server Error Information Exposure: Internal errors (e.g., 500) reveal stack traces or server information in responses. Detection steps: 1) Examine error handling for server-side errors (e.g., HTTP 500). 2) Check the content of error responses sent to the client in production. 3) Verify that server-specific information (software type/version, OS details) is not included. 4) Check server configuration to suppress revealing headers (e.g., `Server` header; Nginx `server_tokens off;`). 5) Ensure detailed errors are logged only, with generic messages shown to users. (Similar to `overly_detailed_errors` but focusing on server info).",
|
76
|
+
dependency_trojan_package: "Dependency Trojan Package Risk: Installation of malicious or typosquatted packages from untrusted sources. Detection steps: 1) Review dependency files (`Gemfile`, `Gemfile.lock`). 2) Scan the list of Gems for typosquatting or unfamiliar names. 3) Check Gem sources (avoid untrusted Git repos if possible). 4) Investigate reputation and maintenance status of less-known Gems. 5) Ensure `Gemfile.lock` is committed to version control. 6) Check if dependency scanning tools (e.g., `bundler-audit`) are used.",
|
77
|
+
api_overexposure: "Excessive API Exposure: Public APIs exposed without authentication, leading to data leakage or unauthorized access. Detection steps: 1) Identify all API endpoint definitions. 2) Verify that appropriate authentication and authorization checks are applied to each endpoint. 3) Check if rate limiting or access controls are in place, even for public APIs. 4) Ensure sensitive data or internal-only information is not returned by unauthenticated endpoints. 5) Review API documentation for unintended exposure.",
|
78
|
+
security_middleware_disabled: "Security Middleware Disabled: Important protections (e.g., CSRF tokens, input sanitization) are turned off or removed. Detection steps: 1) Review framework initialization and configuration files. 2) Look for intentional disabling or removal of standard security middleware (e.g., CSRF protection, secure session handling). 3) Check for route-specific or controller-specific disabling of security features (e.g., `skip_before_action :verify_authenticity_token`) and evaluate the justification.",
|
79
|
+
security_header_inconsistency: "Security Header Inconsistency: Inconsistent or missing security headers across environments or routes. Detection steps: 1) Locate code setting security headers (CSP, X-Frame-Options, HSTS, etc.). 2) Compare header settings across different environments (dev, staging, prod), ensuring production is not weaker. 3) Verify consistent application of headers across different routes/pages within the application. 4) Check for conflicts if headers are set in multiple places (middleware, reverse proxy).",
|
80
|
+
excessive_login_attempts: "Excessive Login Attempts Allowed: Lack of rate limiting allows brute-force login attempts. Detection steps: 1) Identify the login authentication code. 2) Check for logic that counts and limits login attempts per account and/or IP address within a time window. 3) Verify that countermeasures (account lockout, CAPTCHA, delay) are triggered upon exceeding the limit. 4) Check configuration of rate-limiting libraries (e.g., `rack-attack`). 5) Ensure similar limits exist for password reset functions.",
|
81
|
+
inappropriate_cache_settings: "Insecure Cache Settings: Sensitive pages are cached publicly (e.g., with Cache-Control: public), risking data leakage. Detection steps: 1) Identify code setting `Cache-Control` or `Pragma` headers. 2) Locate code generating pages containing user-specific or sensitive data. 3) Ensure these pages have restrictive cache directives (`private`, `no-store`, `no-cache`). 4) Look for inappropriate use of `public` or long `max-age`. 5) Review framework caching (page, action, fragment) usage for sensitive content. 6) Consider cache settings in reverse proxies/CDNs.",
|
82
|
+
secret_key_committed: "Secret Key Committed to Repository: Credentials, JWT secrets, or API keys are hardcoded or pushed to version control. Detection steps: 1) Scan codebase for hardcoded secrets (passwords, API keys, tokens). 2) Review configuration files (`database.yml`, `secrets.yml`, `.env`) for secrets and ensure they are gitignored if present. 3) Verify secrets are loaded from environment variables or dedicated secret management systems. 4) Scan version control history for accidentally committed secrets (and rotate if found). 5) Consider using secret scanning tools (e.g., `truffleHog`, `gitleaks`).",
|
83
|
+
third_party_script_validation_missing: 'Missing Validation for Third-Party Scripts: External scripts are loaded without integrity checks (e.g., Subresource Integrity). Detection steps: 1) Find HTML templates loading external JS/CSS (`<script src="...">`, `<link href="...">`). 2) Check if these tags include the `integrity` attribute (for SRI). 3) Report as risk if `integrity` attribute is missing or empty. 4) Verify the `crossorigin="anonymous"` attribute is also present when using SRI. 5) Check dynamically loaded scripts for similar integrity validation mechanisms.',
|
84
|
+
over_logging: "Over-Logging: Logging sensitive information such as passwords, tokens, or personal data. Detection steps: 1) Identify all logging statements (`Rails.logger.*`, `puts`, etc.). 2) Examine the data being logged. 3) Check specifically for sensitive data like passwords, tokens, API keys, PII, credit card numbers. 4) Pay attention to logging of entire request parameters or exception objects. 5) Verify framework parameter filtering (e.g., Rails `config.filter_parameters`) is configured correctly to mask sensitive fields.",
|
85
|
+
fail_open_design: "Fail-Open Design: On error or exception, access is granted instead of safely denied. Detection steps: 1) Identify security check code (authentication, authorization, access control). 2) Examine behavior within exception handling blocks (`rescue`). 3) Verify that exceptions during security checks default to denying access (fail-close/fail-safe), not granting it. 4) Look for checks where an error state might be misinterpreted as permissive. 5) Ensure critical operations use transactions and roll back safely on error.",
|
86
|
+
environment_differences: "Uncontrolled Environment Differences: Security settings differ between development and production without strict controls. Detection steps: 1) Compare configuration files across environments (`environments/development.rb` vs `environments/production.rb`). 2) Identify differences in security settings (error reporting, SSL, headers, auth). 3) Evaluate if differences weaken security in production. 4) Check for a process to manage and review environment-specific configurations. 5) Consider potential infrastructure differences (firewalls, server settings).",
|
87
|
+
audit_log_missing: "Missing Audit Logging: Lack of logging for critical actions or authorization checks prevents accountability. Detection steps: 1) Identify code performing critical actions (login, permission change, sensitive data access/modification, config change). 2) Verify these actions generate logs including who (user), when (timestamp), what (action/resource), result (success/fail), and where (IP address). 3) Check if authentication successes/failures and authorization failures are logged. 4) Assess if logs are stored securely and retained appropriately. 5) Ensure log format is consistent and useful for monitoring.",
|
88
|
+
time_based_side_channel: "Time-Based Side Channel: Execution time differences can leak secrets (e.g., timing attacks in string comparison). Detection steps: 1) Locate code comparing secret values (passwords, tokens, API keys). 2) Check if standard comparison operators (`==`) are used for secrets. 3) Verify use of constant-time comparison functions (e.g., `ActiveSupport::SecurityUtils.secure_compare`, `Rack::Utils.secure_compare`). 4) Analyze cryptographic operations for potential timing leaks (may depend on library implementation). 5) Consider if database query times varying based on input could leak information."
|
56
89
|
}.freeze
|
57
|
-
|
90
|
+
|
58
91
|
|
59
92
|
def initialize(config = {})
|
60
93
|
# Load custom templates and language from config, merge with default
|
@@ -64,12 +97,30 @@ module Omamori
|
|
64
97
|
@language = config.get("language", "en") # Get language from config, default to 'en'
|
65
98
|
end
|
66
99
|
|
67
|
-
|
68
|
-
|
100
|
+
# Updated to accept file_path keyword argument
|
101
|
+
def build_prompt(code_content, risks_to_check, json_schema, template_key: :default, file_path: nil)
|
69
102
|
template = @prompt_templates.fetch(template_key, @prompt_templates[:default])
|
70
103
|
risk_list = risks_to_check.map { |risk_key| @risk_prompts[risk_key] }.compact.join(", ")
|
71
104
|
|
72
|
-
|
105
|
+
prompt_variables = {
|
106
|
+
risk_list: risk_list,
|
107
|
+
code_content: code_content,
|
108
|
+
json_schema: json_schema.to_json,
|
109
|
+
language: @language
|
110
|
+
}
|
111
|
+
# Add file_path to variables if provided and template expects it
|
112
|
+
# Ensure your template string (DEFAULT_PROMPT_TEMPLATE or custom ones)
|
113
|
+
# actually uses %{file_path} if you want to include it.
|
114
|
+
prompt_variables[:file_path] = file_path if file_path && template.include?("%{file_path}")
|
115
|
+
|
116
|
+
# Handle cases where a key in prompt_variables might not be in the template string
|
117
|
+
# by selecting only keys present in the template.
|
118
|
+
final_variables = {}
|
119
|
+
template.scan(/%\{(\w+)\}/).flatten.uniq.each do |key_in_template|
|
120
|
+
final_variables[key_in_template.to_sym] = prompt_variables[key_in_template.to_sym]
|
121
|
+
end
|
122
|
+
|
123
|
+
template % final_variables
|
73
124
|
end
|
74
125
|
end
|
75
126
|
end
|
data/lib/omamori/config.rb
CHANGED
@@ -5,10 +5,14 @@ require 'yaml'
|
|
5
5
|
module Omamori
|
6
6
|
class Config
|
7
7
|
DEFAULT_CONFIG_PATH = ".omamorirc"
|
8
|
+
DEFAULT_IGNORE_PATH = ".omamoriignore"
|
9
|
+
|
10
|
+
attr_reader :ignore_patterns
|
8
11
|
|
9
12
|
def initialize(config_path = DEFAULT_CONFIG_PATH)
|
10
13
|
@config_path = config_path
|
11
14
|
@config = load_config
|
15
|
+
@ignore_patterns = load_ignore_patterns # Load ignore patterns
|
12
16
|
validate_config # Add validation after loading
|
13
17
|
end
|
14
18
|
|
@@ -128,6 +132,23 @@ module Omamori
|
|
128
132
|
end
|
129
133
|
end
|
130
134
|
|
135
|
+
# Load .omamoriignore file and return an array of ignore patterns
|
136
|
+
def load_ignore_patterns
|
137
|
+
ignore_path = DEFAULT_IGNORE_PATH
|
138
|
+
if File.exist?(ignore_path)
|
139
|
+
begin
|
140
|
+
File.readlines(ignore_path, chomp: true).reject do |line|
|
141
|
+
line.strip.empty? || line.strip.start_with?('#')
|
142
|
+
end
|
143
|
+
rescue => e
|
144
|
+
puts "Warning: Error reading .omamoriignore file #{ignore_path}: #{e.message}"
|
145
|
+
[] # Return empty array if reading fails
|
146
|
+
end
|
147
|
+
else
|
148
|
+
[] # Return empty array if file does not exist
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
131
152
|
def load_config
|
132
153
|
if File.exist?(@config_path)
|
133
154
|
begin
|