Severity
P0 — remote unauthenticated activity-injection on Teams + Viber adapters.
Files
crates/librefang-channels/src/teams.rs:299-323
crates/librefang-channels/src/viber.rs:335-354
Finding
The Teams POST /webhook parses the body as JSON and dispatches to
parse_teams_activity with no validation of the Authorization: Bearer <jwt>
token that Bot Framework Connector attaches (issuer, audience, signing key from
the OpenID metadata document). Anyone on the internet can POST forged Teams
Activity envelopes from arbitrary from.aadObjectId claiming any tenant,
bypassing the allowed_tenants filter (the field is attacker-supplied).
The Viber POST /webhook is even simpler — it parses JSON and dispatches with
no signature check at all (Viber requires X-Viber-Content-Signature HMAC-SHA256
with the auth token).
Evidence
// crates/librefang-channels/src/teams.rs:299-318
let app = axum::Router::new().route("/webhook", axum::routing::post({
...
move |body: axum::extract::Json<serde_json::Value>| {
...
if let Some(mut msg) = parse_teams_activity(&body, &app_id, &tenants) {
...
let _ = tx.send(msg).await;
}
axum::http::StatusCode::OK
Suggested Fix
- Teams: validate the inbound JWT against
https://login.botframework.com/v1/.well-known/openidconfiguration
(audience = app_id, issuer = https://api.botframework.com) before dispatch.
- Viber: HMAC-SHA256 the raw body with the Viber auth token and constant-time
compare against X-Viber-Content-Signature.
Severity
P0 — remote unauthenticated activity-injection on Teams + Viber adapters.
Files
crates/librefang-channels/src/teams.rs:299-323crates/librefang-channels/src/viber.rs:335-354Finding
The Teams
POST /webhookparses the body as JSON and dispatches toparse_teams_activitywith no validation of theAuthorization: Bearer <jwt>token that Bot Framework Connector attaches (issuer, audience, signing key from
the OpenID metadata document). Anyone on the internet can POST forged Teams
Activityenvelopes from arbitraryfrom.aadObjectIdclaiming anytenant,bypassing the
allowed_tenantsfilter (the field is attacker-supplied).The Viber
POST /webhookis even simpler — it parses JSON and dispatches withno signature check at all (Viber requires
X-Viber-Content-SignatureHMAC-SHA256with the auth token).
Evidence
Suggested Fix
https://login.botframework.com/v1/.well-known/openidconfiguration(audience =
app_id, issuer =https://api.botframework.com) before dispatch.compare against
X-Viber-Content-Signature.