Dangling Dns in Actix with Jwt Tokens
Dangling Dns in Actix with Jwt Tokens — how this specific combination creates or exposes the vulnerability
A dangling DNS reference occurs when an application stores a DNS name or host string that is later used to perform network requests, but the original DNS entry is removed or changed. In an Actix web service that relies on JWT tokens for authentication, this pattern becomes risky when the token validation or route construction logic resolves a hostname at configuration or runtime. If the hostname tied to a JWT issuer, audience claim, or a backend service URL is not validated after a DNS change, the application may route requests to an unintended or attacker-controlled endpoint.
Specifically, consider an Actix service that embeds a hostname inside the claims expected by a JWT verification routine. When the DNS record for that hostname is updated or removed, the application may continue to trust tokens issued for the old name, or it may resolve the hostname to a malicious server. This can lead to authorization bypass if the JWT’s iss (issuer) or aud (audience) are not strictly validated against a current, expected hostname. The combination of dangling DNS and JWT tokens thus exposes two complementary risks: (1) the application may accept tokens intended for a different service, and (2) it may make outbound HTTP calls to a server controlled by an attacker, enabling interception or replay of sensitive data.
During a middleBrick scan, the LLM/AI Security checks exercise active prompt injection probes and system prompt leakage detection, but the API surface tested includes endpoint behaviors such as service discovery and token validation paths. If an Actix endpoint dynamically resolves hostnames used in JWT validation or routes requests based on token metadata, inconsistent DNS records can result in unauthenticated access paths or SSRF-like behaviors. The scanner’s inventory management and unsafe consumption checks highlight cases where external references are not verified, and findings will include guidance to pin hostnames, validate claims strictly, and ensure DNS changes are coordinated with configuration updates.
Jwt Tokens-Specific Remediation in Actix — concrete code fixes
To remediate issues related to dangling DNS references when using JWT tokens in Actix, you should enforce strict validation of token claims, avoid runtime hostname resolution for security boundaries, and pin expected values in configuration. Below are concrete code examples demonstrating secure handling of JWT tokens in Actix with Rust.
First, define a configuration structure that explicitly sets expected issuer and audience values rather than relying on external DNS lookups:
use actix_web::{web, HttpResponse, Error};
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation, TokenData};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
sub: String,
iss: String,
aud: String,
exp: usize,
}
struct JwtConfig {
expected_issuer: String,
expected_audience: String,
decoding_key: DecodingKey,
}
fn validate_token(token: &str, config: &JwtConfig) -> Result, jsonwebtoken::errors::Error> {
let mut validation = Validation::new(Algorithm::HS256);
validation.set_issuer(&[&config.expected_issuer]);
validation.set_audience(&[&config.expected_audience]);
validation.validate_exp = true;
decode::(token, &config.decoding_key, &validation)
}
async fn protected_route(
token: web::Query>,
config: web::Data<JwtConfig>,
) -> Result<HttpResponse, Error> {
let token = match token.get("access_token") {
Some(t) => t,
None => return Ok(HttpResponse::BadRequest().body("Missing token")),
};
match validate_token(token, &config) {
Ok(token_data) => Ok(HttpResponse::Ok().json(token_data.claims)),
Err(_) => Ok(HttpResponse::Unauthorized().body("Invalid token")),
}
}
This approach eliminates dynamic issuer or audience resolution via DNS by embedding expected values directly in JwtConfig. The validation routine explicitly sets the issuer and audience, preventing acceptance of tokens issued for or intended to different services, which mitigates risks from dangling DNS entries.
Second, ensure that any outbound HTTP calls triggered by token data do not resolve hostnames at runtime. Instead, use static, vetted endpoints defined in configuration:
use reqwest::Client;
use std::sync::Arc;
struct ApiClient {
client: Client,
base_url: String,
}
impl ApiClient {
fn new(base_url: String) -> Self {
Self {
client: Client::new(),
base_url,
}
}
async fn call_service(&self, path: &str) -> Result<reqwest::Response, reqwest::Error> {
let url = format!("{}/{}", self.base_url, path);
self.client.get(&url).send().await
}
}
// Initialize once with a fixed, validated URL
let api_client = Arc::new(ApiClient::new("https://api.example.com".to_string()));
By storing a fixed base URL and avoiding runtime DNS-based endpoint selection, you prevent scenarios where a dangling DNS record could redirect sensitive requests. middleBrick findings for such setups will emphasize configuration integrity and input validation, aligning with OWASP API Top 10 and compliance mapping available in the dashboard.