Skip to content

Commit bf48b5b

Browse files
authored
Merge pull request #39 from bordumb/dev-securityHardening
chore: security hardening with tests and cleanup
2 parents 9dc78df + 5f23c1a commit bf48b5b

3 files changed

Lines changed: 19 additions & 3 deletions

File tree

crates/capsec-core/src/attenuate.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,17 @@ mod tests {
173173
assert!(scope.check("evil.com:8080").is_err());
174174
}
175175

176+
#[test]
177+
fn host_scope_rejects_domain_confusion() {
178+
let scope = HostScope::new(["api.example.com"]);
179+
// "api.example.com.evil.com" must NOT match "api.example.com"
180+
assert!(scope.check("api.example.com.evil.com").is_err());
181+
// But exact match and valid suffixes must still work
182+
assert!(scope.check("api.example.com").is_ok());
183+
assert!(scope.check("api.example.com:443").is_ok());
184+
assert!(scope.check("api.example.com/path").is_ok());
185+
}
186+
176187
#[test]
177188
fn dir_scope_rejects_traversal() {
178189
// Create a scope for a real directory

crates/capsec-core/src/has.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ macro_rules! impl_tuple_has_second {
154154
($single:ident) => {};
155155
}
156156

157+
// NOTE: Scaling cliff — these macros enumerate all concrete permission pairs.
158+
// Current: 10 types → 190 impls (100 first-element + 90 second-element).
159+
// Adding 3 more types → ~319 impls. 3-tuples are not supported at all.
160+
// This is a Rust coherence limitation (no generic impl without specialization).
161+
// Workaround: use #[capsec::context] structs instead of tuples for >2 permissions.
162+
// If the permission count grows significantly, consider generating impls via build script.
157163
impl_tuple_has_first!(
158164
[FsRead, FsWrite, FsAll, NetConnect, NetBind, NetAll, EnvRead, EnvWrite, Spawn, Ambient];
159165
[FsRead, FsWrite, FsAll, NetConnect, NetBind, NetAll, EnvRead, EnvWrite, Spawn, Ambient]

crates/capsec/examples/domain_wrapper.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,8 @@ fn process_and_save(config: &ConfigService, output: &OutputWriter) {
139139

140140
// ─── Entry point ─────────────────────────────────────────────────
141141

142-
fn main() {
143-
let root = capsec::root();
144-
142+
#[capsec::main]
143+
fn main(root: CapRoot) {
145144
// Inject capabilities at the domain wrapper boundary.
146145
// After this point, no function sees Cap<P> or Has<P>.
147146
let config = ConfigService::new("/tmp/capsec-demo/config", root.grant::<FsRead>());

0 commit comments

Comments
 (0)