mirror of
https://github.com/getnora-io/nora.git
synced 2026-04-12 08:00:32 +00:00
security: add cargo-fuzz targets and ClusterFuzzLite config
Fuzz targets: - fuzz_validation: storage key, Docker name, digest, reference validators - fuzz_docker_manifest: Docker/OCI manifest media type detection Infrastructure: - lib.rs exposing validation module and docker_fuzz for fuzz harnesses - ClusterFuzzLite project config (libfuzzer + ASan)
This commit is contained in:
9
.clusterfuzzlite/Dockerfile
Normal file
9
.clusterfuzzlite/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
||||
FROM rust:1.87-slim
|
||||
|
||||
RUN apt-get update && apt-get install -y build-essential pkg-config && rm -rf /var/lib/apt/lists/*
|
||||
RUN cargo install cargo-fuzz
|
||||
|
||||
COPY . /src
|
||||
WORKDIR /src
|
||||
|
||||
RUN cd fuzz && cargo fuzz build 2>/dev/null || true
|
||||
5
.clusterfuzzlite/project.yaml
Normal file
5
.clusterfuzzlite/project.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
language: rust
|
||||
fuzzing_engines:
|
||||
- libfuzzer
|
||||
sanitizers:
|
||||
- address
|
||||
36
Cargo.lock
generated
36
Cargo.lock
generated
@@ -68,7 +68,7 @@ version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||
dependencies = [
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -79,7 +79,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -251,6 +251,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
"libc",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
@@ -1103,6 +1105,16 @@ version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.85"
|
||||
@@ -1131,6 +1143,16 @@ version = "0.2.182"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
|
||||
|
||||
[[package]]
|
||||
name = "libfuzzer-sys"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.12"
|
||||
@@ -1259,6 +1281,14 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nora-fuzz"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"libfuzzer-sys",
|
||||
"nora-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nora-registry"
|
||||
version = "0.2.31"
|
||||
@@ -1322,7 +1352,7 @@ version = "0.50.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||
dependencies = [
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -4,6 +4,7 @@ members = [
|
||||
"nora-registry",
|
||||
"nora-storage",
|
||||
"nora-cli",
|
||||
"fuzz",
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
|
||||
22
fuzz/Cargo.toml
Normal file
22
fuzz/Cargo.toml
Normal file
@@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "nora-fuzz"
|
||||
version = "0.0.0"
|
||||
publish = false
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata]
|
||||
cargo-fuzz = true
|
||||
|
||||
[dependencies]
|
||||
libfuzzer-sys = "0.4"
|
||||
nora-registry = { path = "../nora-registry" }
|
||||
|
||||
[[bin]]
|
||||
name = "fuzz_validation"
|
||||
path = "fuzz_targets/fuzz_validation.rs"
|
||||
doc = false
|
||||
|
||||
[[bin]]
|
||||
name = "fuzz_docker_manifest"
|
||||
path = "fuzz_targets/fuzz_docker_manifest.rs"
|
||||
doc = false
|
||||
8
fuzz/fuzz_targets/fuzz_docker_manifest.rs
Normal file
8
fuzz/fuzz_targets/fuzz_docker_manifest.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
#![no_main]
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
use nora_registry::docker_fuzz::detect_manifest_media_type;
|
||||
|
||||
fuzz_target!(|data: &[u8]| {
|
||||
// Fuzz Docker manifest parser — must never panic on any input
|
||||
let _ = detect_manifest_media_type(data);
|
||||
});
|
||||
13
fuzz/fuzz_targets/fuzz_validation.rs
Normal file
13
fuzz/fuzz_targets/fuzz_validation.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
#![no_main]
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
use nora_registry::validation::{
|
||||
validate_digest, validate_docker_name, validate_docker_reference, validate_storage_key,
|
||||
};
|
||||
|
||||
fuzz_target!(|data: &str| {
|
||||
// Fuzz all validators — they must never panic on any input
|
||||
let _ = validate_storage_key(data);
|
||||
let _ = validate_docker_name(data);
|
||||
let _ = validate_digest(data);
|
||||
let _ = validate_docker_reference(data);
|
||||
});
|
||||
@@ -10,6 +10,10 @@ description = "Cloud-Native Artifact Registry - Fast, lightweight, multi-protoco
|
||||
keywords = ["registry", "docker", "artifacts", "cloud-native", "devops"]
|
||||
categories = ["command-line-utilities", "development-tools", "web-programming"]
|
||||
|
||||
[lib]
|
||||
name = "nora_registry"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "nora"
|
||||
path = "src/main.rs"
|
||||
|
||||
28
nora-registry/src/lib.rs
Normal file
28
nora-registry/src/lib.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
//! NORA Registry — library interface for fuzzing and testing
|
||||
|
||||
pub mod validation;
|
||||
|
||||
/// Re-export Docker manifest parsing for fuzz targets
|
||||
pub mod docker_fuzz {
|
||||
pub fn detect_manifest_media_type(data: &[u8]) -> String {
|
||||
let Ok(value) = serde_json::from_slice::<serde_json::Value>(data) else {
|
||||
return "application/octet-stream".to_string();
|
||||
};
|
||||
if let Some(mt) = value.get("mediaType").and_then(|v| v.as_str()) {
|
||||
return mt.to_string();
|
||||
}
|
||||
if value.get("manifests").is_some() {
|
||||
return "application/vnd.oci.image.index.v1+json".to_string();
|
||||
}
|
||||
if value.get("schemaVersion").and_then(|v| v.as_i64()) == Some(2) {
|
||||
if value.get("layers").is_some() {
|
||||
return "application/vnd.oci.image.manifest.v1+json".to_string();
|
||||
}
|
||||
return "application/vnd.docker.distribution.manifest.v2+json".to_string();
|
||||
}
|
||||
if value.get("schemaVersion").and_then(|v| v.as_i64()) == Some(1) {
|
||||
return "application/vnd.docker.distribution.manifest.v1+json".to_string();
|
||||
}
|
||||
"application/vnd.docker.distribution.manifest.v2+json".to_string()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user