GET /.well-known/apple-app-site-association
iOS universal-links manifest (AASA). Apple is famously strict about the Content-Type, JSON validity, appID format (TEAMID.bundle.id), and the paths array. These modes break each of those expectations.
mode
wrong-content-type (default; served as text/html), malformed-json (invalid JSON), bad-appid (missing TEAMID prefix or wrong format), path-mismatch (empty paths array).
build a request:
expect: 200 OK. The wrong-content-type mode is the default because it's the most common real-world bug — Apple rejects AASA served as text/html. Other modes break JSON, appID format, or paths matching. X-Chaos-Aasa-Mode reflects the selection.
curl -i 'https://bots.catastrophic.io/.well-known/apple-app-site-association?mode=wrong-content-type'
import urllib.request
resp = urllib.request.urlopen("https://bots.catastrophic.io/.well-known/apple-app-site-association?mode=wrong-content-type")
print(resp.status, "Content-Type:", resp.headers["Content-Type"])
print(resp.headers["X-Chaos-Aasa-Mode"])
print(resp.read().decode())
const res = await fetch("https://bots.catastrophic.io/.well-known/apple-app-site-association?mode=wrong-content-type");
console.log(res.status, res.headers.get("content-type"));
console.log(res.headers.get("x-chaos-aasa-mode"));
console.log(await res.text());
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
resp, _ := http.Get("https://bots.catastrophic.io/.well-known/apple-app-site-association?mode=wrong-content-type")
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode, "Content-Type:", resp.Header.Get("Content-Type"))
fmt.Println(resp.Header.Get("X-Chaos-Aasa-Mode"))
fmt.Println(string(body))
}
fn main() -> Result<(), Box> {
let resp = reqwest::blocking::get("https://bots.catastrophic.io/.well-known/apple-app-site-association?mode=wrong-content-type")?;
println!("{} {:?}", resp.status(), resp.headers().get("content-type"));
println!("{:?}", resp.headers().get("x-chaos-aasa-mode"));
println!("{}", resp.text()?);
Ok(())
}
import java.net.URI;
import java.net.http.*;
public class BotsAasa {
public static void main(String[] args) throws Exception {
var client = HttpClient.newHttpClient();
var req = HttpRequest.newBuilder(URI.create("https://bots.catastrophic.io/.well-known/apple-app-site-association?mode=wrong-content-type")).build();
var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.statusCode() + " " +
resp.headers().firstValue("Content-Type").orElse(""));
System.out.println(resp.headers().firstValue("X-Chaos-Aasa-Mode").orElse(""));
System.out.println(resp.body());
}
}
using var client = new HttpClient();
var resp = await client.GetAsync("https://bots.catastrophic.io/.well-known/apple-app-site-association?mode=wrong-content-type");
Console.WriteLine($"{(int)resp.StatusCode} {resp.Content.Headers.ContentType}");
resp.Headers.TryGetValues("X-Chaos-Aasa-Mode", out var mode);
Console.WriteLine(mode?.FirstOrDefault());
Console.WriteLine(await resp.Content.ReadAsStringAsync());
require "net/http"
res = Net::HTTP.get_response(URI("https://bots.catastrophic.io/.well-known/apple-app-site-association?mode=wrong-content-type"))
puts "#{res.code} Content-Type: #{res['Content-Type']}"
puts res['X-Chaos-Aasa-Mode']
puts res.body
$r = Invoke-WebRequest -Uri 'https://bots.catastrophic.io/.well-known/apple-app-site-association?mode=wrong-content-type'
"Content-Type: $($r.Headers['Content-Type'])"
$r.Headers['X-Chaos-Aasa-Mode']
$r.Content
headers
body