PR-SEC-1: Доп. харденинг и маскинг#454
Conversation
There was a problem hiding this comment.
Pull request overview
This PR strengthens the proxy’s anti-censorship and security posture by hardening fallback relaying behavior, improving pre-auth probe throttling robustness (including IPv6 normalization), and tightening TLS validation behavior to reduce side-channel surface area.
Changes:
- Adjust masking fallback relay to better handle client half-close / stalled directions while still allowing backend responses to reach the client.
- Improve pre-auth auth-probe tracking by normalizing IPv6 to /64 and adding bounded eviction when the tracking map is full.
- Refine data-plane payload reading to reduce copies, and extend security test coverage for these behaviors.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/proxy/middle_relay_security_tests.rs | Adds/updates tests for dedup cache churn and payload parsing correctness. |
| src/proxy/middle_relay.rs | Adds bounded eviction for desync dedup and refactors payload reads to use pooled buffers. |
| src/proxy/masking_security_tests.rs | Adds regression tests for fallback relaying under stall/half-close conditions. |
| src/proxy/masking.rs | Reworks relay loop to avoid early termination on client half-close by relaying both directions concurrently. |
| src/proxy/handshake_security_tests.rs | Updates and extends tests for auth-probe throttling/eviction and IPv6 /64 bucketing behavior. |
| src/proxy/handshake.rs | Implements IPv6 /64 normalization for auth-probe throttling and bounded eviction under full tracking state. |
| src/protocol/tls_security_tests.rs | Adds additional TLS parsing/validation tests (session_id length edges, version rejection, overflow guards). |
| src/protocol/tls.rs | Refactors TLS validation to avoid allocations in the secret-check loop (reducing timing side-channel risk). |
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
This PR hardens the proxy against censorship probing and resource-exhaustion patterns by improving masking fallback relay behavior, strengthening pre-auth throttling (especially for IPv6), and tightening TLS handshake validation to reduce side-channels—backed by expanded security regression tests.
Changes:
- Update mask fallback relaying to tolerate client TCP half-close while still allowing backend responses to flow back to the client.
- Strengthen pre-auth probe tracking by normalizing IPv6 peers to /64 buckets and adding bounded eviction under full-map pressure.
- Refactor data-plane frame reads and TLS validation for more predictable behavior, with new/expanded regression tests.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/proxy/middle_relay.rs |
Adds bounded eviction for desync dedup, refactors client payload reads to use BufferPool and adjusts emitted payload construction. |
src/proxy/middle_relay_security_tests.rs |
Adds regression tests for full-cache churn suppression and multiple read_client_payload framing/edge cases (including pool-return behavior). |
src/proxy/masking.rs |
Replaces tokio::select! relay loop with tokio::join! + tokio::io::copy to preserve backend→client flow during client half-close/stalls. |
src/proxy/masking_security_tests.rs |
Adds tests covering half-close behavior, one-direction stall behavior, and timeout-driven cancellation/drop of I/O endpoints. |
src/proxy/handshake.rs |
Implements IPv6 /64 normalization for auth-probe throttling and adds deterministic bounded eviction when the probe map is full. |
src/proxy/handshake_security_tests.rs |
Adds/updates tests for IPv6 bucketing, forced eviction behavior, and adjusts probe/throttle assertions/locking. |
src/protocol/tls.rs |
Refactors TLS validation to avoid per-match allocations in the secret-validation loop (reducing timing side-channel signal). |
src/protocol/tls_security_tests.rs |
Expands TLS tests for session_id length handling, record header version rejection, and ClientHello overflow/truncation edge cases. |
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Security hardening and data-plane performance updates across the proxy stack, focusing on masking fallback robustness, pre-auth throttling resilience, and constant-time TLS validation.
Changes:
- Fix masking relay behavior on client TCP half-close by running both directions to completion (bounded by a global timeout) and add regression tests.
- Harden pre-auth probe throttling by normalizing IPv6 addresses to /64 and adding bounded eviction to prevent fail-closed behavior under cache pressure (plus concurrency/IPv6 coverage in tests).
- Restore zero-copy payload handling in the middle relay hot path by switching client frame payloads to
PooledBufferand expanding related security/perf tests; remove TLS validation allocations from the secret-iteration loop.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/proxy/middle_relay.rs | Switch C2ME payloads to PooledBuffer, add dedup bounded eviction, and rework client payload reads to reuse pool buffers. |
| src/proxy/middle_relay_security_tests.rs | Update/enhance tests for pooled payload recycling, desync dedup churn behavior, and payload read edge cases. |
| src/proxy/masking.rs | Replace tokio::select! relay loop with tokio::join! + io::copy to preserve backend responses across half-close. |
| src/proxy/masking_security_tests.rs | Add regression tests for half-close behavior, stalled-direction behavior, and timeout cancellation dropping endpoints. |
| src/proxy/handshake.rs | Normalize IPv6 probe IPs to /64, add bounded eviction for auth-probe tracking, and introduce a warned-secrets test lock. |
| src/proxy/handshake_security_tests.rs | Add tests for IPv6 bucketing, forced eviction behavior, and concurrent probe update correctness. |
| src/protocol/tls.rs | Avoid per-secret allocations on HMAC match by deferring TlsValidation construction until after iteration. |
| src/protocol/tls_security_tests.rs | Expand TLS parsing/validation tests (prefix-length robustness, session_id length coverage, invalid record versions, overflow guards). |
You can also share your feedback on Copilot code review. Take the survey.
| .unwrap_or_else(|poisoned| poisoned.into_inner()); | ||
| clear_auth_probe_state_for_testing(); | ||
|
|
||
| let secret = [0x31u8; 16]; |
Check failure
Code scanning / CodeQL
Hard-coded cryptographic value Critical
| } | ||
|
|
||
| fn make_crypto_writer(writer: tokio::io::DuplexStream) -> CryptoWriter<tokio::io::DuplexStream> { | ||
| let key = [0u8; 32]; |
Check failure
Code scanning / CodeQL
Hard-coded cryptographic value Critical
|
|
||
| fn make_crypto_writer(writer: tokio::io::DuplexStream) -> CryptoWriter<tokio::io::DuplexStream> { | ||
| let key = [0u8; 32]; | ||
| let iv = 0u128; |
Check failure
Code scanning / CodeQL
Hard-coded cryptographic value Critical
There was a problem hiding this comment.
Pull request overview
Security hardening and anti-fingerprinting updates across the proxy data plane and handshake/TLS validation paths, with accompanying security-focused regression tests.
Changes:
- Updated masking fallback relay to avoid TCP half-close prematurely terminating backend→client responses (reduces proxy fingerprinting).
- Hardened pre-auth rate limiting against IPv6 /64 churn and cache-eviction attacks (normalized bucketing + forced eviction).
- Reworked middle relay client payload handling to use pooled buffers end-to-end (zero-copy/zero-allocation intent) and added extensive regression tests; adjusted TLS validation to avoid per-secret allocations in the match loop (timing side-channel reduction).
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/proxy/middle_relay_security_tests.rs | Adds regression tests for pooled-buffer lifecycle, desync dedup suppression, and frame parsing behaviors. |
| src/proxy/middle_relay.rs | Switches C→ME payloads to PooledBuffer, adds forced dedup eviction, and rewrites payload reads to fill pooled buffers directly. |
| src/proxy/masking_security_tests.rs | Adds tests covering half-close behavior, backend response preservation, and timeout-driven cancellation/drop semantics. |
| src/proxy/masking.rs | Replaces tokio::select! relay loop with concurrent tokio::join! + tokio::io::copy to preserve backend→client flow under client half-close/stall. |
| src/proxy/handshake_security_tests.rs | Expands tests for forced eviction, IPv6 bucketing, and concurrent failure accounting under load. |
| src/proxy/handshake.rs | Implements IPv6 /64 normalization, forced eviction when auth-probe map is full, and adds test-only lock for warned-secrets global state. |
| src/protocol/tls_security_tests.rs | Adds edge-case tests for session_id lengths, TLS record header version validation, and SNI/ALPN overflow handling. |
| src/protocol/tls.rs | Avoids per-secret allocations inside TLS secret validation loop by deferring TlsValidation construction. |
You can also share your feedback on Copilot code review. Take the survey.
| if current_cap < len { | ||
| payload.reserve(len - current_cap); |
| let mut payload = buffer_pool.get(); | ||
| payload.clear(); | ||
| let current_cap = payload.capacity(); | ||
| if current_cap < len { | ||
| payload.reserve(len - current_cap); | ||
| } | ||
| payload.resize(len, 0); | ||
| read_exact_with_timeout(client_reader, &mut payload[..len], frame_read_timeout).await?; |
| @@ -123,23 +156,27 @@ fn auth_probe_record_failure_with_state( | |||
| state.remove(&stale_key); | |||
| } | |||
| if state.len() >= AUTH_PROBE_TRACK_MAX_ENTRIES { | |||
| return; | |||
| if eviction_candidates.is_empty() { | |||
| return; | |||
| } | |||
| let idx = auth_probe_eviction_offset(peer_ip, now) % eviction_candidates.len(); | |||
| let evict_key = eviction_candidates[idx]; | |||
| state.remove(&evict_key); | |||
| } | |||
🛡 Основные изменения (Security & Anti-Censorship)
masking.rs)tokio::select!приводило к мгновенному прерыванию задачи чтения от маск-хоста, если клиент (например, HTTP-сканер цензора) отправлял запрос и сразу закрывал поток на запись (TCP Half-Close). Прокси рвал соединение до того, как Nginx успевал ответить, что является явным паттерном (fingerprint) прокси-сервера.tokio::join!(c2m, m2c). Теперь обе задачи корректно дожидаются завершения, позволяя fallback-серверу отправить легитимный HTTP-ответ сканеру. Защита от Slowloris обеспечивается глобальным таймаутомMASK_RELAY_TIMEOUT.handshake.rs)AUTH_PROBE_STATEопирался на точное совпадениеIpAddr. Атакующий с/64подсетью (18 квинтиллионов адресов) мог обходить блокировку, инкрементируя младшие биты.normalize_auth_probe_ip, которая маскирует все IPv6-адреса до/64перед записью в стейт пре-авторизации.handshake.rs,middle_relay.rs)DashMapдо лимита (AUTH_PROBE_TRACK_MAX_ENTRIES) и отсутствии протухших ключей в первых 1024 элементах, логика переходила в состояние fail-closed — новые IP переставали отслеживаться, позволяя беспрепятственно брутфорсить хэндшейк.eviction_candidate). Если stale-ключи не найдены, принудительно удаляется случайный элемент из отсканированного батча, сохраняя работоспособность защиты под DDoS-нагрузкой.tls.rs)user.clone(),session_id.clone()) при совпадении HMAC, что создавало микроскопический тайминг-оракул.TlsValidationвынесены за пределы цикла. Внутри цикла теперь сохраняется только легковесная ссылка(&String, u32). Валидация стала строго constant-time.⚡ Производительность и Архитектура (Data Plane)
middle_relay.rs)read_client_payloadпроисходила аллокацияBytesMutна куче и двойное копирование (extend_from_slice) для каждого MTProto-фрейма, что нарушало изоляцию Data Plane и приводило к деградации кэша CPU при высоком RPS.BufferPool. Изменение размера буфера (reserve/resize) и последующий вызовfreeze()позволяют передавать данные в Control Plane с нулевым копированием (zero-copy) и без дополнительных аллокаций.📋 Чек-лист (Checklist)
cargo check,cargo clippy).