CVE-2026-105133Discovered Published
AhsayCBS system password-check bypass
View patch bundle on GitHubFull published report
The reviewed summary below describes the scope of the fixture testing.
AhsayCBS system password-check bypass (CVE-2026-105133)
cve.now entry.
Eden terminates the HTTP connection to the affected product, evaluates a declarative policy and — in tier 2 — a separately compiled native Rust module under signed module authority, before any byte reaches the application. It does not patch the affected component; the vendor's fixed release remains the durable repair.
Status: live two-tier remediation recorded 2026-11-11 on the installed eden-product-release:1.103.0-single lab container (image sha256:809293e1f0b525ac04698d1fa8d7ffdc66cbee1ff690b082ba26b4d050f08416). Both bypass
branches of the fixture's login check are refused (the bypass parameter
and the missing-password form); ordinary credential checks pass.
The vulnerability
Improper authentication in the AhsayCBS system password check lets a remote attacker bypass login protections (v7-v10; earlier hotfixes incomplete). KEV-listed.
The Eden patch
Tier 1 — declarative policy (blunt, fail-closed): deny on the affected
route family — takes the whole surface offline, legitimate calls included.
Tier 2 — native module: gabriel_ahsayauth_v1, binary SHA-256 53cda7c4ed3e240a17da33acffb9a398242da24e8395ebaa7dff475062e52cb4
(source 0af7371242ff2ffda9edd57c4ba4559a29d07023fd5c2e4232bd52e38d0663c7). See the comparison table for what it keys, and the
honest scope for what it cannot.
Measured comparison (live, 2026-11-11)
| Probe | Baseline (unprotected) | Tier 1 | Tier 2 (module) |
|---|---|---|---|
| benign_login | 200 | 403 | 200 |
| attack_bypass_param | 200 (auth_bypass ×1) | 403 | 403 |
| attack_missing_password | 200 (auth_bypass ×1) | 403 | 403 |
| benign_no_user_param | 200 | 403 | 200 |
Performance trace (Eden telemetry, live 2026-11-11)
Measured with Eden's built-in request telemetry (gateway.request.baseline
spans, read back through /api/v1/analytics/telemetry?signal=traces), not
client wall-clock. Latency Eden introduces per remediation arm for this case:
| Arm | n | mean | p50 | p95 | min–max |
|---|---|---|---|---|---|
| Tier 1 — declarative policy, blocked request (403) | 15 | 29 µs | 24 µs | 51 µs | 18 µs–51 µs |
| Tier 2 — native module, benign passes through (200) | 22 | 447 µs | 426 µs | 591 µs | 356 µs–755 µs |
| Tier 2 — native module, attack refused (403) | 14 | 133 µs | 130 µs | 191 µs | 104 µs–191 µs |
Eden-added latency for the tier-2 remediation: benign requests complete in 447 µs mean (p50 426 µs, p95 591 µs) in-product, module evaluation included. Honest scope: lab fixtures on one host, fresh connection per measured request, warm requests only; module reactivated shards 2/2 with a fresh signed statement per measurement; spans carry the full authority lineage (module SHA-256, operation, publication). Not the EDEN-3640 performance qualification contract.
Tested against: eden-product-release:1.103.0-single (image sha256:809293e1f0b525ac…, build target
eden_service_single, tooling revision 81a0724a…). Raw data:
module2/telemetry-ab/ahsayauth-telemetry.json and module2/tier1-ab/ahsayauth-tier1.json.
Authority lifecycle and negatives
Driven through the full signed lifecycle (module2/evidence/ahsayauth-module.json):
enroll_key (Ed25519 public key), independent-host inventory, inspect
(bindings derived without mapping code), host approve, signed admit
(prepared, serving_now: false), activate — receipt serving_now: true,
applied_shards == expected_shards (2/2).
Negatives held: read-only inspect -> 403, tampered statement binding -> 400,
flipped signature bit -> 403. revoke failed the interlay closed (503,
nothing forwarded, zero backend effects) and a fresh host approval plus a
newly signed activation restored the module's behavior.
Honest scope
The fixture replicates the delivery shape and exploit prerequisite with a harmless marker effect; no real vendor component runs here. The module keys only the primitive listed above — bypass variants (encodings, alternate routes, crafted members other than the one keyed) are not bypass-tested and are out of scope; the rule is a lab-grade partial by construction. The vendor's fixed release remains the durable repair. Perf: request-path A/B not re-run for this batch (see README); activation telemetry measured ~0.14 s one-time load.
Cost record (per-CVE ledger)
$0.0789 USD (marginal session growth: 1,128,044 in + 46 out tokens, 3 turns; shared debug windows overlap).
Evidence appendix
- cve.now entry
- Raw evidence:
gabriel-2026-11-11/module2/evidence/ahsayauth-module.json - Deployment: installed
eden-product-release:1.103.0-singlelab container (imagesha256:809293e1f0b525ac04698d1fa8d7ffdc66cbee1ff690b082ba26b4d050f08416) - Skill: eden-vulnerability-remediation
Decision flow
This is the available form-byte predicate. It neither verifies a password nor establishes coverage of every Ahsay login path.
Complete native module source
The complete available source for gabriel_ahsayauth_v1 is reproduced below from the reviewed repository snapshot. The source SHA-256 is 0af7371242ff2ffda9edd57c4ba4559a29d07023fd5c2e4232bd52e38d0663c7. This identifies the source bytes, rather than independently proving the binary build or the recorded test results. The case’s experiment status and limitations still apply, including any failed import, partial coverage, or withdrawn claim. Original source comments are preserved verbatim.
//! Gabriel module: refuse the system-password-check bypass parameter (CVE-2026-105133 shape)
//!
//! CVE-2026-105133: improper authentication in the AhsayCBS system
//! password check lets a remote attacker bypass login protections.
//! This module refuses login bodies carrying the bypass primitive;
//! ordinary credential checks pass unchanged. no_std; no allocator, storage, background work or state.
#![no_std]
use core::mem::size_of;
use core::panic::PanicInfo;
use eden_gateway_remediation::message::{Availability, MessageInput};
use eden_gateway_remediation::module::{
ApiHeader, CONTINUE, Decision, EDIT, EditSink, Edits, Failure, ModuleOutput, NEED_MORE, REFUSE, RemediationModule,
};
use eden_gateway_remediation::native_http_v3::{self as http, Api, Input, Request};
/// Route prefix in scope.
const ROUTE: &[u8] = b"/cb5/loginModule";
/// The byte primitives this module refuses on that route.
static NEEDLES: [&[u8]; 1] = [b"sys_pwd_bypass"];
fn find(haystack: &[u8], needle: &[u8]) -> Option<usize> {
if haystack.len() < needle.len() || needle.is_empty() {
return None;
}
let mut i = 0usize;
while i + needle.len() <= haystack.len() {
let mut j = 0usize;
let mut same = true;
while j < needle.len() {
if haystack[i + j] != needle[j] {
same = false;
break;
}
j += 1;
}
if same {
return Some(i);
}
i += 1;
}
None
}
struct gabriel_ahsayauth_v1;
impl RemediationModule<Request<'_>> for gabriel_ahsayauth_v1 {
fn evaluate(&self, request: &Request<'_>, edits: &mut Edits<'_>) -> Result<Decision, Failure> {
let _ = edits;
let _ = match request.header_count() {
Availability::Ready(count) => count,
Availability::NeedMore => return Ok(Decision::NeedMore),
Availability::Unavailable => return Err(Failure),
};
let message = request.message();
let head = message.prefix();
let line_end = head.iter().position(|&b| b == b'\r').unwrap_or(head.len());
let request_line = &head[..line_end];
let path_at = request_line.iter().position(|&b| b == b' ').unwrap_or(request_line.len());
let target = &request_line[path_at + 1..];
if !target.starts_with(ROUTE) {
return Ok(Decision::Continue);
}
if !message.is_complete() {
return Ok(Decision::NeedMore);
}
let body_range = match request.body_range() {
Availability::Ready(range) => range,
Availability::NeedMore => return Ok(Decision::NeedMore),
Availability::Unavailable => return Err(Failure),
};
let body = match message.bytes(body_range)? {
Availability::Ready(bytes) => bytes,
Availability::NeedMore => return Ok(Decision::NeedMore),
Availability::Unavailable => return Err(Failure),
};
if NEEDLES.iter().any(|n| find(body, n).is_some()) {
return Ok(Decision::Refuse);
}
// The lab fixture models a second bypass branch: a system-user login
// form that omits the password field entirely. Presence of `sys_user=`
// without `sys_password=` is refused for the same reason as the
// marker form: the vulnerable check must not decide on markers.
if find(body, b"sys_user=").is_some() && find(body, b"sys_password=").is_none() {
return Ok(Decision::Refuse);
}
Ok(Decision::Continue)
}
}
static API: Api = Api {
header: ApiHeader { version: http::VERSION, table_size: size_of::<Api>() as u32 },
input_size: size_of::<Input>() as u32,
output_size: size_of::<ModuleOutput>() as u32,
sink_size: size_of::<EditSink>() as u32,
message_size: size_of::<MessageInput>() as u32,
state_bytes: 0,
capabilities: CONTINUE | REFUSE | NEED_MORE | EDIT,
required_inputs: 0,
evaluate: Some(evaluate),
};
unsafe extern "C" fn evaluate(input: *const Input, sink: *const EditSink, output: *mut ModuleOutput) -> i32 {
unsafe { http::invoke(&gabriel_ahsayauth_v1, input, sink, output) }
}
#[unsafe(no_mangle)]
pub extern "C" fn eden_http_remediation_v3() -> *const Api {
&API
}
#[panic_handler]
fn panic(_information: &PanicInfo<'_>) -> ! {
loop {
core::hint::spin_loop();
}
}
The recorded attack_bypass_param request returned 200 at baseline and 403 with the native module active. The case examines AhsayCBS system password-check bypass using an Eden gateway and a purpose-built fixture; it did not run the vendor application.
Decision flow
This is the available form-byte predicate. It neither verifies a password nor establishes coverage of every Ahsay login path.
The vulnerability and the test boundary
Improper authentication in the AhsayCBS system password check lets a remote attacker bypass login protections (v7-v10; earlier hotfixes incomplete). KEV-listed.
The application behavior in this experiment was modeled by a purpose-built fixture. Backend markers in the comparison record the fixture’s effects; they do not mean the vendor application was run.
The broad policy and its tradeoff
The first approach was a declarative deny on the affected route family. It removed access to that surface while active, including legitimate requests. The table below shows the effect on the particular controls included in the experiment.
The case record describes this action but does not retain the complete deployed settings or API request. The exact historical policy cannot be reconstructed from the available record.
The native module
Tier 2: native module: gabriel_ahsayauth_v1. See the comparison table for what it keys, and the honest scope for what it cannot.
The available source declares the following route or matching constants: const ROUTE: &[u8] = b"/cb5/loginModule"; static NEEDLES: [&[u8]; 1] = [b"sys_pwd_bypass"];. These are literal source declarations; the complete evaluation code below determines how they are used.
The evaluator extracts the request target from the request line and continues immediately when the target does not begin with its route prefix. For an in-scope request it waits for a complete message and obtains the body through the request API before evaluating the bytes. The refusal predicate checks whether any listed byte sequence appears in the body using a case-sensitive substring scan. Unlisted representations are not covered by that predicate.
Why the matching logic matters
The available code treats a sys_user= value without sys_password= as suspicious, and also checks a named bypass marker. Those conditions explain what was blocked: the rule is looking at request form bytes, not verifying a password against Ahsay's authentication database. An alternate form or route is outside the recorded comparison.
The before-and-after experiment
| Probe | Baseline (unprotected) | Tier 1 | Tier 2 (module) |
|---|---|---|---|
| benign_login | 200 | 403 | 200 |
| attack_bypass_param | 200 (auth_bypass ×1) | 403 | 403 |
| attack_missing_password | 200 (auth_bypass ×1) | 403 | 403 |
| benign_no_user_param | 200 | 403 | 200 |
For the attack_bypass_param probe, the recorded response changed from 200 at baseline to 403 with the module active. The baseline fixture also recorded auth_bypass; that marker is a simulated backend effect. The benign_login control returned 200 both before and with the module, while the broader tier-one deny returned 403 for that same control. This comparison describes the listed requests, not a complete test of application behavior.
The case records enrollment, inspection, host approval, signed admission and activation. The activation receipt reported 2/2 local shards serving. The recorded negative tests rejected unauthorized inspection, a changed binding and an invalid signature; revocation produced fail-closed 503 responses. These observations concern the local test, not production deployment.
What the evidence does and does not establish
This experiment covers the recorded fixture requests and the selected Eden boundary. It does not validate every request variant, a real vendor installation, other traffic paths, or production performance. Use the vendor’s fixed release and advisory for the durable repair.
Complete native module source
//! Gabriel module: refuse the system-password-check bypass parameter (CVE-2026-105133 shape)
//!
//! CVE-2026-105133: improper authentication in the AhsayCBS system
//! password check lets a remote attacker bypass login protections.
//! This module refuses login bodies carrying the bypass primitive;
//! ordinary credential checks pass unchanged. no_std; no allocator, storage, background work or state.
#![no_std]
use core::mem::size_of;
use core::panic::PanicInfo;
use eden_gateway_remediation::message::{Availability, MessageInput};
use eden_gateway_remediation::module::{
ApiHeader, CONTINUE, Decision, EDIT, EditSink, Edits, Failure, ModuleOutput, NEED_MORE, REFUSE, RemediationModule,
};
use eden_gateway_remediation::native_http_v3::{self as http, Api, Input, Request};
/// Route prefix in scope.
const ROUTE: &[u8] = b"/cb5/loginModule";
/// The byte primitives this module refuses on that route.
static NEEDLES: [&[u8]; 1] = [b"sys_pwd_bypass"];
fn find(haystack: &[u8], needle: &[u8]) -> Option<usize> {
if haystack.len() < needle.len() || needle.is_empty() {
return None;
}
let mut i = 0usize;
while i + needle.len() <= haystack.len() {
let mut j = 0usize;
let mut same = true;
while j < needle.len() {
if haystack[i + j] != needle[j] {
same = false;
break;
}
j += 1;
}
if same {
return Some(i);
}
i += 1;
}
None
}
struct gabriel_ahsayauth_v1;
impl RemediationModule<Request<'_>> for gabriel_ahsayauth_v1 {
fn evaluate(&self, request: &Request<'_>, edits: &mut Edits<'_>) -> Result<Decision, Failure> {
let _ = edits;
let _ = match request.header_count() {
Availability::Ready(count) => count,
Availability::NeedMore => return Ok(Decision::NeedMore),
Availability::Unavailable => return Err(Failure),
};
let message = request.message();
let head = message.prefix();
let line_end = head.iter().position(|&b| b == b'\r').unwrap_or(head.len());
let request_line = &head[..line_end];
let path_at = request_line.iter().position(|&b| b == b' ').unwrap_or(request_line.len());
let target = &request_line[path_at + 1..];
if !target.starts_with(ROUTE) {
return Ok(Decision::Continue);
}
if !message.is_complete() {
return Ok(Decision::NeedMore);
}
let body_range = match request.body_range() {
Availability::Ready(range) => range,
Availability::NeedMore => return Ok(Decision::NeedMore),
Availability::Unavailable => return Err(Failure),
};
let body = match message.bytes(body_range)? {
Availability::Ready(bytes) => bytes,
Availability::NeedMore => return Ok(Decision::NeedMore),
Availability::Unavailable => return Err(Failure),
};
if NEEDLES.iter().any(|n| find(body, n).is_some()) {
return Ok(Decision::Refuse);
}
// The lab fixture models a second bypass branch: a system-user login
// form that omits the password field entirely. Presence of `sys_user=`
// without `sys_password=` is refused for the same reason as the
// marker form: the vulnerable check must not decide on markers.
if find(body, b"sys_user=").is_some() && find(body, b"sys_password=").is_none() {
return Ok(Decision::Refuse);
}
Ok(Decision::Continue)
}
}
static API: Api = Api {
header: ApiHeader { version: http::VERSION, table_size: size_of::<Api>() as u32 },
input_size: size_of::<Input>() as u32,
output_size: size_of::<ModuleOutput>() as u32,
sink_size: size_of::<EditSink>() as u32,
message_size: size_of::<MessageInput>() as u32,
state_bytes: 0,
capabilities: CONTINUE | REFUSE | NEED_MORE | EDIT,
required_inputs: 0,
evaluate: Some(evaluate),
};
unsafe extern "C" fn evaluate(input: *const Input, sink: *const EditSink, output: *mut ModuleOutput) -> i32 {
unsafe { http::invoke(&gabriel_ahsayauth_v1, input, sink, output) }
}
#[unsafe(no_mangle)]
pub extern "C" fn eden_http_remediation_v3() -> *const Api {
&API
}
#[panic_handler]
fn panic(_information: &PanicInfo<'_>) -> ! {
loop {
core::hint::spin_loop();
}
}