thuban 0.4.0 → 0.4.2
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.
- package/dist/package.json +63 -0
- package/dist/packages/crucible/rules/code-scanner-core.json +129 -0
- package/dist/packages/crucible/rules/command-injection.json +411 -0
- package/dist/packages/crucible/rules/crypto-misuse.json +35 -0
- package/dist/packages/crucible/rules/deserialization.json +152 -0
- package/dist/packages/crucible/rules/env-injection.json +46 -0
- package/dist/packages/crucible/rules/eval-abuse.json +104 -0
- package/dist/packages/crucible/rules/file-upload.json +46 -0
- package/dist/packages/crucible/rules/hallucination.json +22 -0
- package/dist/packages/crucible/rules/hardcoded-secret.json +397 -0
- package/dist/packages/crucible/rules/hardcoded-url.json +13 -0
- package/dist/packages/crucible/rules/insecure-crypto.json +302 -0
- package/dist/packages/crucible/rules/integer-overflow.json +35 -0
- package/dist/packages/crucible/rules/log-injection.json +33 -0
- package/dist/packages/crucible/rules/mass-assignment.json +112 -0
- package/dist/packages/crucible/rules/open-redirect.json +196 -0
- package/dist/packages/crucible/rules/path-traversal.json +422 -0
- package/dist/packages/crucible/rules/prototype-pollution.json +22 -0
- package/dist/packages/crucible/rules/sql-injection.json +597 -0
- package/dist/packages/crucible/rules/ssrf.json +557 -0
- package/dist/packages/crucible/rules/timing-attack.json +55 -0
- package/dist/packages/crucible/rules/unsafe-block.json +24 -0
- package/dist/packages/crucible/rules/xss.json +641 -0
- package/dist/packages/crucible/rules/xxe.json +66 -0
- package/dist/packages/crucible/rules/yaml-deserialization.json +22 -0
- package/dist/packages/crucible/rules/yaml-injection.json +22 -0
- package/dist/packages/scanner/executive-report.js +1 -1
- package/dist/packages/scanner/hallucination-detector.js +1 -1
- package/dist/packages/scanner/secret-scanner.js +1 -1
- package/package.json +7 -4
- package/dist/packages/crucible/seeds/python/seed-021 3.py +0 -37
- package/dist/packages/crucible/seeds/python/seed-022 3.py +0 -34
- package/dist/packages/crucible/seeds/python/seed-023 3.py +0 -37
- package/dist/packages/crucible/seeds/python/seed-024 3.py +0 -38
- package/dist/packages/crucible/seeds/python/seed-025 3.py +0 -40
- package/dist/packages/crucible/seeds/python/seed-026 3.py +0 -35
- package/dist/packages/crucible/seeds/python/seed-027 3.py +0 -35
- package/dist/packages/crucible/seeds/python/seed-028 3.py +0 -42
- package/dist/packages/crucible/seeds/python/seed-030 3.py +0 -37
- package/dist/packages/crucible/seeds/python/seed-031 3.py +0 -34
- package/dist/packages/crucible/seeds/python/seed-036 3.py +0 -33
- package/dist/packages/crucible/seeds/python/seed-037 3.py +0 -41
- package/dist/packages/crucible/seeds/python/seed-038 3.py +0 -33
- package/dist/packages/crucible/seeds/python/seed-039 3.py +0 -39
- package/dist/packages/crucible/seeds/python/seed-040 3.py +0 -39
- package/dist/packages/crucible/seeds/python/seed-041 3.py +0 -37
- package/dist/packages/crucible/seeds/python/seed-042 3.py +0 -38
- package/dist/packages/crucible/seeds/python/seed-043 3.py +0 -32
- package/dist/packages/crucible/seeds/python/seed-044 3.py +0 -38
- package/dist/packages/crucible/seeds/python/seed-045 3.py +0 -36
- package/dist/packages/crucible/seeds/python/seed-046 3.py +0 -33
- package/dist/packages/crucible/seeds/python/seed-047 3.py +0 -44
- package/dist/packages/crucible/seeds/python/seed-048 3.py +0 -35
- package/dist/packages/crucible/seeds/python/seed-049 3.py +0 -39
- package/dist/packages/crucible/seeds/python/seed-050 3.py +0 -39
- package/dist/packages/crucible/seeds/python/seed-051 3.py +0 -38
- package/dist/packages/crucible/seeds/python/seed-052 3.py +0 -41
- package/dist/packages/crucible/seeds/ruby/seed-001 3.rb +0 -15
- package/dist/packages/crucible/seeds/ruby/seed-002 3.rb +0 -22
- package/dist/packages/crucible/seeds/ruby/seed-003 3.rb +0 -25
- package/dist/packages/crucible/seeds/ruby/seed-004 3.rb +0 -17
- package/dist/packages/crucible/seeds/ruby/seed-005 3.rb +0 -21
- package/dist/packages/crucible/seeds/ruby/seed-006 3.rb +0 -17
- package/dist/packages/crucible/seeds/ruby/seed-007 3.rb +0 -16
- package/dist/packages/crucible/seeds/ruby/seed-008 3.rb +0 -18
- package/dist/packages/crucible/seeds/ruby/seed-009 3.rb +0 -20
- package/dist/packages/crucible/seeds/ruby/seed-010 3.rb +0 -24
- package/dist/packages/crucible/seeds/ruby/seed-011 3.rb +0 -21
- package/dist/packages/crucible/seeds/ruby/seed-012 3.rb +0 -22
- package/dist/packages/crucible/seeds/ruby/seed-013 3.rb +0 -21
- package/dist/packages/crucible/seeds/ruby/seed-014 3.rb +0 -16
- package/dist/packages/crucible/seeds/ruby/seed-015 3.rb +0 -18
- package/dist/packages/crucible/seeds/ruby/seed-016 3.rb +0 -17
- package/dist/packages/crucible/seeds/ruby/seed-017 3.rb +0 -25
- package/dist/packages/crucible/seeds/ruby/seed-018 3.rb +0 -23
- package/dist/packages/crucible/seeds/ruby/seed-019 3.rb +0 -20
- package/dist/packages/crucible/seeds/ruby/seed-020 3.rb +0 -17
- package/dist/packages/crucible/seeds/ruby/seed-021 3.rb +0 -20
- package/dist/packages/crucible/seeds/ruby/seed-022 3.rb +0 -21
- package/dist/packages/crucible/seeds/ruby/seed-023 3.rb +0 -19
- package/dist/packages/crucible/seeds/ruby/seed-024 3.rb +0 -17
- package/dist/packages/crucible/seeds/ruby/seed-025 3.rb +0 -17
- package/dist/packages/crucible/seeds/ruby/seed-026 3.rb +0 -18
- package/dist/packages/crucible/seeds/ruby/seed-027 3.rb +0 -21
- package/dist/packages/crucible/seeds/ruby/seed-028 3.rb +0 -22
- package/dist/packages/crucible/seeds/ruby/seed-029 3.rb +0 -19
- package/dist/packages/crucible/seeds/ruby/seed-030 3.rb +0 -20
- package/dist/packages/crucible/seeds/ruby/seed-031 3.rb +0 -17
- package/dist/packages/crucible/seeds/ruby/seed-032 3.rb +0 -22
- package/dist/packages/crucible/seeds/ruby/seed-033 3.rb +0 -18
- package/dist/packages/crucible/seeds/ruby/seed-034 3.rb +0 -19
- package/dist/packages/crucible/seeds/ruby/seed-035 3.rb +0 -19
- package/dist/packages/crucible/seeds/ruby/seed-036 3.rb +0 -18
- package/dist/packages/crucible/seeds/ruby/seed-037 3.rb +0 -21
- package/dist/packages/crucible/seeds/ruby/seed-038 3.rb +0 -24
- package/dist/packages/crucible/seeds/ruby/seed-039 3.rb +0 -24
- package/dist/packages/crucible/seeds/ruby/seed-040 3.rb +0 -22
- package/dist/packages/crucible/seeds/ruby/seed-041 3.rb +0 -23
- package/dist/packages/crucible/seeds/ruby/seed-042 3.rb +0 -25
- package/dist/packages/crucible/seeds/ruby/seed-043 3.rb +0 -23
- package/dist/packages/crucible/seeds/ruby/seed-044 3.rb +0 -16
- package/dist/packages/crucible/seeds/ruby/seed-045 3.rb +0 -22
- package/dist/packages/crucible/seeds/ruby/seed-046 3.rb +0 -27
- package/dist/packages/crucible/seeds/ruby/seed-047 3.rb +0 -26
- package/dist/packages/crucible/seeds/ruby/seed-048 3.rb +0 -24
- package/dist/packages/crucible/seeds/ruby/seed-049 3.rb +0 -20
- package/dist/packages/crucible/seeds/ruby/seed-050 3.rb +0 -27
- package/dist/packages/crucible/seeds/rust/seed-001 3.rs +0 -25
- package/dist/packages/crucible/seeds/rust/seed-002 3.rs +0 -20
- package/dist/packages/crucible/seeds/rust/seed-003 3.rs +0 -23
- package/dist/packages/crucible/seeds/rust/seed-004 3.rs +0 -21
- package/dist/packages/crucible/seeds/rust/seed-005 3.rs +0 -21
- package/dist/packages/crucible/seeds/rust/seed-006 3.rs +0 -24
- package/dist/packages/crucible/seeds/rust/seed-007 3.rs +0 -20
- package/dist/packages/crucible/seeds/rust/seed-008 3.rs +0 -19
- package/dist/packages/crucible/seeds/rust/seed-009 3.rs +0 -28
- package/dist/packages/crucible/seeds/rust/seed-010 3.rs +0 -28
- package/dist/packages/crucible/seeds/rust/seed-011 3.rs +0 -25
- package/dist/packages/crucible/seeds/rust/seed-012 3.rs +0 -31
- package/dist/packages/crucible/seeds/rust/seed-013 3.rs +0 -27
- package/dist/packages/crucible/seeds/rust/seed-014 3.rs +0 -30
- package/dist/packages/crucible/seeds/rust/seed-015 3.rs +0 -33
- package/dist/packages/crucible/seeds/rust/seed-016 3.rs +0 -22
- package/dist/packages/crucible/seeds/rust/seed-017 3.rs +0 -28
- package/dist/packages/crucible/seeds/rust/seed-018 3.rs +0 -21
- package/dist/packages/crucible/seeds/rust/seed-019 3.rs +0 -36
- package/dist/packages/crucible/seeds/rust/seed-020 3.rs +0 -27
- package/dist/packages/crucible/seeds/rust/seed-021 3.rs +0 -26
- package/dist/packages/crucible/seeds/rust/seed-022 3.rs +0 -23
- package/dist/packages/crucible/seeds/rust/seed-023 3.rs +0 -22
- package/dist/packages/crucible/seeds/rust/seed-024 3.rs +0 -24
- package/dist/packages/crucible/seeds/rust/seed-025 3.rs +0 -29
- package/dist/packages/crucible/seeds/rust/seed-026 3.rs +0 -23
- package/dist/packages/crucible/seeds/rust/seed-027 3.rs +0 -24
- package/dist/packages/crucible/seeds/rust/seed-028 3.rs +0 -25
- package/dist/packages/crucible/seeds/rust/seed-029 3.rs +0 -25
- package/dist/packages/crucible/seeds/rust/seed-030 3.rs +0 -30
- package/dist/packages/crucible/seeds/rust/seed-031 3.rs +0 -22
- package/dist/packages/crucible/seeds/rust/seed-032 3.rs +0 -25
- package/dist/packages/crucible/seeds/rust/seed-033 3.rs +0 -25
- package/dist/packages/crucible/seeds/rust/seed-034 3.rs +0 -20
- package/dist/packages/crucible/seeds/rust/seed-035 3.rs +0 -28
- package/dist/packages/crucible/seeds/rust/seed-036 3.rs +0 -26
- package/dist/packages/crucible/seeds/rust/seed-037 3.rs +0 -31
- package/dist/packages/crucible/seeds/rust/seed-038 3.rs +0 -25
- package/dist/packages/crucible/seeds/rust/seed-039 3.rs +0 -28
- package/dist/packages/crucible/seeds/rust/seed-040 3.rs +0 -27
- package/dist/packages/crucible/seeds/rust/seed-041 3.rs +0 -32
- package/dist/packages/crucible/seeds/rust/seed-042 3.rs +0 -27
- package/dist/packages/crucible/seeds/rust/seed-043 3.rs +0 -29
- package/dist/packages/crucible/seeds/rust/seed-044 3.rs +0 -25
- package/dist/packages/crucible/seeds/rust/seed-045 3.rs +0 -28
- package/dist/packages/crucible/seeds/rust/seed-046 3.rs +0 -25
- package/dist/packages/crucible/seeds/rust/seed-047 3.rs +0 -34
- package/dist/packages/crucible/seeds/rust/seed-048 3.rs +0 -21
- package/dist/packages/crucible/seeds/rust/seed-049 3.rs +0 -26
- package/dist/packages/crucible/seeds/rust/seed-050 3.rs +0 -23
- package/dist/packages/crucible/seeds/ts/seed-001 3.ts +0 -32
- package/dist/packages/crucible/seeds/ts/seed-002 3.ts +0 -34
- package/dist/packages/crucible/seeds/ts/seed-003 3.ts +0 -28
- package/dist/packages/crucible/seeds/ts/seed-004 3.ts +0 -34
- package/dist/packages/crucible/seeds/ts/seed-005 3.ts +0 -32
- package/dist/packages/crucible/seeds/ts/seed-006 3.ts +0 -31
- package/dist/packages/crucible/seeds/ts/seed-007 3.ts +0 -28
- package/dist/packages/crucible/seeds/ts/seed-008 3.ts +0 -40
- package/dist/packages/crucible/seeds/ts/seed-009 3.ts +0 -31
- package/dist/packages/crucible/seeds/ts/seed-010 3.ts +0 -33
- package/dist/packages/crucible/seeds/ts/seed-011 3.ts +0 -29
- package/dist/packages/crucible/seeds/ts/seed-012 3.ts +0 -34
- package/dist/packages/crucible/seeds/ts/seed-013 3.ts +0 -31
- package/dist/packages/crucible/seeds/ts/seed-014 3.ts +0 -36
- package/dist/packages/crucible/seeds/ts/seed-015 3.ts +0 -31
- package/dist/packages/crucible/seeds/ts/seed-016 3.ts +0 -37
- package/dist/packages/crucible/seeds/ts/seed-017 3.ts +0 -44
- package/dist/packages/crucible/seeds/ts/seed-018 3.ts +0 -33
- package/dist/packages/crucible/seeds/ts/seed-019 3.ts +0 -32
- package/dist/packages/crucible/seeds/ts/seed-020 3.ts +0 -33
- package/dist/packages/crucible/seeds/ts/seed-021 3.ts +0 -33
- package/dist/packages/crucible/seeds/ts/seed-022 3.ts +0 -34
- package/dist/packages/crucible/seeds/ts/seed-023 3.ts +0 -33
- package/dist/packages/crucible/seeds/ts/seed-024 3.ts +0 -35
- package/dist/packages/crucible/seeds/ts/seed-025 3.ts +0 -29
- package/dist/packages/crucible/seeds/ts/seed-026 3.ts +0 -36
- package/dist/packages/crucible/seeds/ts/seed-027 3.ts +0 -30
- package/dist/packages/crucible/seeds/ts/seed-028 3.ts +0 -32
- package/dist/packages/crucible/seeds/ts/seed-029 3.ts +0 -34
- package/dist/packages/crucible/seeds/ts/seed-030 3.ts +0 -37
- package/dist/packages/crucible/seeds/ts/seed-031 3.ts +0 -31
- package/dist/packages/crucible/seeds/ts/seed-032 3.ts +0 -32
- package/dist/packages/crucible/seeds/ts/seed-033 3.ts +0 -32
- package/dist/packages/crucible/seeds/ts/seed-034 3.ts +0 -34
- package/dist/packages/crucible/seeds/ts/seed-035 3.ts +0 -29
- package/dist/packages/crucible/seeds/ts/seed-036 3.ts +0 -34
- package/dist/packages/crucible/seeds/ts/seed-037 3.ts +0 -33
- package/dist/packages/crucible/seeds/ts/seed-038 3.ts +0 -29
- package/dist/packages/crucible/seeds/ts/seed-039 3.ts +0 -35
- package/dist/packages/crucible/seeds/ts/seed-040 3.ts +0 -31
- package/dist/packages/crucible/seeds/ts/seed-041 3.ts +0 -29
- package/dist/packages/crucible/seeds/ts/seed-042 3.ts +0 -33
- package/dist/packages/crucible/seeds/ts/seed-043 3.ts +0 -32
- package/dist/packages/crucible/seeds/ts/seed-044 3.ts +0 -36
- package/dist/packages/crucible/seeds/ts/seed-045 3.ts +0 -39
- package/dist/packages/crucible/seeds/ts/seed-046 3.ts +0 -41
- package/dist/packages/crucible/seeds/ts/seed-047 3.ts +0 -33
- package/dist/packages/crucible/seeds/ts/seed-048 3.ts +0 -33
- package/dist/packages/crucible/seeds/ts/seed-049 3.ts +0 -34
- package/dist/packages/crucible/seeds/ts/seed-050 3.ts +0 -41
- package/dist/packages/crucible/seeds/ts/seed-051 3.ts +0 -34
- package/dist/packages/crucible/seeds/ts/seed-052 3.ts +0 -36
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# [CRUCIBLE-SEED]
|
|
2
|
-
# category: yaml_deserialization
|
|
3
|
-
# severity: critical
|
|
4
|
-
# language: ruby
|
|
5
|
-
# expected: YAML.load with user-controlled input — allows arbitrary object instantiation
|
|
6
|
-
|
|
7
|
-
class ConfigController < ApplicationController
|
|
8
|
-
def import
|
|
9
|
-
config_data = params[:config]
|
|
10
|
-
config = YAML.load(config_data)
|
|
11
|
-
apply_config(config)
|
|
12
|
-
render json: { applied: true }
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def load_template(template_string)
|
|
16
|
-
YAML.load(template_string)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
|
|
21
|
-
def apply_config(cfg)
|
|
22
|
-
cfg.each { |k, v| Rails.application.config.send("#{k}=", v) rescue nil }
|
|
23
|
-
end
|
|
24
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# [CRUCIBLE-SEED]
|
|
2
|
-
# category: yaml_deserialization
|
|
3
|
-
# severity: critical
|
|
4
|
-
# language: ruby
|
|
5
|
-
# expected: YAML.load on file contents from user-supplied path — RCE via Psych gadget
|
|
6
|
-
|
|
7
|
-
def load_config_file(config_name)
|
|
8
|
-
path = "/etc/app/configs/#{config_name}.yml"
|
|
9
|
-
content = File.read(path)
|
|
10
|
-
YAML.load(content)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def parse_pipeline(pipeline_definition)
|
|
14
|
-
YAML.load(pipeline_definition)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def deserialize_job(job_yaml)
|
|
18
|
-
job = YAML.load(job_yaml)
|
|
19
|
-
job.merge(loaded_at: Time.now)
|
|
20
|
-
end
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# [CRUCIBLE-SEED]
|
|
2
|
-
# category: yaml_deserialization
|
|
3
|
-
# severity: critical
|
|
4
|
-
# language: ruby
|
|
5
|
-
# expected: YAML.load used in API endpoint — remote code execution via crafted payload
|
|
6
|
-
|
|
7
|
-
require 'sinatra'
|
|
8
|
-
require 'yaml'
|
|
9
|
-
|
|
10
|
-
post '/api/import' do
|
|
11
|
-
content_type :json
|
|
12
|
-
raw_body = request.body.read
|
|
13
|
-
data = YAML.load(raw_body)
|
|
14
|
-
process_import(data)
|
|
15
|
-
{ imported: data.keys.count }.to_json
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
post '/api/config/update' do
|
|
19
|
-
yaml_config = params[:yaml]
|
|
20
|
-
config = YAML.load(yaml_config)
|
|
21
|
-
config.each { |k, v| CONFIG[k] = v }
|
|
22
|
-
{ updated: true }.to_json
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def process_import(data)
|
|
26
|
-
data.each { |k, v| puts "#{k}: #{v}" }
|
|
27
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: hardcoded_secret
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Hardcoded AWS access key and secret in string literals
|
|
6
|
-
|
|
7
|
-
use aws_sdk_s3::Client;
|
|
8
|
-
|
|
9
|
-
const AWS_ACCESS_KEY_ID: &str = "AKIAIOSFODNN7EXAMPLE1";
|
|
10
|
-
const AWS_SECRET_ACCESS_KEY: &str = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";
|
|
11
|
-
const AWS_REGION: &str = "us-east-1";
|
|
12
|
-
const S3_BUCKET: &str = "my-production-bucket";
|
|
13
|
-
|
|
14
|
-
pub async fn create_s3_client() -> Client {
|
|
15
|
-
std::env::set_var("AWS_ACCESS_KEY_ID", AWS_ACCESS_KEY_ID);
|
|
16
|
-
std::env::set_var("AWS_SECRET_ACCESS_KEY", AWS_SECRET_ACCESS_KEY);
|
|
17
|
-
std::env::set_var("AWS_DEFAULT_REGION", AWS_REGION);
|
|
18
|
-
let config = aws_config::load_from_env().await;
|
|
19
|
-
Client::new(&config)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
pub fn get_bucket() -> &'static str {
|
|
23
|
-
println!("Using bucket: {} with key: {}", S3_BUCKET, AWS_ACCESS_KEY_ID);
|
|
24
|
-
S3_BUCKET
|
|
25
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: hardcoded_secret
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Hardcoded database password in connection string literal
|
|
6
|
-
|
|
7
|
-
use sqlx::PgPool;
|
|
8
|
-
|
|
9
|
-
const DB_URL: &str = "postgresql://appuser:Sup3rS3cr3tP@ssw0rd!@prod-db.example.com:5432/appdb";
|
|
10
|
-
const REDIS_URL: &str = "redis://:myR3d1sS3cret@redis.prod.example.com:6379/0";
|
|
11
|
-
const MONGO_URL: &str = "mongodb://admin:M0ng0P@ssw0rd@mongo.example.com:27017/proddb";
|
|
12
|
-
|
|
13
|
-
pub async fn connect_db() -> PgPool {
|
|
14
|
-
PgPool::connect(DB_URL).await.expect("Failed to connect to DB")
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
pub fn get_db_url() -> &'static str {
|
|
18
|
-
eprintln!("Connecting to: {}", DB_URL);
|
|
19
|
-
DB_URL
|
|
20
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: hardcoded_secret
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Hardcoded JWT secret key used to sign tokens
|
|
6
|
-
|
|
7
|
-
use hmac::{Hmac, Mac};
|
|
8
|
-
use sha2::Sha256;
|
|
9
|
-
|
|
10
|
-
const JWT_SECRET: &str = "mySuperSecretJWTSigningKey_2024_doNotCommit";
|
|
11
|
-
const JWT_EXPIRY_HOURS: u64 = 24;
|
|
12
|
-
const ADMIN_API_KEY: &str = "admin_sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
|
13
|
-
|
|
14
|
-
pub fn sign_token(payload: &str) -> Vec<u8> {
|
|
15
|
-
let mut mac = Hmac::<Sha256>::new_from_slice(JWT_SECRET.as_bytes())
|
|
16
|
-
.expect("HMAC key error");
|
|
17
|
-
mac.update(payload.as_bytes());
|
|
18
|
-
mac.finalize().into_bytes().to_vec()
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
pub fn verify_admin(key: &str) -> bool {
|
|
22
|
-
key == ADMIN_API_KEY
|
|
23
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: hardcoded_secret
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Hardcoded Stripe and payment processor API keys
|
|
6
|
-
|
|
7
|
-
const STRIPE_SECRET_KEY: &str = "sk_live_51HxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghij";
|
|
8
|
-
const STRIPE_WEBHOOK_SECRET: &str = "whsec_abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJ";
|
|
9
|
-
const PAYPAL_CLIENT_ID: &str = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVv";
|
|
10
|
-
const PAYPAL_CLIENT_SECRET: &str = "EeLlKkJjIiHhGgFfEeDdCcBbAa0123456789xyzabcdef";
|
|
11
|
-
|
|
12
|
-
pub fn get_stripe_headers() -> Vec<(&'static str, String)> {
|
|
13
|
-
vec![
|
|
14
|
-
("Authorization", format!("Bearer {}", STRIPE_SECRET_KEY)),
|
|
15
|
-
("Stripe-Version", "2023-10-16".to_string()),
|
|
16
|
-
]
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
pub fn validate_webhook(sig: &str) -> bool {
|
|
20
|
-
sig.starts_with(&STRIPE_WEBHOOK_SECRET[..10])
|
|
21
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: hardcoded_secret
|
|
3
|
-
// severity: high
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Hardcoded GitHub and GitLab personal access tokens
|
|
6
|
-
|
|
7
|
-
const GITHUB_TOKEN: &str = "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
|
8
|
-
const GITLAB_TOKEN: &str = "glpat-xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
|
9
|
-
const GITHUB_WEBHOOK_SECRET: &str = "github_webhook_secret_super_secret_value_here";
|
|
10
|
-
|
|
11
|
-
pub fn clone_repo(repo_url: &str) -> String {
|
|
12
|
-
format!(
|
|
13
|
-
"https://{}@github.com/{}",
|
|
14
|
-
GITHUB_TOKEN, repo_url
|
|
15
|
-
)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
pub async fn create_github_issue(owner: &str, repo: &str, title: &str) {
|
|
19
|
-
let url = format!("https://api.github.com/repos/{}/{}/issues", owner, repo);
|
|
20
|
-
println!("POST {} with token: {}", url, &GITHUB_TOKEN[..10]);
|
|
21
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: hardcoded_secret
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Hardcoded encryption key and IV in const literals
|
|
6
|
-
|
|
7
|
-
use aes::Aes256;
|
|
8
|
-
use cbc::cipher::KeyIvInit;
|
|
9
|
-
|
|
10
|
-
const ENCRYPTION_KEY: &[u8] = b"0123456789abcdef0123456789abcdef";
|
|
11
|
-
const ENCRYPTION_IV: &[u8] = b"abcdef0123456789";
|
|
12
|
-
const HMAC_KEY: &str = "super-secret-hmac-key-do-not-share";
|
|
13
|
-
|
|
14
|
-
pub fn create_cipher() -> cbc::Encryptor<Aes256> {
|
|
15
|
-
cbc::Encryptor::<Aes256>::new(
|
|
16
|
-
ENCRYPTION_KEY.into(),
|
|
17
|
-
ENCRYPTION_IV.into(),
|
|
18
|
-
)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
pub fn get_hmac_key() -> &'static [u8] {
|
|
22
|
-
println!("HMAC key length: {}", HMAC_KEY.len());
|
|
23
|
-
HMAC_KEY.as_bytes()
|
|
24
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: hardcoded_secret
|
|
3
|
-
// severity: high
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Hardcoded SMTP credentials and email service API key
|
|
6
|
-
|
|
7
|
-
const SMTP_HOST: &str = "smtp.sendgrid.net";
|
|
8
|
-
const SMTP_PORT: u16 = 587;
|
|
9
|
-
const SMTP_USERNAME: &str = "apikey";
|
|
10
|
-
const SMTP_PASSWORD: &str = "SG.xxxxxxxxxxxxxxxxxxxxxxxxxxxx.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
|
|
11
|
-
const FROM_EMAIL: &str = "noreply@example.com";
|
|
12
|
-
|
|
13
|
-
pub fn build_smtp_transport() -> String {
|
|
14
|
-
format!("{}://{}:{}@{}:{}", "smtp", SMTP_USERNAME, SMTP_PASSWORD, SMTP_HOST, SMTP_PORT)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
pub fn get_smtp_config() -> (String, String) {
|
|
18
|
-
println!("SMTP config loaded for: {}", SMTP_HOST);
|
|
19
|
-
(SMTP_USERNAME.to_string(), SMTP_PASSWORD.to_string())
|
|
20
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: hardcoded_secret
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Hardcoded Slack webhook URL and bot token
|
|
6
|
-
|
|
7
|
-
const SLACK_BOT_TOKEN: &str = "xoxb-1234567890-1234567890123-abcdefghijklmnopqrstuvwx";
|
|
8
|
-
const SLACK_SIGNING_SECRET: &str = "abcdef0123456789abcdef0123456789";
|
|
9
|
-
const SLACK_WEBHOOK_URL: &str = "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX";
|
|
10
|
-
|
|
11
|
-
pub async fn send_slack_message(channel: &str, text: &str) {
|
|
12
|
-
println!("Sending to {} via token: {}...", channel, &SLACK_BOT_TOKEN[..15]);
|
|
13
|
-
let client = reqwest::Client::new();
|
|
14
|
-
let _ = client
|
|
15
|
-
.post(SLACK_WEBHOOK_URL)
|
|
16
|
-
.json(&serde_json::json!({"text": text}))
|
|
17
|
-
.send()
|
|
18
|
-
.await;
|
|
19
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: unsafe_block
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Raw pointer dereference in unsafe block without bounds checking
|
|
6
|
-
|
|
7
|
-
pub fn read_from_raw_ptr(ptr: *const u8, offset: usize) -> u8 {
|
|
8
|
-
unsafe {
|
|
9
|
-
*ptr.add(offset)
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
pub fn write_to_raw_ptr(ptr: *mut u8, offset: usize, value: u8) {
|
|
14
|
-
unsafe {
|
|
15
|
-
*ptr.add(offset) = value;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
pub fn slice_from_raw(ptr: *const u8, len: usize) -> &'static [u8] {
|
|
20
|
-
unsafe {
|
|
21
|
-
std::slice::from_raw_parts(ptr, len)
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
pub fn null_ptr_deref_risk() -> u8 {
|
|
26
|
-
let ptr: *const u8 = 0x0 as *const u8;
|
|
27
|
-
unsafe { *ptr }
|
|
28
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: unsafe_block
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: std::mem::transmute misuse — reinterpret arbitrary bytes as typed reference
|
|
6
|
-
|
|
7
|
-
use std::mem;
|
|
8
|
-
|
|
9
|
-
pub fn transmute_bytes_to_struct<T>(bytes: &[u8]) -> &T {
|
|
10
|
-
unsafe {
|
|
11
|
-
mem::transmute(bytes.as_ptr())
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
pub fn reinterpret_as<S, D>(src: &S) -> &D {
|
|
16
|
-
unsafe { mem::transmute(src) }
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
pub fn bytes_to_u64(bytes: &[u8]) -> u64 {
|
|
20
|
-
unsafe {
|
|
21
|
-
let arr: [u8; 8] = *(bytes.as_ptr() as *const [u8; 8]);
|
|
22
|
-
mem::transmute(arr)
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
pub fn lifetime_extend<'a, 'b, T>(r: &'a T) -> &'b T {
|
|
27
|
-
unsafe { mem::transmute(r) }
|
|
28
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: unsafe_block
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Unsafe foreign function interface call without input validation
|
|
6
|
-
|
|
7
|
-
extern "C" {
|
|
8
|
-
fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8;
|
|
9
|
-
fn strlen(s: *const u8) -> usize;
|
|
10
|
-
fn strcpy(dest: *mut u8, src: *const u8) -> *mut u8;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
pub fn raw_memcpy(src: &[u8], dest: &mut Vec<u8>, n: usize) {
|
|
14
|
-
unsafe {
|
|
15
|
-
memcpy(dest.as_mut_ptr(), src.as_ptr(), n);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
pub fn get_c_strlen(s: *const u8) -> usize {
|
|
20
|
-
unsafe { strlen(s) }
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
pub fn unsafe_string_copy(src: *const u8, dest: *mut u8) {
|
|
24
|
-
unsafe { strcpy(dest, src); }
|
|
25
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: unsafe_block
|
|
3
|
-
// severity: high
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Vec::set_len called without initializing memory — UB
|
|
6
|
-
|
|
7
|
-
pub fn create_uninitialized_vec(size: usize) -> Vec<u8> {
|
|
8
|
-
let mut v = Vec::with_capacity(size);
|
|
9
|
-
unsafe {
|
|
10
|
-
v.set_len(size);
|
|
11
|
-
}
|
|
12
|
-
v
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
pub fn extend_vec_unsafely(v: &mut Vec<u8>, extra: usize) {
|
|
16
|
-
let new_len = v.len() + extra;
|
|
17
|
-
if v.capacity() < new_len {
|
|
18
|
-
v.reserve(extra);
|
|
19
|
-
}
|
|
20
|
-
unsafe {
|
|
21
|
-
v.set_len(new_len);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
pub fn read_uninitialized() -> u32 {
|
|
26
|
-
let x: u32;
|
|
27
|
-
unsafe {
|
|
28
|
-
x = std::mem::MaybeUninit::uninit().assume_init();
|
|
29
|
-
}
|
|
30
|
-
x
|
|
31
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: unsafe_block
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Mutable aliasing via raw pointers — violates Rust's aliasing rules
|
|
6
|
-
|
|
7
|
-
pub fn create_aliased_refs(data: &mut Vec<i32>) -> (*mut i32, *mut i32) {
|
|
8
|
-
let ptr1 = data.as_mut_ptr();
|
|
9
|
-
let ptr2 = data.as_mut_ptr();
|
|
10
|
-
(ptr1, ptr2)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
pub fn alias_write(v: &mut Vec<u8>) {
|
|
14
|
-
unsafe {
|
|
15
|
-
let p1 = v.as_mut_ptr();
|
|
16
|
-
let p2 = v.as_mut_ptr();
|
|
17
|
-
*p1 = 1;
|
|
18
|
-
*p2 = 2;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
pub fn double_free_risk(ptr: *mut u8, len: usize) {
|
|
23
|
-
unsafe {
|
|
24
|
-
let _v1 = Vec::from_raw_parts(ptr, len, len);
|
|
25
|
-
let _v2 = Vec::from_raw_parts(ptr, len, len);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: unsafe_block
|
|
3
|
-
// severity: high
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Use of unsafe to bypass borrow checker — potential use-after-free
|
|
6
|
-
|
|
7
|
-
use std::collections::HashMap;
|
|
8
|
-
|
|
9
|
-
pub struct Cache {
|
|
10
|
-
data: HashMap<String, String>,
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
impl Cache {
|
|
14
|
-
pub fn get_or_insert(&mut self, key: &str, value: String) -> &str {
|
|
15
|
-
if !self.data.contains_key(key) {
|
|
16
|
-
self.data.insert(key.to_string(), value);
|
|
17
|
-
}
|
|
18
|
-
unsafe {
|
|
19
|
-
let s: *const String = self.data.get(key).unwrap();
|
|
20
|
-
&*s
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
pub fn dangling_ref(&mut self) -> &str {
|
|
25
|
-
let s = String::from("temporary");
|
|
26
|
-
let ptr = s.as_str() as *const str;
|
|
27
|
-
drop(s);
|
|
28
|
-
unsafe { &*ptr }
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: unsafe_block
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Send/Sync implemented for non-thread-safe type via unsafe impl
|
|
6
|
-
|
|
7
|
-
use std::cell::Cell;
|
|
8
|
-
use std::rc::Rc;
|
|
9
|
-
|
|
10
|
-
pub struct SharedCounter {
|
|
11
|
-
value: Cell<i64>,
|
|
12
|
-
data: Rc<Vec<u8>>,
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
unsafe impl Send for SharedCounter {}
|
|
16
|
-
unsafe impl Sync for SharedCounter {}
|
|
17
|
-
|
|
18
|
-
impl SharedCounter {
|
|
19
|
-
pub fn new() -> Self {
|
|
20
|
-
SharedCounter {
|
|
21
|
-
value: Cell::new(0),
|
|
22
|
-
data: Rc::new(vec![]),
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
pub fn increment(&self) {
|
|
27
|
-
self.value.set(self.value.get() + 1);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
pub fn get(&self) -> i64 {
|
|
31
|
-
self.value.get()
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: command_injection
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Command::new with user-controlled string passed to shell
|
|
6
|
-
|
|
7
|
-
use std::process::Command;
|
|
8
|
-
|
|
9
|
-
pub fn ping_host(host: &str) -> String {
|
|
10
|
-
let output = Command::new("sh")
|
|
11
|
-
.arg("-c")
|
|
12
|
-
.arg(format!("ping -c 4 {}", host))
|
|
13
|
-
.output()
|
|
14
|
-
.expect("Failed to execute ping");
|
|
15
|
-
String::from_utf8_lossy(&output.stdout).to_string()
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
pub fn lookup_dns(domain: &str) -> String {
|
|
19
|
-
let cmd = format!("nslookup {}", domain);
|
|
20
|
-
let output = Command::new("/bin/sh").arg("-c").arg(cmd).output().unwrap();
|
|
21
|
-
String::from_utf8_lossy(&output.stdout).to_string()
|
|
22
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: command_injection
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: User input interpolated into shell command string passed to sh -c
|
|
6
|
-
|
|
7
|
-
use std::process::Command;
|
|
8
|
-
|
|
9
|
-
pub fn convert_image(input: &str, output: &str, width: &str, height: &str) -> bool {
|
|
10
|
-
let cmd = format!("convert {} -resize {}x{} {}", input, width, height, output);
|
|
11
|
-
Command::new("sh")
|
|
12
|
-
.arg("-c")
|
|
13
|
-
.arg(&cmd)
|
|
14
|
-
.status()
|
|
15
|
-
.map(|s| s.success())
|
|
16
|
-
.unwrap_or(false)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
pub fn compress_file(path: &str, dest: &str) -> i32 {
|
|
20
|
-
let cmd = format!("gzip -c {} > {}", path, dest);
|
|
21
|
-
Command::new("bash")
|
|
22
|
-
.arg("-c")
|
|
23
|
-
.arg(cmd)
|
|
24
|
-
.status()
|
|
25
|
-
.unwrap()
|
|
26
|
-
.code()
|
|
27
|
-
.unwrap_or(-1)
|
|
28
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: command_injection
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Actix-web handler passes query param to shell command
|
|
6
|
-
|
|
7
|
-
use actix_web::{web, HttpResponse};
|
|
8
|
-
use std::process::Command;
|
|
9
|
-
|
|
10
|
-
pub async fn run_report(query: web::Query<std::collections::HashMap<String, String>>) -> HttpResponse {
|
|
11
|
-
let report_type = query.get("type").map(|s| s.as_str()).unwrap_or("summary");
|
|
12
|
-
let date = query.get("date").unwrap_or(&String::new()).clone();
|
|
13
|
-
let cmd = format!("./scripts/generate_report.sh {} {}", report_type, date);
|
|
14
|
-
let output = Command::new("sh").arg("-c").arg(cmd).output().unwrap();
|
|
15
|
-
HttpResponse::Ok().body(String::from_utf8_lossy(&output.stdout).to_string())
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
pub async fn execute_tool(body: String) -> HttpResponse {
|
|
19
|
-
let output = Command::new("sh").arg("-c").arg(&body).output().unwrap();
|
|
20
|
-
HttpResponse::Ok().body(String::from_utf8_lossy(&output.stdout).to_string())
|
|
21
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: command_injection
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Git command constructed with user-supplied repository URL
|
|
6
|
-
|
|
7
|
-
use std::process::Command;
|
|
8
|
-
|
|
9
|
-
pub fn clone_repo(url: &str, dest: &str) -> bool {
|
|
10
|
-
let output = Command::new("git")
|
|
11
|
-
.arg("clone")
|
|
12
|
-
.arg(url)
|
|
13
|
-
.arg(dest)
|
|
14
|
-
.output();
|
|
15
|
-
|
|
16
|
-
match output {
|
|
17
|
-
Ok(o) => o.status.success(),
|
|
18
|
-
Err(_) => false,
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
pub fn git_pull(repo_path: &str, branch: &str) -> String {
|
|
23
|
-
let cmd = format!("cd {} && git pull origin {}", repo_path, branch);
|
|
24
|
-
let out = Command::new("sh").arg("-c").arg(cmd).output().unwrap();
|
|
25
|
-
String::from_utf8_lossy(&out.stdout).to_string()
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
pub fn run_git_hook(hook_name: &str, args: &str) -> i32 {
|
|
29
|
-
Command::new("sh")
|
|
30
|
-
.arg("-c")
|
|
31
|
-
.arg(format!(".git/hooks/{} {}", hook_name, args))
|
|
32
|
-
.status()
|
|
33
|
-
.unwrap()
|
|
34
|
-
.code()
|
|
35
|
-
.unwrap_or(-1)
|
|
36
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: command_injection
|
|
3
|
-
// severity: high
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: ffmpeg command built from user-controlled filenames without sanitization
|
|
6
|
-
|
|
7
|
-
use std::process::Command;
|
|
8
|
-
use std::path::Path;
|
|
9
|
-
|
|
10
|
-
pub fn transcode_video(input: &str, output: &str, codec: &str) -> std::io::Result<()> {
|
|
11
|
-
let cmd = format!("ffmpeg -i '{}' -c:v {} '{}'", input, codec, output);
|
|
12
|
-
Command::new("sh").arg("-c").arg(&cmd).status()?;
|
|
13
|
-
Ok(())
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
pub fn extract_audio(video_path: &str, audio_path: &str) -> bool {
|
|
17
|
-
let ffmpeg_cmd = format!(
|
|
18
|
-
"ffmpeg -i {} -vn -acodec copy {}",
|
|
19
|
-
video_path, audio_path
|
|
20
|
-
);
|
|
21
|
-
Command::new("/bin/sh")
|
|
22
|
-
.arg("-c")
|
|
23
|
-
.arg(ffmpeg_cmd)
|
|
24
|
-
.status()
|
|
25
|
-
.map(|s| s.success())
|
|
26
|
-
.unwrap_or(false)
|
|
27
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: command_injection
|
|
3
|
-
// severity: critical
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: eval-like dynamic command execution from deserialized task payload
|
|
6
|
-
|
|
7
|
-
use std::process::Command;
|
|
8
|
-
use serde::Deserialize;
|
|
9
|
-
|
|
10
|
-
#[derive(Deserialize)]
|
|
11
|
-
pub struct Task {
|
|
12
|
-
pub command: String,
|
|
13
|
-
pub args: Vec<String>,
|
|
14
|
-
pub shell: Option<bool>,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
pub fn execute_task(task: &Task) -> String {
|
|
18
|
-
if task.shell.unwrap_or(false) {
|
|
19
|
-
let full_cmd = format!("{} {}", task.command, task.args.join(" "));
|
|
20
|
-
let out = Command::new("sh").arg("-c").arg(&full_cmd).output().unwrap();
|
|
21
|
-
String::from_utf8_lossy(&out.stdout).to_string()
|
|
22
|
-
} else {
|
|
23
|
-
let out = Command::new(&task.command).args(&task.args).output().unwrap();
|
|
24
|
-
String::from_utf8_lossy(&out.stdout).to_string()
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// [CRUCIBLE-SEED]
|
|
2
|
-
// category: command_injection
|
|
3
|
-
// severity: high
|
|
4
|
-
// language: rust
|
|
5
|
-
// expected: Log archival uses user-supplied log name in shell command
|
|
6
|
-
|
|
7
|
-
use std::process::Command;
|
|
8
|
-
|
|
9
|
-
pub fn archive_logs(log_name: &str, destination: &str) -> bool {
|
|
10
|
-
let cmd = format!("tar -czf {}/{}.tar.gz /var/log/{}", destination, log_name, log_name);
|
|
11
|
-
Command::new("sh")
|
|
12
|
-
.arg("-c")
|
|
13
|
-
.arg(&cmd)
|
|
14
|
-
.status()
|
|
15
|
-
.map(|s| s.success())
|
|
16
|
-
.unwrap_or(false)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
pub fn rotate_log(service_name: &str) -> String {
|
|
20
|
-
let cmd = format!("logrotate -f /etc/logrotate.d/{}", service_name);
|
|
21
|
-
let output = Command::new("/bin/sh").arg("-c").arg(cmd).output().unwrap();
|
|
22
|
-
String::from_utf8_lossy(&output.stdout).to_string()
|
|
23
|
-
}
|