Skip to content

Commit 310c52d

Browse files
Istrate Andrei-EduardIstrate Andrei-Eduard
authored andcommitted
Fixed security issue & replication issue after refactoring of security
1 parent 049e97f commit 310c52d

5 files changed

Lines changed: 194 additions & 98 deletions

File tree

CLAUDE.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Architectural Overview
6+
7+
The codebase appears to be a Rust project, heavily focused on network communication, security, storage, and tokenization, suggesting an application that handles data processing, potentially involving encryption or large data structures (indicated by `zstd` dependencies).
8+
9+
**Major Components & Interactions:**
10+
11+
1. **Network Layer (`src/network/`)**:
12+
* `broadcaster.rs` and `mod.rs` suggest a component responsible for broadcasting information across the system. This likely interfaces with other layers to disseminate data or state updates.
13+
2. **Security Layer (`src/security/`)**:
14+
* `authentication.rs` and `mod.rs` handle user or service authentication/authorization. This layer is critical for securing interactions with storage and network components. It interacts heavily with encryption mechanisms.
15+
3. **Storage Layer (`src/storage/`)**:
16+
* This is the data persistence core, featuring several modules:
17+
* `persistance.rs`: Likely handles the primary read/write operations for application data.
18+
* `engine.rs`: Suggests a core logic engine for data manipulation or state management within storage.
19+
* `subscription.rs`: Implies features related to managing subscriptions or access control over stored data.
20+
* `snapshoting.rs`: Points to functionality for creating snapshots of the storage state, crucial for backup or versioning.
21+
* `statistics.rs`: Suggests metrics collection related to storage operations.
22+
* `admin.*` (`admin.html`, `admin.rs`): Indicates an administrative interface or endpoint is present.
23+
4. **Tokenizer Layer (`src/tokenizer/`)**:
24+
* `engine.rs` and `mod.rs` form a dedicated component for text processing, likely involved in data preparation, compression, or encoding before storage or transmission.
25+
5. **Core / Utilities**:
26+
* The presence of `encryption.sh` and key files (`encryption.key`) indicates that cryptography is an integral part of the system's operation, likely used by the Security and Storage layers.
27+
* Files in the root like `Cargo.toml` and `.env` define project dependencies and environment configuration.
28+
29+
**Component Interaction Flow (Hypothetical):**
30+
31+
A typical flow might involve: A network request hits the **Network Layer**, which is validated by the **Security Layer**. If authorized, data is processed by the **Tokenizer Layer** (for encoding/compression) before being persisted via the **Storage Layer's engine**. The Storage Layer may use **Snapshotting** for state management and the Statistics module to track performance.
32+
33+
## Common Commands
34+
35+
### Build
36+
* **Command**: `cargo build`
37+
* **Notes**: Standard Rust compilation. Check `Cargo.toml` for specific target configurations or dependencies required by `zstd-sys`.
38+
39+
### Linting
40+
* **Command**: (Not explicitly found, but typically handled by `cargo clippy`)
41+
* **Notes**: Check for existing linting setup in a `.cargo/config.toml` file or look for integration with Clippy via scripts in `test.sh`.
42+
43+
### Testing
44+
* **Command**: `./test.sh` (or individual tests)
45+
* **Notes**: The presence of `test.sh` suggests an explicit script for running the test suite. Review files in `tests/` for component-specific test logic, especially around storage engine and network handlers.
46+
47+
### Running Application / Stress Testing
48+
* **Command**: `./stress.sh`
49+
* **Notes**: This script is designated for stress testing the system, likely targeting the Storage or Network layers under heavy load. Review this script to understand the specific load profile it imposes on the system components.
50+
51+
## Code Conventions & Specifics
52+
53+
* **Encryption**: Cryptographic operations are separated (via `encryption.sh` and key files), suggesting a clear separation of cryptographic concerns from business logic in storage/security modules.
54+
* **Data Structures**: The presence of `zstd` related files (`zdict.h`, `zstd.h`) suggests that data serialization or compression is a significant concern, likely implemented within the Tokenizer layer or Storage persistence routines.
55+
* **Administration**: The existence of `src/storage/admin.rs` and `src/storage/admin.html` indicates that system configuration or monitoring access points are designed into the storage module structure.

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ async fn main() -> std::io::Result<()> {
9393
// (Optionally) Ensure the default table exists in memory.
9494
state.store.entry("default".to_string()).or_default();
9595
start_snapshot_task(&state);
96+
9697

9798
// Initialize cluster data with dynamic membership.
9899
let mut initial_nodes = HashMap::new();

src/security/authentication.rs

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use sha2::{Digest, Sha256};
55
use hex;
66
use chrono::{Utc, Duration};
77
use std::collections::HashMap;
8+
use std::env;
89
use jsonwebtoken::{encode, Header, EncodingKey};
910

1011
use crate::storage::engine::{get_active_nodes, get_jwt_secret, get_replication_nodes, AppState, ClusterData, VersionedValue};
@@ -36,38 +37,43 @@ pub async fn access(
3637

3738
println!("Access request for user: {}", username);
3839

39-
// Internal replication requests bypass authentication
40-
if req.headers().contains_key("X-Internal-Request") {
41-
let provided_secret = match bincode::deserialize::<AccessToken>(&body) {
42-
Ok(t) => t.secret,
43-
Err(_) => return HttpResponse::BadRequest().finish(),
44-
};
4540

46-
println!("Processing internal replication request for {}", username);
41+
let cluster_secret = env::var("CLUSTER_SECRET").unwrap_or_else(|_| "default_secret".to_string());
4742

48-
// Simplified internal replication handling
49-
let auth_table = state.store.entry("auth".to_string()).or_default();
43+
// Internal replication requests - verify secret matching
44+
if let Some(internal_req) = req.headers().get("X-Internal-Request") {
45+
if internal_req.to_str().unwrap_or("") == cluster_secret {
46+
let provided_secret = match bincode::deserialize::<AccessToken>(&body) {
47+
Ok(t) => t.secret,
48+
Err(_) => return HttpResponse::BadRequest().finish(),
49+
};
5050

51-
// For internal requests, use the provided hash directly
52-
let mut value_map = HashMap::new();
53-
value_map.insert("secret".to_string(), json!(provided_secret));
51+
println!("Processing internal replication request for {}", username);
5452

55-
let user_header = req.headers().get("User")
56-
.and_then(|h| h.to_str().ok())
57-
.unwrap_or(&username);
53+
// Simplified internal replication handling
54+
let auth_table = state.store.entry("auth".to_string()).or_default();
5855

59-
let new_rec = VersionedValue::new(value_map, String::from(user_header), current_addr.get_ref().clone());
60-
auth_table.insert(username.clone(), new_rec.clone());
56+
// For internal requests, use the provided hash directly
57+
let mut value_map = HashMap::new();
58+
value_map.insert("secret".to_string(), json!(provided_secret));
6159

62-
println!("Successfully replicated user: {}", username);
60+
let user_header = req.headers().get("User")
61+
.and_then(|h| h.to_str().ok())
62+
.unwrap_or(&username);
6363

64-
sub_manager
65-
.notify(&"auth".to_string(), &username, KeyEvent::Updated(new_rec.clone()))
66-
.await;
64+
let new_rec = VersionedValue::new(value_map, String::from(user_header), current_addr.get_ref().clone());
65+
auth_table.insert(username.clone(), new_rec.clone());
66+
67+
println!("Successfully replicated user: {}", username);
6768

68-
return HttpResponse::Created().json(json!({
69-
"status": "User replicated"
70-
}));
69+
sub_manager
70+
.notify(&"auth".to_string(), &username, KeyEvent::Updated(new_rec.clone()))
71+
.await;
72+
73+
return HttpResponse::Created().json(json!({
74+
"status": "User replicated"
75+
}));
76+
}
7177
}
7278

7379
// Regular authentication flow
@@ -163,10 +169,11 @@ pub async fn access(
163169
println!("Sending replication request to: {}", url);
164170
// Create the payload with the same structure as AccessToken
165171
let payload = AccessToken { secret: secret_clone };
172+
let cluster_secret = env::var("CLUSTER_SECRET").unwrap_or_else(|_| "default_secret".to_string());
166173

167174
let result = client_clone
168175
.post(&url)
169-
.header("X-Internal-Request", "true")
176+
.header("X-Internal-Request", cluster_secret)
170177
.header("User", &username_clone)
171178
.header("Content-Type", "application/octet-stream")
172179
.body(bincode::serialize(&payload).unwrap())

src/storage/admin.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,13 @@ pub async fn admin_delete_record(
195195
let url = format!("http://{}/{}/key/{}", target, table_name, key_val);
196196
let client_clone = client.clone();
197197
let permit = <Arc<Semaphore> as Clone>::clone(&sem).acquire_owned().await.unwrap();
198+
let cluster_secret = env::var("CLUSTER_SECRET").unwrap_or_else(|_| "default_secret".to_string());
198199

199200
tokio::spawn(async move {
200201
let _permit = permit;
201202
let _ = client_clone
202203
.delete(&url)
203-
.header("X-Internal-Request", "true")
204+
.header("X-Internal-Request", cluster_secret)
204205
.timeout(std::time::Duration::from_secs(3))
205206
.send()
206207
.await;
@@ -244,8 +245,7 @@ async fn replicate_admin_change(
244245
let _permit = permit;
245246
let _ = cli
246247
.put(&url)
247-
.header("X-Internal-Request", "true")
248-
.header("SECRET", &secret_clone)
248+
.header("X-Internal-Request", &secret_clone)
249249
.json(&payload)
250250
.send()
251251
.await;

0 commit comments

Comments
 (0)