Skip to content

Instantly share code, notes, and snippets.

@quantumproxies
Created August 21, 2026 12:42
Show Gist options
  • Select an option

  • Save quantumproxies/9974c4819b7a11c5cab63009b3e159f5 to your computer and use it in GitHub Desktop.

Select an option

Save quantumproxies/9974c4819b7a11c5cab63009b3e159f5 to your computer and use it in GitHub Desktop.
What your user-agent says about you, from the shell — plus why UA rotation alone does nothing https://quanticdata.io/tools/user-agent/
#!/usr/bin/env bash
# What a server actually sees, and why rotating the user-agent alone changes nothing.
#
# ./qd-ua.sh # your current UA, parsed
# ./qd-ua.sh "Mozilla/5.0 (…)" # parse any UA string
#
# Interactive lookup: https://quanticdata.io/tools/user-agent/
set -euo pipefail
ECHO_SERVICE="${ECHO_SERVICE:-https://httpbin.org}"
# The echo service is a convenience, not a dependency — everything below still
# works if it is down, which public echo endpoints regularly are.
echo_json() {
curl -sS -m 15 "$@" 2>/dev/null | jq . 2>/dev/null
}
UA="${1:-$(echo_json "$ECHO_SERVICE/user-agent" | jq -r '."user-agent" // empty' || true)}"
UA="${UA:-$(curl --version | head -1 | awk '{print "curl/"$2}')}"
echo "user-agent"
echo " $UA"
echo
echo "what a server reads out of it"
case "$UA" in
*Chrome/*) printf " browser Chrome %s\n" "$(sed -n 's/.*Chrome\/\([0-9.]*\).*/\1/p' <<<"$UA")" ;;
*Firefox/*) printf " browser Firefox %s\n" "$(sed -n 's/.*Firefox\/\([0-9.]*\).*/\1/p' <<<"$UA")" ;;
*Safari/*) echo " browser Safari" ;;
*curl/*) echo " browser curl — this is not a browser and every anti-bot vendor knows it" ;;
*python*|*requests*) echo " browser a Python client, announcing itself" ;;
*) echo " browser unrecognised" ;;
esac
case "$UA" in
*Windows*) echo " platform Windows" ;;
*Macintosh*|*"Mac OS X"*) echo " platform macOS" ;;
*Android*) echo " platform Android" ;;
*iPhone*|*iPad*) echo " platform iOS" ;;
*Linux*) echo " platform Linux" ;;
esac
case "$UA" in
*Mobile*) echo " form mobile" ;;
*) echo " form desktop" ;;
esac
echo
echo "everything else the server sees"
# `|| true` matters: under `set -e` a failed substitution would end the script.
HEADERS=$(echo_json "$ECHO_SERVICE/headers" -H "User-Agent: $UA") || true
if [ -n "$HEADERS" ]; then
printf '%s' "$HEADERS" | jq -r '.headers | to_entries[] | " \(.key): \(.value)"'
else
echo " ($ECHO_SERVICE is not answering — set ECHO_SERVICE to another echo endpoint)"
fi
cat <<'NOTE'
Rotating the user-agent alone accomplishes nothing. A server fingerprints the whole
request: header ORDER, the TLS/JA3 handshake, HTTP/2 settings frames, and whether the
sec-ch-ua hints agree with the UA string. A Chrome 140 user-agent arriving with
Python's TLS signature and no client hints is MORE distinctive than plain curl.
Coherence is the point:
- mobile exit IP -> mobile user-agent AND sec-ch-ua-mobile: ?1
- German exit -> Accept-Language starting with de
- Chrome UA -> Chrome's header order and TLS fingerprint
That last one is not something you can set from curl. It is what
https://quanticdata.io/web-scraping-api/ does for you server-side.
UA lookup: https://quanticdata.io/tools/user-agent/
NOTE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment