[{"data":1,"prerenderedAt":4665},["ShallowReactive",2],{"navLinks":3,"sidebar_docs_navigation_\u002Fblog":124,"navigation":140,"navLinks_footer":181,"blog_data":211},{"id":4,"extension":5,"links":6,"meta":121,"stem":122,"__hash__":123},"navigationMenu\u002Fnavigation.json","json",[7,57,62,103],{"label":8,"icon":9,"nested":10,"children":11},"API Products","i-lucide-box",true,[12,17,22,27,32,37,42,47,52],{"label":13,"to":14,"description":15,"icon":16},"Full IP Lookup","\u002Ffull-ip-lookup","Enrich any IP with complete intelligence","i-lucide-globe",{"label":18,"to":19,"description":20,"icon":21},"Proxy & VPN Detection","\u002Fproxy-vpn-detection","Identify proxies and VPN networks","i-lucide-shield-alert",{"label":23,"to":24,"description":25,"icon":26},"Tor Exit Nodes","\u002Ftor-exit-nodes","Block Tor anonymity network traffic","i-lucide-eye-off",{"label":28,"to":29,"description":30,"icon":31},"Granular Geolocation","\u002Fgranular-geolocation","Highly accurate location mapping","i-lucide-map-pin",{"label":33,"to":34,"description":35,"icon":36},"Threat Scoring System","\u002Fthreat-scoring-system","Unified traffic risk score","i-lucide-activity",{"label":38,"to":39,"description":40,"icon":41},"ASN & Carrier Data","\u002Fasn-carrier-data","Identify autonomous systems","i-lucide-server",{"label":43,"to":44,"description":45,"icon":46},"Disposable Email Check","\u002Fdisposable-email-check","Detect temporary email domains","i-lucide-mail",{"label":48,"to":49,"description":50,"icon":51},"User Agent Parser","\u002Fuser-agent-bot-parser","Parse messy HTTP headers","i-lucide-bot",{"label":53,"to":54,"description":55,"icon":56},"Verified Bots","\u002Fverified-bots-crawlers","Identify legitimate search engine crawlers","i-lucide-check-circle",{"label":58,"to":59,"icon":60,"nested":61},"Pricing","\u002Fpricing","i-lucide-credit-card",false,{"label":63,"to":64,"icon":65,"nested":10,"children":66},"Docs","\u002Fdocs","i-lucide-book-open",[67,71,76,81,86,91,95,98],{"label":68,"to":64,"description":69,"icon":70},"Getting Started","Learn how to setup and use IP Shield","i-lucide-rocket",{"label":72,"to":73,"description":74,"icon":75},"All Endpoints","\u002Fdocs\u002Fendpoints\u002Femail-domain-check","Reference for all IP Shield REST API endpoints","i-lucide-plug",{"label":77,"to":78,"description":79,"icon":80},"Network API","\u002Fdocs\u002Fendpoints\u002Fnetwork","Network intelligence and routing data","i-lucide-network",{"label":82,"to":83,"description":84,"icon":85},"Summary API","\u002Fdocs\u002Fendpoints\u002Fsummary","Full IP intelligence summary","i-lucide-bar-chart-2",{"label":87,"to":88,"description":89,"icon":90},"Lookup IP API","\u002Fdocs\u002Fendpoints\u002Flookup-ip","Single IP data lookup","i-lucide-search",{"label":92,"to":93,"description":94,"icon":31},"Geo Check API","\u002Fdocs\u002Fendpoints\u002Fgeo-check","Check geographic location",{"label":96,"to":73,"description":97,"icon":46},"Email Domain Check API","Verify disposable email domains",{"label":99,"to":100,"description":101,"icon":102},"User Agent Check API","\u002Fdocs\u002Fendpoints\u002Fuser-agent-check","Detect malicious user agents","i-lucide-monitor",{"label":104,"icon":105,"nested":10,"children":106},"Resources","i-lucide-library",[107,112,117],{"label":108,"to":109,"icon":110,"description":111},"About Us","\u002Fabout","i-lucide-info","Learn more about IP Shield and our mission",{"label":113,"to":114,"icon":115,"description":116},"Blog","\u002Fblog","i-lucide-newspaper","Latest news, updates, and security articles",{"label":118,"to":119,"description":120,"icon":46},"Contact Us","\u002Fcontact","Get in touch with our support team",{},"navigation","OH-Zj4UmYqVQJC8Ts6f4KeKRzXJYi5trdK22JpX9Y0Q",[125],{"title":113,"path":114,"stem":126,"children":127,"page":61},"blog",[128,132,136],{"title":129,"path":130,"stem":131},"Combating Residential Proxies and VPNs in Modern Applications","\u002Fblog\u002Fcombating-residential-proxies","blog\u002Fcombating-residential-proxies",{"title":133,"path":134,"stem":135},"Ultimate Guide to Trading Automation & Volume Strategies","\u002Fblog\u002Fintroducing-ip-shield","blog\u002Fintroducing-ip-shield",{"title":137,"path":138,"stem":139},"The Evolution of Bot Management and User Agent Parsing","\u002Fblog\u002Fthe-evolution-of-bot-management","blog\u002Fthe-evolution-of-bot-management",[141],{"title":63,"path":64,"stem":142,"children":143},"docs",[144,147,164],{"title":145,"path":64,"stem":146},"Introduction","docs\u002Findex",{"title":148,"path":149,"stem":150,"children":151,"page":61},"Credit & Authorization","\u002Fdocs\u002Fcredits-and-auth","docs\u002Fcredits-and-auth",[152,156,160],{"title":153,"path":154,"stem":155},"Authentication","\u002Fdocs\u002Fcredits-and-auth\u002Fauth","docs\u002Fcredits-and-auth\u002Fauth",{"title":157,"path":158,"stem":159},"Credits & Usage","\u002Fdocs\u002Fcredits-and-auth\u002Fcredits-usage","docs\u002Fcredits-and-auth\u002Fcredits-usage",{"title":161,"path":162,"stem":163},"Rate Limits","\u002Fdocs\u002Fcredits-and-auth\u002Frate-limits","docs\u002Fcredits-and-auth\u002Frate-limits",{"title":165,"path":166,"stem":167,"children":168,"page":61},"API Endpoints","\u002Fdocs\u002Fendpoints","docs\u002Fendpoints",[169,171,173,175,177,179],{"title":96,"path":73,"stem":170},"docs\u002Fendpoints\u002Femail-domain-check",{"title":92,"path":93,"stem":172},"docs\u002Fendpoints\u002Fgeo-check",{"title":87,"path":88,"stem":174},"docs\u002Fendpoints\u002Flookup-ip",{"title":77,"path":78,"stem":176},"docs\u002Fendpoints\u002Fnetwork",{"title":82,"path":83,"stem":178},"docs\u002Fendpoints\u002Fsummary",{"title":99,"path":100,"stem":180},"docs\u002Fendpoints\u002Fuser-agent-check",{"id":4,"extension":5,"links":182,"meta":210,"stem":122,"__hash__":123},[183,194,195,205],{"label":8,"icon":9,"nested":10,"children":184},[185,186,187,188,189,190,191,192,193],{"label":13,"to":14,"description":15,"icon":16},{"label":18,"to":19,"description":20,"icon":21},{"label":23,"to":24,"description":25,"icon":26},{"label":28,"to":29,"description":30,"icon":31},{"label":33,"to":34,"description":35,"icon":36},{"label":38,"to":39,"description":40,"icon":41},{"label":43,"to":44,"description":45,"icon":46},{"label":48,"to":49,"description":50,"icon":51},{"label":53,"to":54,"description":55,"icon":56},{"label":58,"to":59,"icon":60,"nested":61},{"label":63,"to":64,"icon":65,"nested":10,"children":196},[197,198,199,200,201,202,203,204],{"label":68,"to":64,"description":69,"icon":70},{"label":72,"to":73,"description":74,"icon":75},{"label":77,"to":78,"description":79,"icon":80},{"label":82,"to":83,"description":84,"icon":85},{"label":87,"to":88,"description":89,"icon":90},{"label":92,"to":93,"description":94,"icon":31},{"label":96,"to":73,"description":97,"icon":46},{"label":99,"to":100,"description":101,"icon":102},{"label":104,"icon":105,"nested":10,"children":206},[207,208,209],{"label":108,"to":109,"icon":110,"description":111},{"label":113,"to":114,"icon":115,"description":116},{"label":118,"to":119,"description":120,"icon":46},{},{"landing":212,"posts":236},{"id":213,"title":113,"body":214,"description":230,"extension":231,"meta":232,"navigation":10,"path":114,"seo":233,"stem":234,"__hash__":235},"blog_landing\u002Fblog\u002Findex.md",{"type":215,"value":216,"toc":226},"minimark",[217,222],[218,219,221],"h1",{"id":220},"ip-shield-blog","IP Shield Blog",[223,224,225],"p",{},"Welcome to the IP Shield blog. Here you will find the latest news, updates, tips, and tutorials to help you get the most out of your trading experience.",{"title":227,"searchDepth":228,"depth":228,"links":229},"",2,[],"Latest news, updates, and tutorials from the IP Shield.","md",{},{"title":113,"description":230},"blog\u002Findex","Bh76HS7VWhJTcKrzrDmCbj0-Xk6IIDnTmFHEqKIMOI8",[237,3082,4588],{"id":238,"title":129,"author":239,"authorGithub":240,"authorGithubUserName":241,"authorImg":242,"body":243,"date":3067,"description":3068,"extension":231,"featured":10,"icon":3069,"image":3070,"meta":3071,"navigation":10,"path":130,"rawbody":3072,"readingTime":3073,"seo":3074,"stem":131,"tags":3075,"__hash__":3081},"blog\u002Fblog\u002Fcombating-residential-proxies.md","Sergio","https:\u002F\u002Fgithub.com\u002FSergo706","Sergo706","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F187537278?v=4",{"type":215,"value":244,"toc":3039},[245,248,251,254,260,265,268,273,276,305,309,312,315,318,394,398,401,405,408,412,415,419,422,428,432,435,438,442,445,448,451,455,458,462,465,468,1529,1539,1543,1546,1983,1986,2258,2262,2265,2888,2894,2898,2905,2915,2919,2944,2955,2959,2962,2966,2969,2972,2976,2979,2982,2986,2989,2992,3019,3022,3026,3029,3032,3035],[218,246,129],{"id":247},"combating-residential-proxies-and-vpns-in-modern-applications",[223,249,250],{},"Protecting modern web applications requires significantly more than just checking an IP address against a static blocklist. Attackers constantly evolve their techniques. They leverage residential proxies and commercial VPN networks to mask their true origin and bypass rate limits.",[223,252,253],{},"The security industry faces a continuous and escalating challenge. Traditional security layers struggle to differentiate between a legitimate user logging in from their home internet and an automated script routing traffic through a compromised residential proxy network. This comprehensive guide explores the mechanics of residential proxies, the economics driving their use, and the technical strategies you must implement to defend your infrastructure.",[255,256,257],"note",{},[223,258,259],{},"A residential proxy routes traffic through an actual residential internet connection. This makes the traffic appear as though it originates from a standard home user rather than a datacenter, effectively bypassing traditional IP-based filtering.",[261,262,264],"h2",{"id":263},"the-anatomy-of-the-threat-landscape","The Anatomy of the Threat Landscape",[223,266,267],{},"To effectively defend against a threat, you must first understand how it operates at a fundamental level. The proxy ecosystem is vast, complex, and highly commercialized.",[269,270,272],"h3",{"id":271},"types-of-ip-addresses-used-by-attackers","Types of IP Addresses Used by Attackers",[223,274,275],{},"Attackers utilize several categories of IP addresses, each with distinct characteristics and risk profiles:",[277,278,279,287,293,299],"ol",{},[280,281,282,286],"li",{},[283,284,285],"strong",{},"Datacenter IPs",": These are IP addresses assigned to massive server farms and cloud providers like AWS, Google Cloud, DigitalOcean, and Hetzner. They are cheap, fast, and highly available. However, they are also incredibly easy to detect and block. Legitimate consumers rarely browse the web from an AWS data center.",[280,288,289,292],{},[283,290,291],{},"Commercial VPNs",": Services like NordVPN, ExpressVPN, and ProtonVPN route user traffic through shared egress IPs. While often used by privacy-conscious individuals, attackers heavily abuse them to mask their geographic location and true identity.",[280,294,295,298],{},[283,296,297],{},"Residential Proxies",": These IPs belong to standard Internet Service Providers (ISPs) like Comcast, AT&T, and BT. They are attached to actual residential homes. Traffic originating from these IPs carries an inherently high reputation.",[280,300,301,304],{},[283,302,303],{},"Mobile Proxies",": Similar to residential proxies, but the IPs belong to cellular carriers (e.g., Verizon, T-Mobile, Vodafone). These are the most difficult to block because thousands of legitimate users often share a single mobile IP via Carrier-Grade NAT (CGNAT).",[269,306,308],{"id":307},"how-residential-proxy-networks-are-built","How Residential Proxy Networks are Built",[223,310,311],{},"Understanding how attackers acquire residential IPs is critical. They do not purchase these directly from ISPs. Instead, residential proxy networks are formed through various methods, many of which reside in an ethical gray area or are outright illegal.",[223,313,314],{},"Some networks operate legitimately by offering users free software or premium features in exchange for sharing their idle bandwidth. Users agree to the terms of service, effectively turning their home router or computer into an exit node for the proxy network.",[223,316,317],{},"However, many residential proxy networks are botnets built via malware. Attackers infect thousands of IoT devices, smart TVs, home routers, and personal computers. They then sell access to this compromised network to other malicious actors on the dark web or through shady proxy reselling platforms.",[319,320,324],"pre",{"className":321,"code":322,"language":323,"meta":227,"style":227},"language-mermaid shiki shiki-themes light-plus light-plus dracula","graph TD\n    A[Attacker \u002F Scraper Script] -->|Routes Traffic| B(Proxy Network Controller)\n    B --> C[Infected Smart TV]\n    B --> D[Compromised Router]\n    B --> E[User running 'Free' VPN Extension]\n    C -->|Requests| F[Your Application]\n    D -->|Requests| F[Your Application]\n    E -->|Requests| F[Your Application]\n    \n    style A fill:#ffcccc,stroke:#ff0000,stroke-width:2px\n    style F fill:#ccffcc,stroke:#00aa00,stroke-width:2px\n","mermaid",[325,326,327,335,340,346,352,358,364,370,376,382,388],"code",{"__ignoreMap":227},[328,329,332],"span",{"class":330,"line":331},"line",1,[328,333,334],{},"graph TD\n",[328,336,337],{"class":330,"line":228},[328,338,339],{},"    A[Attacker \u002F Scraper Script] -->|Routes Traffic| B(Proxy Network Controller)\n",[328,341,343],{"class":330,"line":342},3,[328,344,345],{},"    B --> C[Infected Smart TV]\n",[328,347,349],{"class":330,"line":348},4,[328,350,351],{},"    B --> D[Compromised Router]\n",[328,353,355],{"class":330,"line":354},5,[328,356,357],{},"    B --> E[User running 'Free' VPN Extension]\n",[328,359,361],{"class":330,"line":360},6,[328,362,363],{},"    C -->|Requests| F[Your Application]\n",[328,365,367],{"class":330,"line":366},7,[328,368,369],{},"    D -->|Requests| F[Your Application]\n",[328,371,373],{"class":330,"line":372},8,[328,374,375],{},"    E -->|Requests| F[Your Application]\n",[328,377,379],{"class":330,"line":378},9,[328,380,381],{},"    \n",[328,383,385],{"class":330,"line":384},10,[328,386,387],{},"    style A fill:#ffcccc,stroke:#ff0000,stroke-width:2px\n",[328,389,391],{"class":330,"line":390},11,[328,392,393],{},"    style F fill:#ccffcc,stroke:#00aa00,stroke-width:2px\n",[261,395,397],{"id":396},"the-economic-incentives","The Economic Incentives",[223,399,400],{},"Why do attackers go through the trouble and expense of using residential proxies? The answer lies in the massive return on investment (ROI) available in digital fraud.",[269,402,404],{"id":403},"account-takeover-ato-and-credential-stuffing","Account Takeover (ATO) and Credential Stuffing",[223,406,407],{},"Attackers purchase massive databases of leaked usernames and passwords. They write scripts to test these credentials against your login endpoints. If they use a single datacenter IP, your rate-limiting rules block them after a few dozen attempts. By routing the requests through thousands of residential proxies, they stay under the rate-limit thresholds and blend in with regular login traffic.",[269,409,411],{"id":410},"e-commerce-scalping-and-inventory-hoarding","E-commerce Scalping and Inventory Hoarding",[223,413,414],{},"When highly anticipated products drop—such as limited-edition sneakers, concert tickets, or next-generation gaming consoles—scalping bots swarm the site. They use residential proxies to bypass per-IP purchase limits. Scalpers can generate millions of dollars in secondary market profits, easily justifying the cost of premium residential proxy subscriptions.",[269,416,418],{"id":417},"payment-fraud-and-carding","Payment Fraud and Carding",[223,420,421],{},"Attackers use stolen credit card information to purchase digital goods or physical items. They use residential proxies located in the same city or zip code as the stolen credit card's billing address. This geographic consistency easily bypasses simplistic fraud detection systems that flag long-distance mismatches.",[423,424,425],"warning",{},[223,426,427],{},"Blocking entire ISPs or geographic regions to stop these attacks often leads to unacceptable false positive rates. You lock out genuine customers while attempting to stop a handful of malicious actors.",[261,429,431],{"id":430},"utilizing-deep-network-intelligence","Utilizing Deep Network Intelligence",[223,433,434],{},"IP Shield resolves this challenge by providing deep network intelligence on every request. The platform analyzes the IP address and returns a comprehensive metadata payload. This includes VPN detection flags, proxy network associations, Tor exit node identification, and precise ASN details.",[223,436,437],{},"You use this intelligence to introduce adaptive friction into your user flows. Rather than outright blocking an IP, you challenge high-risk connections with a CAPTCHA, require multi-factor authentication (MFA), or flag the account for manual review.",[269,439,441],{"id":440},"the-role-of-the-autonomous-system-number-asn","The Role of the Autonomous System Number (ASN)",[223,443,444],{},"The Internet is a network of networks. An Autonomous System (AS) is a large network or group of networks that has a unified routing policy. Every AS is assigned an Autonomous System Number (ASN).",[223,446,447],{},"By evaluating the ASN, you determine the organization responsible for the IP address. If the ASN belongs to a known consumer ISP like \"Comcast Cable Communications,\" the traffic is likely residential. If the ASN belongs to \"DigitalOcean, LLC,\" the traffic is from a datacenter.",[223,449,450],{},"IP Shield provides the ASN data instantly. You filter traffic based on the network type. For example, you easily block all traffic originating from hosting providers on your consumer-facing login routes, while allowing cellular and residential networks to pass unhindered.",[261,452,454],{"id":453},"implementing-the-defense-in-code","Implementing the Defense in Code",[223,456,457],{},"Defending against residential proxies demands a dynamic security posture. You must integrate real-time intelligence into your edge compute layer or application backend. By doing so, you automatically filter out the noise and focus your resources on serving legitimate users.",[269,459,461],{"id":460},"nuxt-3-and-h3-implementation","Nuxt 3 and h3 Implementation",[223,463,464],{},"If you are using the modern Nuxt 3 stack, you integrate the IP Shield Network API directly into your server API routes or middleware. You evaluate the IP address before processing sensitive actions like logins, registrations, or checkouts.",[223,466,467],{},"Here is an extensive example of how you build a robust, production-ready login handler using Nuxt 3, handling edge cases, proxy headers, and implementing adaptive friction.",[319,469,474],{"className":470,"code":471,"filename":472,"language":473,"meta":227,"style":227},"language-typescript shiki shiki-themes light-plus light-plus dracula","import { IPShield } from '@ip-shield\u002Fsdk';\nimport { sendError, setResponseStatus, createError } from 'h3';\n\n\u002F\u002F Initialize the IP Shield SDK with your secure API key\nconst shield = new IPShield(process.env.IP_SHIELD_API_KEY);\n\nexport default defineEventHandler(async (event) => {\n  \u002F\u002F 1. Safely extract the client IP address\n  \u002F\u002F When behind a CDN or Load Balancer (Cloudflare, AWS ALB), the direct \n  \u002F\u002F connection IP belongs to the CDN. We must inspect the X-Forwarded-For header.\n  const ip = getRequestIP(event, { xForwardedFor: true });\n  \n  if (!ip) {\n    throw createError({\n      statusCode: 400,\n      statusMessage: 'Unable to determine client IP address'\n    });\n  }\n\n  const body = await readBody(event);\n  \n  \u002F\u002F 2. Perform the IP Intelligence Lookup\n  \u002F\u002F We use a try-catch block to ensure that if the IP Shield API is unreachable \n  \u002F\u002F due to network issues, we fail open or handle it gracefully rather than \n  \u002F\u002F blocking all user logins.\n  let networkData;\n  try {\n    networkData = await shield.network.lookup(ip);\n  } catch (err) {\n    console.error('IP Shield lookup failed, failing open for availability', err);\n    \u002F\u002F Proceed with standard authentication, but log the failure\n    return authenticateUser(body.email, body.password);\n  }\n  \n  \u002F\u002F 3. Analyze the Threat Vectors\n  const isHighRisk = networkData.isProxy || networkData.isVpn || networkData.isTor;\n  const isDatacenter = networkData.asn.type === 'hosting';\n  \n  \u002F\u002F 4. Execute the Security Policy\n  if (networkData.isTor) {\n    \u002F\u002F Tor traffic is almost exclusively malicious in an e-commerce context.\n    \u002F\u002F We block it outright.\n    setResponseStatus(event, 403);\n    return { \n      error: 'access_denied', \n      message: 'Connections from the Tor network are not permitted.' \n    };\n  }\n\n  if (isDatacenter) {\n    \u002F\u002F Legitimate users do not log in from AWS servers. This is likely a script.\n    setResponseStatus(event, 403);\n    return { \n      error: 'access_denied', \n      message: 'Datacenter IP ranges are not permitted. Please disable your VPN.' \n    };\n  }\n\n  if (isHighRisk) {\n    \u002F\u002F The IP belongs to a residential proxy or commercial VPN. \n    \u002F\u002F It might be a malicious actor, or it might be a privacy-conscious user.\n    \u002F\u002F We do NOT block them outright. Instead, we introduce adaptive friction.\n    setResponseStatus(event, 401);\n    return { \n      error: 'verification_required', \n      challengeType: 'mfa',\n      message: 'Unusual network detected. Please enter the code sent to your mobile device.' \n    };\n  }\n  \n  \u002F\u002F 5. If all checks pass, proceed with standard authentication\n  const authResult = await authenticateUser(body.email, body.password);\n  \n  if (!authResult.success) {\n    \u002F\u002F Even if the IP is safe, standard credential checks still apply\n    throw createError({\n      statusCode: 401,\n      statusMessage: 'Invalid credentials'\n    });\n  }\n\n  return {\n    success: true,\n    token: authResult.token,\n    user: authResult.user\n  };\n});\n","server\u002Fapi\u002Flogin.post.ts","typescript",[325,475,476,510,542,547,553,596,600,632,637,642,647,681,687,704,716,731,747,753,759,764,786,791,797,803,809,815,826,834,862,878,904,910,940,945,950,956,994,1028,1033,1039,1055,1061,1067,1084,1092,1110,1128,1134,1139,1144,1156,1162,1177,1184,1199,1215,1220,1225,1230,1242,1248,1254,1260,1276,1283,1299,1316,1332,1337,1342,1347,1353,1385,1390,1409,1415,1424,1436,1450,1455,1460,1465,1473,1485,1502,1517,1523],{"__ignoreMap":227},[328,477,478,482,486,490,493,496,500,504,507],{"class":330,"line":331},[328,479,481],{"class":480},"sZ328","import",[328,483,485],{"class":484},"sDd4n"," { ",[328,487,489],{"class":488},"sjsA6","IPShield",[328,491,492],{"class":484}," } ",[328,494,495],{"class":480},"from",[328,497,499],{"class":498},"sFkSl"," '",[328,501,503],{"class":502},"sFB1V","@ip-shield\u002Fsdk",[328,505,506],{"class":498},"'",[328,508,509],{"class":484},";\n",[328,511,512,514,516,519,522,525,527,530,532,534,536,538,540],{"class":330,"line":228},[328,513,481],{"class":480},[328,515,485],{"class":484},[328,517,518],{"class":488},"sendError",[328,520,521],{"class":484},", ",[328,523,524],{"class":488},"setResponseStatus",[328,526,521],{"class":484},[328,528,529],{"class":488},"createError",[328,531,492],{"class":484},[328,533,495],{"class":480},[328,535,499],{"class":498},[328,537,269],{"class":502},[328,539,506],{"class":498},[328,541,509],{"class":484},[328,543,544],{"class":330,"line":342},[328,545,546],{"emptyLinePlaceholder":10},"\n",[328,548,549],{"class":330,"line":348},[328,550,552],{"class":551},"sghk6","\u002F\u002F Initialize the IP Shield SDK with your secure API key\n",[328,554,555,559,563,567,571,575,578,581,584,587,589,593],{"class":330,"line":354},[328,556,558],{"class":557},"sl46w","const",[328,560,562],{"class":561},"s3JHE"," shield",[328,564,566],{"class":565},"saOXh"," =",[328,568,570],{"class":569},"sakC6"," new",[328,572,574],{"class":573},"sHOzp"," IPShield",[328,576,577],{"class":484},"(",[328,579,580],{"class":488},"process",[328,582,583],{"class":484},".",[328,585,586],{"class":488},"env",[328,588,583],{"class":484},[328,590,592],{"class":591},"sPzPf","IP_SHIELD_API_KEY",[328,594,595],{"class":484},");\n",[328,597,598],{"class":330,"line":360},[328,599,546],{"emptyLinePlaceholder":10},[328,601,602,605,608,611,613,616,619,623,626,629],{"class":330,"line":366},[328,603,604],{"class":480},"export",[328,606,607],{"class":480}," default",[328,609,610],{"class":573}," defineEventHandler",[328,612,577],{"class":484},[328,614,615],{"class":557},"async",[328,617,618],{"class":484}," (",[328,620,622],{"class":621},"sygFZ","event",[328,624,625],{"class":484},") ",[328,627,628],{"class":557},"=>",[328,630,631],{"class":484}," {\n",[328,633,634],{"class":330,"line":372},[328,635,636],{"class":551},"  \u002F\u002F 1. Safely extract the client IP address\n",[328,638,639],{"class":330,"line":378},[328,640,641],{"class":551},"  \u002F\u002F When behind a CDN or Load Balancer (Cloudflare, AWS ALB), the direct \n",[328,643,644],{"class":330,"line":384},[328,645,646],{"class":551},"  \u002F\u002F connection IP belongs to the CDN. We must inspect the X-Forwarded-For header.\n",[328,648,649,652,655,657,660,662,664,667,670,674,678],{"class":330,"line":390},[328,650,651],{"class":557},"  const",[328,653,654],{"class":561}," ip",[328,656,566],{"class":565},[328,658,659],{"class":573}," getRequestIP",[328,661,577],{"class":484},[328,663,622],{"class":488},[328,665,666],{"class":484},", { ",[328,668,669],{"class":488},"xForwardedFor",[328,671,673],{"class":672},"s34zl",":",[328,675,677],{"class":676},"sjR7W"," true",[328,679,680],{"class":484}," });\n",[328,682,684],{"class":330,"line":683},12,[328,685,686],{"class":484},"  \n",[328,688,690,693,695,698,701],{"class":330,"line":689},13,[328,691,692],{"class":480},"  if",[328,694,618],{"class":484},[328,696,697],{"class":565},"!",[328,699,700],{"class":488},"ip",[328,702,703],{"class":484},") {\n",[328,705,707,710,713],{"class":330,"line":706},14,[328,708,709],{"class":480},"    throw",[328,711,712],{"class":573}," createError",[328,714,715],{"class":484},"({\n",[328,717,719,722,724,728],{"class":330,"line":718},15,[328,720,721],{"class":488},"      statusCode",[328,723,673],{"class":672},[328,725,727],{"class":726},"spgvN"," 400",[328,729,730],{"class":484},",\n",[328,732,734,737,739,741,744],{"class":330,"line":733},16,[328,735,736],{"class":488},"      statusMessage",[328,738,673],{"class":672},[328,740,499],{"class":498},[328,742,743],{"class":502},"Unable to determine client IP address",[328,745,746],{"class":498},"'\n",[328,748,750],{"class":330,"line":749},17,[328,751,752],{"class":484},"    });\n",[328,754,756],{"class":330,"line":755},18,[328,757,758],{"class":484},"  }\n",[328,760,762],{"class":330,"line":761},19,[328,763,546],{"emptyLinePlaceholder":10},[328,765,767,769,772,774,777,780,782,784],{"class":330,"line":766},20,[328,768,651],{"class":557},[328,770,771],{"class":561}," body",[328,773,566],{"class":565},[328,775,776],{"class":480}," await",[328,778,779],{"class":573}," readBody",[328,781,577],{"class":484},[328,783,622],{"class":488},[328,785,595],{"class":484},[328,787,789],{"class":330,"line":788},21,[328,790,686],{"class":484},[328,792,794],{"class":330,"line":793},22,[328,795,796],{"class":551},"  \u002F\u002F 2. Perform the IP Intelligence Lookup\n",[328,798,800],{"class":330,"line":799},23,[328,801,802],{"class":551},"  \u002F\u002F We use a try-catch block to ensure that if the IP Shield API is unreachable \n",[328,804,806],{"class":330,"line":805},24,[328,807,808],{"class":551},"  \u002F\u002F due to network issues, we fail open or handle it gracefully rather than \n",[328,810,812],{"class":330,"line":811},25,[328,813,814],{"class":551},"  \u002F\u002F blocking all user logins.\n",[328,816,818,821,824],{"class":330,"line":817},26,[328,819,820],{"class":557},"  let",[328,822,823],{"class":488}," networkData",[328,825,509],{"class":484},[328,827,829,832],{"class":330,"line":828},27,[328,830,831],{"class":480},"  try",[328,833,631],{"class":484},[328,835,837,840,842,844,846,848,851,853,856,858,860],{"class":330,"line":836},28,[328,838,839],{"class":488},"    networkData",[328,841,566],{"class":565},[328,843,776],{"class":480},[328,845,562],{"class":488},[328,847,583],{"class":484},[328,849,850],{"class":488},"network",[328,852,583],{"class":484},[328,854,855],{"class":573},"lookup",[328,857,577],{"class":484},[328,859,700],{"class":488},[328,861,595],{"class":484},[328,863,865,868,871,873,876],{"class":330,"line":864},29,[328,866,867],{"class":484},"  } ",[328,869,870],{"class":480},"catch",[328,872,618],{"class":484},[328,874,875],{"class":488},"err",[328,877,703],{"class":484},[328,879,881,884,886,889,891,893,896,898,900,902],{"class":330,"line":880},30,[328,882,883],{"class":488},"    console",[328,885,583],{"class":484},[328,887,888],{"class":573},"error",[328,890,577],{"class":484},[328,892,506],{"class":498},[328,894,895],{"class":502},"IP Shield lookup failed, failing open for availability",[328,897,506],{"class":498},[328,899,521],{"class":484},[328,901,875],{"class":488},[328,903,595],{"class":484},[328,905,907],{"class":330,"line":906},31,[328,908,909],{"class":551},"    \u002F\u002F Proceed with standard authentication, but log the failure\n",[328,911,913,916,919,921,924,926,929,931,933,935,938],{"class":330,"line":912},32,[328,914,915],{"class":480},"    return",[328,917,918],{"class":573}," authenticateUser",[328,920,577],{"class":484},[328,922,923],{"class":488},"body",[328,925,583],{"class":484},[328,927,928],{"class":488},"email",[328,930,521],{"class":484},[328,932,923],{"class":488},[328,934,583],{"class":484},[328,936,937],{"class":488},"password",[328,939,595],{"class":484},[328,941,943],{"class":330,"line":942},33,[328,944,758],{"class":484},[328,946,948],{"class":330,"line":947},34,[328,949,686],{"class":484},[328,951,953],{"class":330,"line":952},35,[328,954,955],{"class":551},"  \u002F\u002F 3. Analyze the Threat Vectors\n",[328,957,959,961,964,966,968,970,973,976,978,980,983,985,987,989,992],{"class":330,"line":958},36,[328,960,651],{"class":557},[328,962,963],{"class":561}," isHighRisk",[328,965,566],{"class":565},[328,967,823],{"class":488},[328,969,583],{"class":484},[328,971,972],{"class":488},"isProxy",[328,974,975],{"class":565}," ||",[328,977,823],{"class":488},[328,979,583],{"class":484},[328,981,982],{"class":488},"isVpn",[328,984,975],{"class":565},[328,986,823],{"class":488},[328,988,583],{"class":484},[328,990,991],{"class":488},"isTor",[328,993,509],{"class":484},[328,995,997,999,1002,1004,1006,1008,1011,1013,1016,1019,1021,1024,1026],{"class":330,"line":996},37,[328,998,651],{"class":557},[328,1000,1001],{"class":561}," isDatacenter",[328,1003,566],{"class":565},[328,1005,823],{"class":488},[328,1007,583],{"class":484},[328,1009,1010],{"class":488},"asn",[328,1012,583],{"class":484},[328,1014,1015],{"class":488},"type",[328,1017,1018],{"class":565}," ===",[328,1020,499],{"class":498},[328,1022,1023],{"class":502},"hosting",[328,1025,506],{"class":498},[328,1027,509],{"class":484},[328,1029,1031],{"class":330,"line":1030},38,[328,1032,686],{"class":484},[328,1034,1036],{"class":330,"line":1035},39,[328,1037,1038],{"class":551},"  \u002F\u002F 4. Execute the Security Policy\n",[328,1040,1042,1044,1046,1049,1051,1053],{"class":330,"line":1041},40,[328,1043,692],{"class":480},[328,1045,618],{"class":484},[328,1047,1048],{"class":488},"networkData",[328,1050,583],{"class":484},[328,1052,991],{"class":488},[328,1054,703],{"class":484},[328,1056,1058],{"class":330,"line":1057},41,[328,1059,1060],{"class":551},"    \u002F\u002F Tor traffic is almost exclusively malicious in an e-commerce context.\n",[328,1062,1064],{"class":330,"line":1063},42,[328,1065,1066],{"class":551},"    \u002F\u002F We block it outright.\n",[328,1068,1070,1073,1075,1077,1079,1082],{"class":330,"line":1069},43,[328,1071,1072],{"class":573},"    setResponseStatus",[328,1074,577],{"class":484},[328,1076,622],{"class":488},[328,1078,521],{"class":484},[328,1080,1081],{"class":726},"403",[328,1083,595],{"class":484},[328,1085,1087,1089],{"class":330,"line":1086},44,[328,1088,915],{"class":480},[328,1090,1091],{"class":484}," { \n",[328,1093,1095,1098,1100,1102,1105,1107],{"class":330,"line":1094},45,[328,1096,1097],{"class":488},"      error",[328,1099,673],{"class":672},[328,1101,499],{"class":498},[328,1103,1104],{"class":502},"access_denied",[328,1106,506],{"class":498},[328,1108,1109],{"class":484},", \n",[328,1111,1113,1116,1118,1120,1123,1125],{"class":330,"line":1112},46,[328,1114,1115],{"class":488},"      message",[328,1117,673],{"class":672},[328,1119,499],{"class":498},[328,1121,1122],{"class":502},"Connections from the Tor network are not permitted.",[328,1124,506],{"class":498},[328,1126,1127],{"class":484}," \n",[328,1129,1131],{"class":330,"line":1130},47,[328,1132,1133],{"class":484},"    };\n",[328,1135,1137],{"class":330,"line":1136},48,[328,1138,758],{"class":484},[328,1140,1142],{"class":330,"line":1141},49,[328,1143,546],{"emptyLinePlaceholder":10},[328,1145,1147,1149,1151,1154],{"class":330,"line":1146},50,[328,1148,692],{"class":480},[328,1150,618],{"class":484},[328,1152,1153],{"class":488},"isDatacenter",[328,1155,703],{"class":484},[328,1157,1159],{"class":330,"line":1158},51,[328,1160,1161],{"class":551},"    \u002F\u002F Legitimate users do not log in from AWS servers. This is likely a script.\n",[328,1163,1165,1167,1169,1171,1173,1175],{"class":330,"line":1164},52,[328,1166,1072],{"class":573},[328,1168,577],{"class":484},[328,1170,622],{"class":488},[328,1172,521],{"class":484},[328,1174,1081],{"class":726},[328,1176,595],{"class":484},[328,1178,1180,1182],{"class":330,"line":1179},53,[328,1181,915],{"class":480},[328,1183,1091],{"class":484},[328,1185,1187,1189,1191,1193,1195,1197],{"class":330,"line":1186},54,[328,1188,1097],{"class":488},[328,1190,673],{"class":672},[328,1192,499],{"class":498},[328,1194,1104],{"class":502},[328,1196,506],{"class":498},[328,1198,1109],{"class":484},[328,1200,1202,1204,1206,1208,1211,1213],{"class":330,"line":1201},55,[328,1203,1115],{"class":488},[328,1205,673],{"class":672},[328,1207,499],{"class":498},[328,1209,1210],{"class":502},"Datacenter IP ranges are not permitted. Please disable your VPN.",[328,1212,506],{"class":498},[328,1214,1127],{"class":484},[328,1216,1218],{"class":330,"line":1217},56,[328,1219,1133],{"class":484},[328,1221,1223],{"class":330,"line":1222},57,[328,1224,758],{"class":484},[328,1226,1228],{"class":330,"line":1227},58,[328,1229,546],{"emptyLinePlaceholder":10},[328,1231,1233,1235,1237,1240],{"class":330,"line":1232},59,[328,1234,692],{"class":480},[328,1236,618],{"class":484},[328,1238,1239],{"class":488},"isHighRisk",[328,1241,703],{"class":484},[328,1243,1245],{"class":330,"line":1244},60,[328,1246,1247],{"class":551},"    \u002F\u002F The IP belongs to a residential proxy or commercial VPN. \n",[328,1249,1251],{"class":330,"line":1250},61,[328,1252,1253],{"class":551},"    \u002F\u002F It might be a malicious actor, or it might be a privacy-conscious user.\n",[328,1255,1257],{"class":330,"line":1256},62,[328,1258,1259],{"class":551},"    \u002F\u002F We do NOT block them outright. Instead, we introduce adaptive friction.\n",[328,1261,1263,1265,1267,1269,1271,1274],{"class":330,"line":1262},63,[328,1264,1072],{"class":573},[328,1266,577],{"class":484},[328,1268,622],{"class":488},[328,1270,521],{"class":484},[328,1272,1273],{"class":726},"401",[328,1275,595],{"class":484},[328,1277,1279,1281],{"class":330,"line":1278},64,[328,1280,915],{"class":480},[328,1282,1091],{"class":484},[328,1284,1286,1288,1290,1292,1295,1297],{"class":330,"line":1285},65,[328,1287,1097],{"class":488},[328,1289,673],{"class":672},[328,1291,499],{"class":498},[328,1293,1294],{"class":502},"verification_required",[328,1296,506],{"class":498},[328,1298,1109],{"class":484},[328,1300,1302,1305,1307,1309,1312,1314],{"class":330,"line":1301},66,[328,1303,1304],{"class":488},"      challengeType",[328,1306,673],{"class":672},[328,1308,499],{"class":498},[328,1310,1311],{"class":502},"mfa",[328,1313,506],{"class":498},[328,1315,730],{"class":484},[328,1317,1319,1321,1323,1325,1328,1330],{"class":330,"line":1318},67,[328,1320,1115],{"class":488},[328,1322,673],{"class":672},[328,1324,499],{"class":498},[328,1326,1327],{"class":502},"Unusual network detected. Please enter the code sent to your mobile device.",[328,1329,506],{"class":498},[328,1331,1127],{"class":484},[328,1333,1335],{"class":330,"line":1334},68,[328,1336,1133],{"class":484},[328,1338,1340],{"class":330,"line":1339},69,[328,1341,758],{"class":484},[328,1343,1345],{"class":330,"line":1344},70,[328,1346,686],{"class":484},[328,1348,1350],{"class":330,"line":1349},71,[328,1351,1352],{"class":551},"  \u002F\u002F 5. If all checks pass, proceed with standard authentication\n",[328,1354,1356,1358,1361,1363,1365,1367,1369,1371,1373,1375,1377,1379,1381,1383],{"class":330,"line":1355},72,[328,1357,651],{"class":557},[328,1359,1360],{"class":561}," authResult",[328,1362,566],{"class":565},[328,1364,776],{"class":480},[328,1366,918],{"class":573},[328,1368,577],{"class":484},[328,1370,923],{"class":488},[328,1372,583],{"class":484},[328,1374,928],{"class":488},[328,1376,521],{"class":484},[328,1378,923],{"class":488},[328,1380,583],{"class":484},[328,1382,937],{"class":488},[328,1384,595],{"class":484},[328,1386,1388],{"class":330,"line":1387},73,[328,1389,686],{"class":484},[328,1391,1393,1395,1397,1399,1402,1404,1407],{"class":330,"line":1392},74,[328,1394,692],{"class":480},[328,1396,618],{"class":484},[328,1398,697],{"class":565},[328,1400,1401],{"class":488},"authResult",[328,1403,583],{"class":484},[328,1405,1406],{"class":488},"success",[328,1408,703],{"class":484},[328,1410,1412],{"class":330,"line":1411},75,[328,1413,1414],{"class":551},"    \u002F\u002F Even if the IP is safe, standard credential checks still apply\n",[328,1416,1418,1420,1422],{"class":330,"line":1417},76,[328,1419,709],{"class":480},[328,1421,712],{"class":573},[328,1423,715],{"class":484},[328,1425,1427,1429,1431,1434],{"class":330,"line":1426},77,[328,1428,721],{"class":488},[328,1430,673],{"class":672},[328,1432,1433],{"class":726}," 401",[328,1435,730],{"class":484},[328,1437,1439,1441,1443,1445,1448],{"class":330,"line":1438},78,[328,1440,736],{"class":488},[328,1442,673],{"class":672},[328,1444,499],{"class":498},[328,1446,1447],{"class":502},"Invalid credentials",[328,1449,746],{"class":498},[328,1451,1453],{"class":330,"line":1452},79,[328,1454,752],{"class":484},[328,1456,1458],{"class":330,"line":1457},80,[328,1459,758],{"class":484},[328,1461,1463],{"class":330,"line":1462},81,[328,1464,546],{"emptyLinePlaceholder":10},[328,1466,1468,1471],{"class":330,"line":1467},82,[328,1469,1470],{"class":480},"  return",[328,1472,631],{"class":484},[328,1474,1476,1479,1481,1483],{"class":330,"line":1475},83,[328,1477,1478],{"class":488},"    success",[328,1480,673],{"class":672},[328,1482,677],{"class":676},[328,1484,730],{"class":484},[328,1486,1488,1491,1493,1495,1497,1500],{"class":330,"line":1487},84,[328,1489,1490],{"class":488},"    token",[328,1492,673],{"class":672},[328,1494,1360],{"class":488},[328,1496,583],{"class":484},[328,1498,1499],{"class":488},"token",[328,1501,730],{"class":484},[328,1503,1505,1508,1510,1512,1514],{"class":330,"line":1504},85,[328,1506,1507],{"class":488},"    user",[328,1509,673],{"class":672},[328,1511,1360],{"class":488},[328,1513,583],{"class":484},[328,1515,1516],{"class":488},"user\n",[328,1518,1520],{"class":330,"line":1519},86,[328,1521,1522],{"class":484},"  };\n",[328,1524,1526],{"class":330,"line":1525},87,[328,1527,1528],{"class":484},"});\n",[1530,1531,1532],"tip",{},[223,1533,1534,1535,1538],{},"Always test your IP extraction logic thoroughly. Misconfiguring the ",[325,1536,1537],{},"x-forwarded-for"," header parsing can lead to IP spoofing vulnerabilities, where an attacker injects a fake IP address to bypass your security checks.",[269,1540,1542],{"id":1541},"expressjs-implementation","Express.js Implementation",[223,1544,1545],{},"If your backend is built on traditional Express.js, the concepts remain identical, though the implementation syntax differs slightly. You implement this as a reusable middleware function that you attach to specific high-risk routes.",[319,1547,1552],{"className":1548,"code":1549,"filename":1550,"language":1551,"meta":227,"style":227},"language-javascript shiki shiki-themes light-plus light-plus dracula","const { IPShield } = require('@ip-shield\u002Fsdk');\nconst shield = new IPShield(process.env.IP_SHIELD_API_KEY);\n\n\u002F**\n * Express middleware to evaluate IP risk before processing requests\n *\u002F\nasync function ipIntelligenceMiddleware(req, res, next) {\n  \u002F\u002F Extract IP, respecting trust proxy settings in Express\n  const ip = req.ip;\n\n  try {\n    const networkData = await shield.network.lookup(ip);\n    \n    \u002F\u002F Attach the intelligence data to the request object for downstream use\n    req.ipIntelligence = networkData;\n\n    \u002F\u002F Hard block for Tor and Datacenters\n    if (networkData.isTor || networkData.asn.type === 'hosting') {\n      return res.status(403).json({\n        error: 'Forbidden',\n        message: 'Your network type is not permitted to access this resource.'\n      });\n    }\n\n    \u002F\u002F Flag for downstream adaptive friction\n    if (networkData.isProxy || networkData.isVpn) {\n      req.requiresMfa = true;\n    }\n\n    next();\n  } catch (error) {\n    console.error('IP Shield API Error:', error);\n    \u002F\u002F Fail open to prevent locking out legitimate users during an outage\n    next();\n  }\n}\n\nmodule.exports = ipIntelligenceMiddleware;\n","middleware\u002FipIntelligence.js","javascript",[325,1553,1554,1580,1606,1610,1615,1620,1625,1652,1657,1674,1678,1684,1711,1715,1720,1736,1740,1745,1780,1804,1820,1834,1839,1844,1848,1853,1875,1891,1895,1899,1907,1919,1942,1947,1953,1957,1962,1966],{"__ignoreMap":227},[328,1555,1556,1558,1560,1562,1564,1567,1570,1572,1574,1576,1578],{"class":330,"line":331},[328,1557,558],{"class":557},[328,1559,485],{"class":484},[328,1561,489],{"class":561},[328,1563,492],{"class":484},[328,1565,1566],{"class":565},"=",[328,1568,1569],{"class":573}," require",[328,1571,577],{"class":484},[328,1573,506],{"class":498},[328,1575,503],{"class":502},[328,1577,506],{"class":498},[328,1579,595],{"class":484},[328,1581,1582,1584,1586,1588,1590,1592,1594,1596,1598,1600,1602,1604],{"class":330,"line":228},[328,1583,558],{"class":557},[328,1585,562],{"class":561},[328,1587,566],{"class":565},[328,1589,570],{"class":569},[328,1591,574],{"class":573},[328,1593,577],{"class":484},[328,1595,580],{"class":488},[328,1597,583],{"class":484},[328,1599,586],{"class":488},[328,1601,583],{"class":484},[328,1603,592],{"class":591},[328,1605,595],{"class":484},[328,1607,1608],{"class":330,"line":342},[328,1609,546],{"emptyLinePlaceholder":10},[328,1611,1612],{"class":330,"line":348},[328,1613,1614],{"class":551},"\u002F**\n",[328,1616,1617],{"class":330,"line":354},[328,1618,1619],{"class":551}," * Express middleware to evaluate IP risk before processing requests\n",[328,1621,1622],{"class":330,"line":360},[328,1623,1624],{"class":551}," *\u002F\n",[328,1626,1627,1629,1632,1635,1637,1640,1642,1645,1647,1650],{"class":330,"line":366},[328,1628,615],{"class":557},[328,1630,1631],{"class":557}," function",[328,1633,1634],{"class":573}," ipIntelligenceMiddleware",[328,1636,577],{"class":484},[328,1638,1639],{"class":621},"req",[328,1641,521],{"class":484},[328,1643,1644],{"class":621},"res",[328,1646,521],{"class":484},[328,1648,1649],{"class":621},"next",[328,1651,703],{"class":484},[328,1653,1654],{"class":330,"line":372},[328,1655,1656],{"class":551},"  \u002F\u002F Extract IP, respecting trust proxy settings in Express\n",[328,1658,1659,1661,1663,1665,1668,1670,1672],{"class":330,"line":378},[328,1660,651],{"class":557},[328,1662,654],{"class":561},[328,1664,566],{"class":565},[328,1666,1667],{"class":488}," req",[328,1669,583],{"class":484},[328,1671,700],{"class":488},[328,1673,509],{"class":484},[328,1675,1676],{"class":330,"line":384},[328,1677,546],{"emptyLinePlaceholder":10},[328,1679,1680,1682],{"class":330,"line":390},[328,1681,831],{"class":480},[328,1683,631],{"class":484},[328,1685,1686,1689,1691,1693,1695,1697,1699,1701,1703,1705,1707,1709],{"class":330,"line":683},[328,1687,1688],{"class":557},"    const",[328,1690,823],{"class":561},[328,1692,566],{"class":565},[328,1694,776],{"class":480},[328,1696,562],{"class":488},[328,1698,583],{"class":484},[328,1700,850],{"class":488},[328,1702,583],{"class":484},[328,1704,855],{"class":573},[328,1706,577],{"class":484},[328,1708,700],{"class":488},[328,1710,595],{"class":484},[328,1712,1713],{"class":330,"line":689},[328,1714,381],{"class":484},[328,1716,1717],{"class":330,"line":706},[328,1718,1719],{"class":551},"    \u002F\u002F Attach the intelligence data to the request object for downstream use\n",[328,1721,1722,1725,1727,1730,1732,1734],{"class":330,"line":718},[328,1723,1724],{"class":488},"    req",[328,1726,583],{"class":484},[328,1728,1729],{"class":488},"ipIntelligence",[328,1731,566],{"class":565},[328,1733,823],{"class":488},[328,1735,509],{"class":484},[328,1737,1738],{"class":330,"line":733},[328,1739,546],{"emptyLinePlaceholder":10},[328,1741,1742],{"class":330,"line":749},[328,1743,1744],{"class":551},"    \u002F\u002F Hard block for Tor and Datacenters\n",[328,1746,1747,1750,1752,1754,1756,1758,1760,1762,1764,1766,1768,1770,1772,1774,1776,1778],{"class":330,"line":755},[328,1748,1749],{"class":480},"    if",[328,1751,618],{"class":484},[328,1753,1048],{"class":488},[328,1755,583],{"class":484},[328,1757,991],{"class":488},[328,1759,975],{"class":565},[328,1761,823],{"class":488},[328,1763,583],{"class":484},[328,1765,1010],{"class":488},[328,1767,583],{"class":484},[328,1769,1015],{"class":488},[328,1771,1018],{"class":565},[328,1773,499],{"class":498},[328,1775,1023],{"class":502},[328,1777,506],{"class":498},[328,1779,703],{"class":484},[328,1781,1782,1785,1788,1790,1793,1795,1797,1800,1802],{"class":330,"line":761},[328,1783,1784],{"class":480},"      return",[328,1786,1787],{"class":488}," res",[328,1789,583],{"class":484},[328,1791,1792],{"class":573},"status",[328,1794,577],{"class":484},[328,1796,1081],{"class":726},[328,1798,1799],{"class":484},").",[328,1801,5],{"class":573},[328,1803,715],{"class":484},[328,1805,1806,1809,1811,1813,1816,1818],{"class":330,"line":766},[328,1807,1808],{"class":488},"        error",[328,1810,673],{"class":672},[328,1812,499],{"class":498},[328,1814,1815],{"class":502},"Forbidden",[328,1817,506],{"class":498},[328,1819,730],{"class":484},[328,1821,1822,1825,1827,1829,1832],{"class":330,"line":788},[328,1823,1824],{"class":488},"        message",[328,1826,673],{"class":672},[328,1828,499],{"class":498},[328,1830,1831],{"class":502},"Your network type is not permitted to access this resource.",[328,1833,746],{"class":498},[328,1835,1836],{"class":330,"line":793},[328,1837,1838],{"class":484},"      });\n",[328,1840,1841],{"class":330,"line":799},[328,1842,1843],{"class":484},"    }\n",[328,1845,1846],{"class":330,"line":805},[328,1847,546],{"emptyLinePlaceholder":10},[328,1849,1850],{"class":330,"line":811},[328,1851,1852],{"class":551},"    \u002F\u002F Flag for downstream adaptive friction\n",[328,1854,1855,1857,1859,1861,1863,1865,1867,1869,1871,1873],{"class":330,"line":817},[328,1856,1749],{"class":480},[328,1858,618],{"class":484},[328,1860,1048],{"class":488},[328,1862,583],{"class":484},[328,1864,972],{"class":488},[328,1866,975],{"class":565},[328,1868,823],{"class":488},[328,1870,583],{"class":484},[328,1872,982],{"class":488},[328,1874,703],{"class":484},[328,1876,1877,1880,1882,1885,1887,1889],{"class":330,"line":828},[328,1878,1879],{"class":488},"      req",[328,1881,583],{"class":484},[328,1883,1884],{"class":488},"requiresMfa",[328,1886,566],{"class":565},[328,1888,677],{"class":676},[328,1890,509],{"class":484},[328,1892,1893],{"class":330,"line":836},[328,1894,1843],{"class":484},[328,1896,1897],{"class":330,"line":864},[328,1898,546],{"emptyLinePlaceholder":10},[328,1900,1901,1904],{"class":330,"line":880},[328,1902,1903],{"class":573},"    next",[328,1905,1906],{"class":484},"();\n",[328,1908,1909,1911,1913,1915,1917],{"class":330,"line":906},[328,1910,867],{"class":484},[328,1912,870],{"class":480},[328,1914,618],{"class":484},[328,1916,888],{"class":488},[328,1918,703],{"class":484},[328,1920,1921,1923,1925,1927,1929,1931,1934,1936,1938,1940],{"class":330,"line":912},[328,1922,883],{"class":488},[328,1924,583],{"class":484},[328,1926,888],{"class":573},[328,1928,577],{"class":484},[328,1930,506],{"class":498},[328,1932,1933],{"class":502},"IP Shield API Error:",[328,1935,506],{"class":498},[328,1937,521],{"class":484},[328,1939,888],{"class":488},[328,1941,595],{"class":484},[328,1943,1944],{"class":330,"line":942},[328,1945,1946],{"class":551},"    \u002F\u002F Fail open to prevent locking out legitimate users during an outage\n",[328,1948,1949,1951],{"class":330,"line":947},[328,1950,1903],{"class":573},[328,1952,1906],{"class":484},[328,1954,1955],{"class":330,"line":952},[328,1956,758],{"class":484},[328,1958,1959],{"class":330,"line":958},[328,1960,1961],{"class":484},"}\n",[328,1963,1964],{"class":330,"line":996},[328,1965,546],{"emptyLinePlaceholder":10},[328,1967,1968,1972,1974,1977,1979,1981],{"class":330,"line":1030},[328,1969,1971],{"class":1970},"sFs1U","module",[328,1973,583],{"class":484},[328,1975,1976],{"class":1970},"exports",[328,1978,566],{"class":565},[328,1980,1634],{"class":488},[328,1982,509],{"class":484},[223,1984,1985],{},"You then apply this middleware to your sensitive routes:",[319,1987,1990],{"className":1548,"code":1988,"filename":1989,"language":1551,"meta":227,"style":227},"const express = require('express');\nconst router = express.Router();\nconst ipIntelligence = require('..\u002Fmiddleware\u002FipIntelligence');\n\n\u002F\u002F Apply the IP intelligence middleware specifically to the login route\nrouter.post('\u002Flogin', ipIntelligence, async (req, res) => {\n  const { email, password } = req.body;\n\n  \u002F\u002F Check if the middleware flagged this request for MFA\n  if (req.requiresMfa) {\n    return res.status(401).json({\n      error: 'MFA_REQUIRED',\n      message: 'Please complete multi-factor authentication.'\n    });\n  }\n\n  \u002F\u002F Standard login logic...\n  res.json({ success: true });\n});\n\nmodule.exports = router;\n","routes\u002Fauth.js",[325,1991,1992,2014,2032,2054,2058,2063,2104,2128,2132,2137,2151,2171,2186,2199,2203,2207,2211,2216,2236,2240,2244],{"__ignoreMap":227},[328,1993,1994,1996,1999,2001,2003,2005,2007,2010,2012],{"class":330,"line":331},[328,1995,558],{"class":557},[328,1997,1998],{"class":561}," express",[328,2000,566],{"class":565},[328,2002,1569],{"class":573},[328,2004,577],{"class":484},[328,2006,506],{"class":498},[328,2008,2009],{"class":502},"express",[328,2011,506],{"class":498},[328,2013,595],{"class":484},[328,2015,2016,2018,2021,2023,2025,2027,2030],{"class":330,"line":228},[328,2017,558],{"class":557},[328,2019,2020],{"class":561}," router",[328,2022,566],{"class":565},[328,2024,1998],{"class":488},[328,2026,583],{"class":484},[328,2028,2029],{"class":573},"Router",[328,2031,1906],{"class":484},[328,2033,2034,2036,2039,2041,2043,2045,2047,2050,2052],{"class":330,"line":342},[328,2035,558],{"class":557},[328,2037,2038],{"class":561}," ipIntelligence",[328,2040,566],{"class":565},[328,2042,1569],{"class":573},[328,2044,577],{"class":484},[328,2046,506],{"class":498},[328,2048,2049],{"class":502},"..\u002Fmiddleware\u002FipIntelligence",[328,2051,506],{"class":498},[328,2053,595],{"class":484},[328,2055,2056],{"class":330,"line":348},[328,2057,546],{"emptyLinePlaceholder":10},[328,2059,2060],{"class":330,"line":354},[328,2061,2062],{"class":551},"\u002F\u002F Apply the IP intelligence middleware specifically to the login route\n",[328,2064,2065,2068,2070,2073,2075,2077,2080,2082,2084,2086,2088,2090,2092,2094,2096,2098,2100,2102],{"class":330,"line":360},[328,2066,2067],{"class":488},"router",[328,2069,583],{"class":484},[328,2071,2072],{"class":573},"post",[328,2074,577],{"class":484},[328,2076,506],{"class":498},[328,2078,2079],{"class":502},"\u002Flogin",[328,2081,506],{"class":498},[328,2083,521],{"class":484},[328,2085,1729],{"class":488},[328,2087,521],{"class":484},[328,2089,615],{"class":557},[328,2091,618],{"class":484},[328,2093,1639],{"class":621},[328,2095,521],{"class":484},[328,2097,1644],{"class":621},[328,2099,625],{"class":484},[328,2101,628],{"class":557},[328,2103,631],{"class":484},[328,2105,2106,2108,2110,2112,2114,2116,2118,2120,2122,2124,2126],{"class":330,"line":366},[328,2107,651],{"class":557},[328,2109,485],{"class":484},[328,2111,928],{"class":561},[328,2113,521],{"class":484},[328,2115,937],{"class":561},[328,2117,492],{"class":484},[328,2119,1566],{"class":565},[328,2121,1667],{"class":488},[328,2123,583],{"class":484},[328,2125,923],{"class":488},[328,2127,509],{"class":484},[328,2129,2130],{"class":330,"line":372},[328,2131,546],{"emptyLinePlaceholder":10},[328,2133,2134],{"class":330,"line":378},[328,2135,2136],{"class":551},"  \u002F\u002F Check if the middleware flagged this request for MFA\n",[328,2138,2139,2141,2143,2145,2147,2149],{"class":330,"line":384},[328,2140,692],{"class":480},[328,2142,618],{"class":484},[328,2144,1639],{"class":488},[328,2146,583],{"class":484},[328,2148,1884],{"class":488},[328,2150,703],{"class":484},[328,2152,2153,2155,2157,2159,2161,2163,2165,2167,2169],{"class":330,"line":390},[328,2154,915],{"class":480},[328,2156,1787],{"class":488},[328,2158,583],{"class":484},[328,2160,1792],{"class":573},[328,2162,577],{"class":484},[328,2164,1273],{"class":726},[328,2166,1799],{"class":484},[328,2168,5],{"class":573},[328,2170,715],{"class":484},[328,2172,2173,2175,2177,2179,2182,2184],{"class":330,"line":683},[328,2174,1097],{"class":488},[328,2176,673],{"class":672},[328,2178,499],{"class":498},[328,2180,2181],{"class":502},"MFA_REQUIRED",[328,2183,506],{"class":498},[328,2185,730],{"class":484},[328,2187,2188,2190,2192,2194,2197],{"class":330,"line":689},[328,2189,1115],{"class":488},[328,2191,673],{"class":672},[328,2193,499],{"class":498},[328,2195,2196],{"class":502},"Please complete multi-factor authentication.",[328,2198,746],{"class":498},[328,2200,2201],{"class":330,"line":706},[328,2202,752],{"class":484},[328,2204,2205],{"class":330,"line":718},[328,2206,758],{"class":484},[328,2208,2209],{"class":330,"line":733},[328,2210,546],{"emptyLinePlaceholder":10},[328,2212,2213],{"class":330,"line":749},[328,2214,2215],{"class":551},"  \u002F\u002F Standard login logic...\n",[328,2217,2218,2221,2223,2225,2228,2230,2232,2234],{"class":330,"line":755},[328,2219,2220],{"class":488},"  res",[328,2222,583],{"class":484},[328,2224,5],{"class":573},[328,2226,2227],{"class":484},"({ ",[328,2229,1406],{"class":488},[328,2231,673],{"class":672},[328,2233,677],{"class":676},[328,2235,680],{"class":484},[328,2237,2238],{"class":330,"line":761},[328,2239,1528],{"class":484},[328,2241,2242],{"class":330,"line":766},[328,2243,546],{"emptyLinePlaceholder":10},[328,2245,2246,2248,2250,2252,2254,2256],{"class":330,"line":788},[328,2247,1971],{"class":1970},[328,2249,583],{"class":484},[328,2251,1976],{"class":1970},[328,2253,566],{"class":565},[328,2255,2020],{"class":488},[328,2257,509],{"class":484},[269,2259,2261],{"id":2260},"implementing-at-the-edge-with-cloudflare-workers","Implementing at the Edge with Cloudflare Workers",[223,2263,2264],{},"For maximum performance, you move your security logic as close to the user as possible. Cloudflare Workers allow you to intercept requests at the CDN edge, before they ever reach your origin server. This protects your backend infrastructure from the computational load of processing malicious requests.",[319,2266,2269],{"className":1548,"code":2267,"filename":2268,"language":1551,"meta":227,"style":227},"export default {\n  async fetch(request, env, ctx) {\n    const url = new URL(request.url);\n    \n    \u002F\u002F Only run the heavy IP check on sensitive endpoints to save costs and latency\n    if (url.pathname !== '\u002Fapi\u002Fv1\u002Flogin' && url.pathname !== '\u002Fapi\u002Fv1\u002Fcheckout') {\n      return fetch(request);\n    }\n\n    \u002F\u002F Cloudflare provides the client IP in the headers\n    const clientIP = request.headers.get('CF-Connecting-IP');\n\n    try {\n      \u002F\u002F Make a subrequest to the IP Shield API\n      const shieldResponse = await fetch(`https:\u002F\u002Fip-shield.riavzon.com\u002Fv1\u002Fnetwork\u002F${clientIP}`, {\n        headers: {\n          'Authorization': `Bearer ${env.IP_SHIELD_API_KEY}`\n        }\n      });\n\n      if (shieldResponse.ok) {\n        const networkData = await shieldResponse.json();\n\n        \u002F\u002F Implement blocking logic at the edge\n        if (networkData.isTor || networkData.asn.type === 'hosting') {\n          return new Response(JSON.stringify({ error: 'Access Denied' }), {\n            status: 403,\n            headers: { 'Content-Type': 'application\u002Fjson' }\n          });\n        }\n        \n        \u002F\u002F Pass intelligence data to the origin server via custom headers\n        const modifiedRequest = new Request(request);\n        if (networkData.isProxy || networkData.isVpn) {\n          modifiedRequest.headers.set('X-Requires-Adaptive-Friction', 'true');\n        }\n        \n        return fetch(modifiedRequest);\n      }\n    } catch (err) {\n      \u002F\u002F Fail open on error\n      console.error('Edge security check failed:', err);\n    }\n\n    return fetch(request);\n  }\n};\n","worker.js",[325,2270,2271,2279,2303,2328,2332,2337,2380,2392,2396,2400,2405,2438,2442,2449,2454,2488,2497,2526,2531,2535,2539,2556,2575,2579,2584,2619,2655,2667,2695,2700,2704,2709,2714,2734,2756,2790,2794,2798,2812,2817,2830,2835,2859,2863,2867,2879,2883],{"__ignoreMap":227},[328,2272,2273,2275,2277],{"class":330,"line":331},[328,2274,604],{"class":480},[328,2276,607],{"class":480},[328,2278,631],{"class":484},[328,2280,2281,2284,2287,2289,2292,2294,2296,2298,2301],{"class":330,"line":228},[328,2282,2283],{"class":557},"  async",[328,2285,2286],{"class":573}," fetch",[328,2288,577],{"class":484},[328,2290,2291],{"class":621},"request",[328,2293,521],{"class":484},[328,2295,586],{"class":621},[328,2297,521],{"class":484},[328,2299,2300],{"class":621},"ctx",[328,2302,703],{"class":484},[328,2304,2305,2307,2310,2312,2314,2317,2319,2321,2323,2326],{"class":330,"line":342},[328,2306,1688],{"class":557},[328,2308,2309],{"class":561}," url",[328,2311,566],{"class":565},[328,2313,570],{"class":569},[328,2315,2316],{"class":573}," URL",[328,2318,577],{"class":484},[328,2320,2291],{"class":488},[328,2322,583],{"class":484},[328,2324,2325],{"class":488},"url",[328,2327,595],{"class":484},[328,2329,2330],{"class":330,"line":348},[328,2331,381],{"class":484},[328,2333,2334],{"class":330,"line":354},[328,2335,2336],{"class":551},"    \u002F\u002F Only run the heavy IP check on sensitive endpoints to save costs and latency\n",[328,2338,2339,2341,2343,2345,2347,2350,2353,2355,2358,2360,2363,2365,2367,2369,2371,2373,2376,2378],{"class":330,"line":360},[328,2340,1749],{"class":480},[328,2342,618],{"class":484},[328,2344,2325],{"class":488},[328,2346,583],{"class":484},[328,2348,2349],{"class":488},"pathname",[328,2351,2352],{"class":565}," !==",[328,2354,499],{"class":498},[328,2356,2357],{"class":502},"\u002Fapi\u002Fv1\u002Flogin",[328,2359,506],{"class":498},[328,2361,2362],{"class":565}," &&",[328,2364,2309],{"class":488},[328,2366,583],{"class":484},[328,2368,2349],{"class":488},[328,2370,2352],{"class":565},[328,2372,499],{"class":498},[328,2374,2375],{"class":502},"\u002Fapi\u002Fv1\u002Fcheckout",[328,2377,506],{"class":498},[328,2379,703],{"class":484},[328,2381,2382,2384,2386,2388,2390],{"class":330,"line":366},[328,2383,1784],{"class":480},[328,2385,2286],{"class":573},[328,2387,577],{"class":484},[328,2389,2291],{"class":488},[328,2391,595],{"class":484},[328,2393,2394],{"class":330,"line":372},[328,2395,1843],{"class":484},[328,2397,2398],{"class":330,"line":378},[328,2399,546],{"emptyLinePlaceholder":10},[328,2401,2402],{"class":330,"line":384},[328,2403,2404],{"class":551},"    \u002F\u002F Cloudflare provides the client IP in the headers\n",[328,2406,2407,2409,2412,2414,2417,2419,2422,2424,2427,2429,2431,2434,2436],{"class":330,"line":390},[328,2408,1688],{"class":557},[328,2410,2411],{"class":561}," clientIP",[328,2413,566],{"class":565},[328,2415,2416],{"class":488}," request",[328,2418,583],{"class":484},[328,2420,2421],{"class":488},"headers",[328,2423,583],{"class":484},[328,2425,2426],{"class":573},"get",[328,2428,577],{"class":484},[328,2430,506],{"class":498},[328,2432,2433],{"class":502},"CF-Connecting-IP",[328,2435,506],{"class":498},[328,2437,595],{"class":484},[328,2439,2440],{"class":330,"line":683},[328,2441,546],{"emptyLinePlaceholder":10},[328,2443,2444,2447],{"class":330,"line":689},[328,2445,2446],{"class":480},"    try",[328,2448,631],{"class":484},[328,2450,2451],{"class":330,"line":706},[328,2452,2453],{"class":551},"      \u002F\u002F Make a subrequest to the IP Shield API\n",[328,2455,2456,2459,2462,2464,2466,2468,2470,2473,2476,2479,2482,2485],{"class":330,"line":718},[328,2457,2458],{"class":557},"      const",[328,2460,2461],{"class":561}," shieldResponse",[328,2463,566],{"class":565},[328,2465,776],{"class":480},[328,2467,2286],{"class":573},[328,2469,577],{"class":484},[328,2471,2472],{"class":502},"`https:\u002F\u002Fip-shield.riavzon.com\u002Fv1\u002Fnetwork\u002F",[328,2474,2475],{"class":557},"${",[328,2477,2478],{"class":488},"clientIP",[328,2480,2481],{"class":557},"}",[328,2483,2484],{"class":502},"`",[328,2486,2487],{"class":484},", {\n",[328,2489,2490,2493,2495],{"class":330,"line":733},[328,2491,2492],{"class":488},"        headers",[328,2494,673],{"class":672},[328,2496,631],{"class":484},[328,2498,2499,2502,2505,2507,2509,2512,2514,2516,2519,2521,2523],{"class":330,"line":749},[328,2500,2501],{"class":498},"          '",[328,2503,2504],{"class":502},"Authorization",[328,2506,506],{"class":498},[328,2508,673],{"class":672},[328,2510,2511],{"class":502}," `Bearer ",[328,2513,2475],{"class":557},[328,2515,586],{"class":488},[328,2517,583],{"class":2518},"s1lnM",[328,2520,592],{"class":591},[328,2522,2481],{"class":557},[328,2524,2525],{"class":502},"`\n",[328,2527,2528],{"class":330,"line":755},[328,2529,2530],{"class":484},"        }\n",[328,2532,2533],{"class":330,"line":761},[328,2534,1838],{"class":484},[328,2536,2537],{"class":330,"line":766},[328,2538,546],{"emptyLinePlaceholder":10},[328,2540,2541,2544,2546,2549,2551,2554],{"class":330,"line":788},[328,2542,2543],{"class":480},"      if",[328,2545,618],{"class":484},[328,2547,2548],{"class":488},"shieldResponse",[328,2550,583],{"class":484},[328,2552,2553],{"class":488},"ok",[328,2555,703],{"class":484},[328,2557,2558,2561,2563,2565,2567,2569,2571,2573],{"class":330,"line":793},[328,2559,2560],{"class":557},"        const",[328,2562,823],{"class":561},[328,2564,566],{"class":565},[328,2566,776],{"class":480},[328,2568,2461],{"class":488},[328,2570,583],{"class":484},[328,2572,5],{"class":573},[328,2574,1906],{"class":484},[328,2576,2577],{"class":330,"line":799},[328,2578,546],{"emptyLinePlaceholder":10},[328,2580,2581],{"class":330,"line":805},[328,2582,2583],{"class":551},"        \u002F\u002F Implement blocking logic at the edge\n",[328,2585,2586,2589,2591,2593,2595,2597,2599,2601,2603,2605,2607,2609,2611,2613,2615,2617],{"class":330,"line":811},[328,2587,2588],{"class":480},"        if",[328,2590,618],{"class":484},[328,2592,1048],{"class":488},[328,2594,583],{"class":484},[328,2596,991],{"class":488},[328,2598,975],{"class":565},[328,2600,823],{"class":488},[328,2602,583],{"class":484},[328,2604,1010],{"class":488},[328,2606,583],{"class":484},[328,2608,1015],{"class":488},[328,2610,1018],{"class":565},[328,2612,499],{"class":498},[328,2614,1023],{"class":502},[328,2616,506],{"class":498},[328,2618,703],{"class":484},[328,2620,2621,2624,2626,2629,2631,2634,2636,2639,2641,2643,2645,2647,2650,2652],{"class":330,"line":817},[328,2622,2623],{"class":480},"          return",[328,2625,570],{"class":569},[328,2627,2628],{"class":573}," Response",[328,2630,577],{"class":484},[328,2632,2633],{"class":591},"JSON",[328,2635,583],{"class":484},[328,2637,2638],{"class":573},"stringify",[328,2640,2227],{"class":484},[328,2642,888],{"class":488},[328,2644,673],{"class":672},[328,2646,499],{"class":498},[328,2648,2649],{"class":502},"Access Denied",[328,2651,506],{"class":498},[328,2653,2654],{"class":484}," }), {\n",[328,2656,2657,2660,2662,2665],{"class":330,"line":828},[328,2658,2659],{"class":488},"            status",[328,2661,673],{"class":672},[328,2663,2664],{"class":726}," 403",[328,2666,730],{"class":484},[328,2668,2669,2672,2674,2676,2678,2681,2683,2685,2687,2690,2692],{"class":330,"line":836},[328,2670,2671],{"class":488},"            headers",[328,2673,673],{"class":672},[328,2675,485],{"class":484},[328,2677,506],{"class":498},[328,2679,2680],{"class":502},"Content-Type",[328,2682,506],{"class":498},[328,2684,673],{"class":672},[328,2686,499],{"class":498},[328,2688,2689],{"class":502},"application\u002Fjson",[328,2691,506],{"class":498},[328,2693,2694],{"class":484}," }\n",[328,2696,2697],{"class":330,"line":864},[328,2698,2699],{"class":484},"          });\n",[328,2701,2702],{"class":330,"line":880},[328,2703,2530],{"class":484},[328,2705,2706],{"class":330,"line":906},[328,2707,2708],{"class":484},"        \n",[328,2710,2711],{"class":330,"line":912},[328,2712,2713],{"class":551},"        \u002F\u002F Pass intelligence data to the origin server via custom headers\n",[328,2715,2716,2718,2721,2723,2725,2728,2730,2732],{"class":330,"line":942},[328,2717,2560],{"class":557},[328,2719,2720],{"class":561}," modifiedRequest",[328,2722,566],{"class":565},[328,2724,570],{"class":569},[328,2726,2727],{"class":573}," Request",[328,2729,577],{"class":484},[328,2731,2291],{"class":488},[328,2733,595],{"class":484},[328,2735,2736,2738,2740,2742,2744,2746,2748,2750,2752,2754],{"class":330,"line":947},[328,2737,2588],{"class":480},[328,2739,618],{"class":484},[328,2741,1048],{"class":488},[328,2743,583],{"class":484},[328,2745,972],{"class":488},[328,2747,975],{"class":565},[328,2749,823],{"class":488},[328,2751,583],{"class":484},[328,2753,982],{"class":488},[328,2755,703],{"class":484},[328,2757,2758,2761,2763,2765,2767,2770,2772,2774,2777,2779,2781,2783,2786,2788],{"class":330,"line":952},[328,2759,2760],{"class":488},"          modifiedRequest",[328,2762,583],{"class":484},[328,2764,2421],{"class":488},[328,2766,583],{"class":484},[328,2768,2769],{"class":573},"set",[328,2771,577],{"class":484},[328,2773,506],{"class":498},[328,2775,2776],{"class":502},"X-Requires-Adaptive-Friction",[328,2778,506],{"class":498},[328,2780,521],{"class":484},[328,2782,506],{"class":498},[328,2784,2785],{"class":502},"true",[328,2787,506],{"class":498},[328,2789,595],{"class":484},[328,2791,2792],{"class":330,"line":958},[328,2793,2530],{"class":484},[328,2795,2796],{"class":330,"line":996},[328,2797,2708],{"class":484},[328,2799,2800,2803,2805,2807,2810],{"class":330,"line":1030},[328,2801,2802],{"class":480},"        return",[328,2804,2286],{"class":573},[328,2806,577],{"class":484},[328,2808,2809],{"class":488},"modifiedRequest",[328,2811,595],{"class":484},[328,2813,2814],{"class":330,"line":1035},[328,2815,2816],{"class":484},"      }\n",[328,2818,2819,2822,2824,2826,2828],{"class":330,"line":1041},[328,2820,2821],{"class":484},"    } ",[328,2823,870],{"class":480},[328,2825,618],{"class":484},[328,2827,875],{"class":488},[328,2829,703],{"class":484},[328,2831,2832],{"class":330,"line":1057},[328,2833,2834],{"class":551},"      \u002F\u002F Fail open on error\n",[328,2836,2837,2840,2842,2844,2846,2848,2851,2853,2855,2857],{"class":330,"line":1063},[328,2838,2839],{"class":488},"      console",[328,2841,583],{"class":484},[328,2843,888],{"class":573},[328,2845,577],{"class":484},[328,2847,506],{"class":498},[328,2849,2850],{"class":502},"Edge security check failed:",[328,2852,506],{"class":498},[328,2854,521],{"class":484},[328,2856,875],{"class":488},[328,2858,595],{"class":484},[328,2860,2861],{"class":330,"line":1069},[328,2862,1843],{"class":484},[328,2864,2865],{"class":330,"line":1086},[328,2866,546],{"emptyLinePlaceholder":10},[328,2868,2869,2871,2873,2875,2877],{"class":330,"line":1094},[328,2870,915],{"class":480},[328,2872,2286],{"class":573},[328,2874,577],{"class":484},[328,2876,2291],{"class":488},[328,2878,595],{"class":484},[328,2880,2881],{"class":330,"line":1112},[328,2882,758],{"class":484},[328,2884,2885],{"class":330,"line":1130},[328,2886,2887],{"class":484},"};\n",[2889,2890,2891],"important",{},[223,2892,2893],{},"When implementing edge security, always ensure your origin server is configured to ONLY accept traffic from your Edge provider (e.g., Cloudflare IP ranges). Otherwise, attackers simply bypass the edge worker by connecting to your origin IP directly.",[261,2895,2897],{"id":2896},"the-challenge-of-ipv6-and-subnet-hopping","The Challenge of IPv6 and Subnet Hopping",[223,2899,2900,2901,2904],{},"As the internet transitions to IPv6, attackers gain access to an unimaginably large address space. Traditional IPv4 blocklists fail against IPv6 because an attacker can cycle through billions of IP addresses within a single ",[325,2902,2903],{},"\u002F64"," subnet.",[223,2906,2907,2908,2911,2912,2914],{},"When dealing with IPv6, you must adjust your defensive strategies. You no longer block or evaluate individual ",[325,2909,2910],{},"\u002F128"," IP addresses. Instead, you apply your logic to the entire ",[325,2913,2903],{}," subnet. IP Shield handles this complexity automatically, aggregating intelligence across IPv6 blocks so that if an attacker hops IPs within their assigned subnet, the threat score remains accurate.",[269,2916,2918],{"id":2917},"subnet-aggregation-strategies","Subnet Aggregation Strategies",[277,2920,2921,2935],{},[280,2922,2923,2926,2927,2930,2931,2934],{},[283,2924,2925],{},"IPv4",": Track and evaluate on a ",[325,2928,2929],{},"\u002F32"," (individual IP) or ",[325,2932,2933],{},"\u002F24"," (C-class subnet) basis.",[280,2936,2937,2940,2941,2943],{},[283,2938,2939],{},"IPv6",": Always track and evaluate on a minimum of a ",[325,2942,2903],{}," basis.",[223,2945,2946,2947,2950,2951,2954],{},"If you observe malicious activity from ",[325,2948,2949],{},"2001:db8:1234:5678:90ab:cdef:0123:4567",", you should apply security friction to the entire ",[325,2952,2953],{},"2001:db8:1234:5678::\u002F64"," range.",[261,2956,2958],{"id":2957},"advanced-techniques-correlating-signals","Advanced Techniques: Correlating Signals",[223,2960,2961],{},"IP intelligence is incredibly powerful, but it becomes exponentially more effective when combined with other security signals. To build a truly resilient system against advanced residential proxies, you must correlate network data with client-side telemetry.",[269,2963,2965],{"id":2964},"device-fingerprinting","Device Fingerprinting",[223,2967,2968],{},"Attackers using residential proxies often route traffic from hundreds of IPs, but they might use the same underlying hardware or scraping script for all requests. By implementing device fingerprinting—analyzing the Canvas API rendering, WebGL drivers, audio context, and font stacks—you generate a unique identifier for the machine making the request.",[223,2970,2971],{},"If you observe 500 different residential IPs logging into 500 different accounts, but all 500 requests share the exact same highly unique device fingerprint, you definitively identify an ongoing attack.",[269,2973,2975],{"id":2974},"behavioral-biometrics","Behavioral Biometrics",[223,2977,2978],{},"How does the user interact with the page? Does the mouse move in perfectly straight lines? Are keystrokes registering with zero variance in timing? Human behavior is messy and unpredictable. Scrapers and bots, even those using residential proxies, often exhibit robotic perfection.",[223,2980,2981],{},"By combining IP Shield's network data with behavioral biometrics, you achieve unprecedented detection accuracy.",[261,2983,2985],{"id":2984},"creating-a-splunk-dashboard-for-traffic-analysis","Creating a Splunk Dashboard for Traffic Analysis",[223,2987,2988],{},"Monitoring your traffic is just as important as blocking it. By logging the IP Shield metadata alongside your standard access logs, you create powerful visualizations in tools like Splunk, ELK (Elasticsearch, Logstash, Kibana), or Datadog.",[223,2990,2991],{},"Here is an example Splunk SPL query to identify the top ASNs associated with failed login attempts:",[319,2993,2997],{"className":2994,"code":2995,"language":2996,"meta":227,"style":227},"language-spl shiki shiki-themes light-plus light-plus dracula","index=production sourcetype=api_logs endpoint=\"\u002Fapi\u002Fv1\u002Flogin\" status=401\n| stats count by ip_intelligence.asn.name, ip_intelligence.asn.type\n| sort - count\n| head 20\n","spl",[325,2998,2999,3004,3009,3014],{"__ignoreMap":227},[328,3000,3001],{"class":330,"line":331},[328,3002,3003],{},"index=production sourcetype=api_logs endpoint=\"\u002Fapi\u002Fv1\u002Flogin\" status=401\n",[328,3005,3006],{"class":330,"line":228},[328,3007,3008],{},"| stats count by ip_intelligence.asn.name, ip_intelligence.asn.type\n",[328,3010,3011],{"class":330,"line":342},[328,3012,3013],{},"| sort - count\n",[328,3015,3016],{"class":330,"line":348},[328,3017,3018],{},"| head 20\n",[223,3020,3021],{},"This query instantly reveals if a specific datacenter or proxy network is currently targeting your authentication endpoints, allowing your security team to respond proactively.",[261,3023,3025],{"id":3024},"conclusion","Conclusion",[223,3027,3028],{},"The era of simple IP blocking is over. The commoditization of residential proxy networks has fundamentally shifted the balance of power, granting attackers the ability to blend seamlessly into legitimate user traffic.",[223,3030,3031],{},"To survive in this environment, your applications must become contextually aware. By integrating deep network intelligence from tools like IP Shield into your authentication flows, edge routers, and monitoring dashboards, you regain visibility. You transition from a static, reactive security posture to a dynamic, adaptive defense capable of thwarting the most sophisticated modern attacks.",[223,3033,3034],{},"Security is not a final destination; it is a continuous arms race. Equip your infrastructure with the intelligence it needs to win.",[3036,3037,3038],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZ328, html code.shiki .sZ328{--shiki-light:#AF00DB;--shiki-default:#AF00DB;--shiki-dark:#FF79C6}html pre.shiki code .sDd4n, html code.shiki .sDd4n{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#F8F8F2}html pre.shiki code .sjsA6, html code.shiki .sjsA6{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#F8F8F2}html pre.shiki code .sFkSl, html code.shiki .sFkSl{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#E9F284}html pre.shiki code .sFB1V, html code.shiki .sFB1V{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#F1FA8C}html pre.shiki code .sghk6, html code.shiki .sghk6{--shiki-light:#008000;--shiki-default:#008000;--shiki-dark:#6272A4}html pre.shiki code .sl46w, html code.shiki .sl46w{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#FF79C6}html pre.shiki code .s3JHE, html code.shiki .s3JHE{--shiki-light:#0070C1;--shiki-default:#0070C1;--shiki-dark:#F8F8F2}html pre.shiki code .saOXh, html code.shiki .saOXh{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#FF79C6}html pre.shiki code .sakC6, html code.shiki .sakC6{--shiki-light:#0000FF;--shiki-light-font-weight:inherit;--shiki-default:#0000FF;--shiki-default-font-weight:inherit;--shiki-dark:#FF79C6;--shiki-dark-font-weight:bold}html pre.shiki code .sHOzp, html code.shiki .sHOzp{--shiki-light:#795E26;--shiki-default:#795E26;--shiki-dark:#50FA7B}html pre.shiki code .sPzPf, html code.shiki .sPzPf{--shiki-light:#0070C1;--shiki-default:#0070C1;--shiki-dark:#BD93F9}html pre.shiki code .sygFZ, html code.shiki .sygFZ{--shiki-light:#001080;--shiki-light-font-style:inherit;--shiki-default:#001080;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}html pre.shiki code .s34zl, html code.shiki .s34zl{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#FF79C6}html pre.shiki code .sjR7W, html code.shiki .sjR7W{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#BD93F9}html pre.shiki code .spgvN, html code.shiki .spgvN{--shiki-light:#098658;--shiki-default:#098658;--shiki-dark:#BD93F9}html pre.shiki code .sFs1U, html code.shiki .sFs1U{--shiki-light:#267F99;--shiki-light-font-style:inherit;--shiki-default:#267F99;--shiki-default-font-style:inherit;--shiki-dark:#8BE9FD;--shiki-dark-font-style:italic}html pre.shiki code .s1lnM, html code.shiki .s1lnM{--shiki-light:#000000FF;--shiki-default:#000000FF;--shiki-dark:#F8F8F2}",{"title":227,"searchDepth":228,"depth":228,"links":3040},[3041,3045,3050,3053,3058,3061,3065,3066],{"id":263,"depth":228,"text":264,"children":3042},[3043,3044],{"id":271,"depth":342,"text":272},{"id":307,"depth":342,"text":308},{"id":396,"depth":228,"text":397,"children":3046},[3047,3048,3049],{"id":403,"depth":342,"text":404},{"id":410,"depth":342,"text":411},{"id":417,"depth":342,"text":418},{"id":430,"depth":228,"text":431,"children":3051},[3052],{"id":440,"depth":342,"text":441},{"id":453,"depth":228,"text":454,"children":3054},[3055,3056,3057],{"id":460,"depth":342,"text":461},{"id":1541,"depth":342,"text":1542},{"id":2260,"depth":342,"text":2261},{"id":2896,"depth":228,"text":2897,"children":3059},[3060],{"id":2917,"depth":342,"text":2918},{"id":2957,"depth":228,"text":2958,"children":3062},[3063,3064],{"id":2964,"depth":342,"text":2965},{"id":2974,"depth":342,"text":2975},{"id":2984,"depth":228,"text":2985},{"id":3024,"depth":228,"text":3025},"2026-06-11","A comprehensive, deep-dive guide into protecting your infrastructure against residential proxies, commercial VPNs, and account takeover attacks using advanced IP intelligence and behavioral analytics.",null,"https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1558494949-ef010cbdcc31?auto=format&fit=crop&q=80&w=800",{},"---\ntitle: Combating Residential Proxies and VPNs in Modern Applications\ndescription: A comprehensive, deep-dive guide into protecting your infrastructure against residential proxies, commercial VPNs, and account takeover attacks using advanced IP intelligence and behavioral analytics.\ntags: [\"security\", \"api\", \"fraud-prevention\", \"architecture\", \"networking\"]\nimage: \"https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1558494949-ef010cbdcc31?auto=format&fit=crop&q=80&w=800\"\nauthor: \"Sergio\"\nauthorImg: \"https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F187537278?v=4\"\nauthorGithub: \"https:\u002F\u002Fgithub.com\u002FSergo706\"\nauthorGithubUserName: \"Sergo706\"\nfeatured: true\ndate: 2026-06-11T00:00:00.000Z\nreadingTime: \"35 min\"\n---\n\n# Combating Residential Proxies and VPNs in Modern Applications\n\nProtecting modern web applications requires significantly more than just checking an IP address against a static blocklist. Attackers constantly evolve their techniques. They leverage residential proxies and commercial VPN networks to mask their true origin and bypass rate limits. \n\nThe security industry faces a continuous and escalating challenge. Traditional security layers struggle to differentiate between a legitimate user logging in from their home internet and an automated script routing traffic through a compromised residential proxy network. This comprehensive guide explores the mechanics of residential proxies, the economics driving their use, and the technical strategies you must implement to defend your infrastructure.\n\n::note\nA residential proxy routes traffic through an actual residential internet connection. This makes the traffic appear as though it originates from a standard home user rather than a datacenter, effectively bypassing traditional IP-based filtering.\n::\n\n## The Anatomy of the Threat Landscape\n\nTo effectively defend against a threat, you must first understand how it operates at a fundamental level. The proxy ecosystem is vast, complex, and highly commercialized.\n\n### Types of IP Addresses Used by Attackers\n\nAttackers utilize several categories of IP addresses, each with distinct characteristics and risk profiles:\n\n1. **Datacenter IPs**: These are IP addresses assigned to massive server farms and cloud providers like AWS, Google Cloud, DigitalOcean, and Hetzner. They are cheap, fast, and highly available. However, they are also incredibly easy to detect and block. Legitimate consumers rarely browse the web from an AWS data center.\n2. **Commercial VPNs**: Services like NordVPN, ExpressVPN, and ProtonVPN route user traffic through shared egress IPs. While often used by privacy-conscious individuals, attackers heavily abuse them to mask their geographic location and true identity.\n3. **Residential Proxies**: These IPs belong to standard Internet Service Providers (ISPs) like Comcast, AT&T, and BT. They are attached to actual residential homes. Traffic originating from these IPs carries an inherently high reputation.\n4. **Mobile Proxies**: Similar to residential proxies, but the IPs belong to cellular carriers (e.g., Verizon, T-Mobile, Vodafone). These are the most difficult to block because thousands of legitimate users often share a single mobile IP via Carrier-Grade NAT (CGNAT).\n\n### How Residential Proxy Networks are Built\n\nUnderstanding how attackers acquire residential IPs is critical. They do not purchase these directly from ISPs. Instead, residential proxy networks are formed through various methods, many of which reside in an ethical gray area or are outright illegal.\n\nSome networks operate legitimately by offering users free software or premium features in exchange for sharing their idle bandwidth. Users agree to the terms of service, effectively turning their home router or computer into an exit node for the proxy network.\n\nHowever, many residential proxy networks are botnets built via malware. Attackers infect thousands of IoT devices, smart TVs, home routers, and personal computers. They then sell access to this compromised network to other malicious actors on the dark web or through shady proxy reselling platforms.\n\n```mermaid\ngraph TD\n    A[Attacker \u002F Scraper Script] -->|Routes Traffic| B(Proxy Network Controller)\n    B --> C[Infected Smart TV]\n    B --> D[Compromised Router]\n    B --> E[User running 'Free' VPN Extension]\n    C -->|Requests| F[Your Application]\n    D -->|Requests| F[Your Application]\n    E -->|Requests| F[Your Application]\n    \n    style A fill:#ffcccc,stroke:#ff0000,stroke-width:2px\n    style F fill:#ccffcc,stroke:#00aa00,stroke-width:2px\n```\n\n## The Economic Incentives\n\nWhy do attackers go through the trouble and expense of using residential proxies? The answer lies in the massive return on investment (ROI) available in digital fraud.\n\n### Account Takeover (ATO) and Credential Stuffing\n\nAttackers purchase massive databases of leaked usernames and passwords. They write scripts to test these credentials against your login endpoints. If they use a single datacenter IP, your rate-limiting rules block them after a few dozen attempts. By routing the requests through thousands of residential proxies, they stay under the rate-limit thresholds and blend in with regular login traffic.\n\n### E-commerce Scalping and Inventory Hoarding\n\nWhen highly anticipated products drop—such as limited-edition sneakers, concert tickets, or next-generation gaming consoles—scalping bots swarm the site. They use residential proxies to bypass per-IP purchase limits. Scalpers can generate millions of dollars in secondary market profits, easily justifying the cost of premium residential proxy subscriptions.\n\n### Payment Fraud and Carding\n\nAttackers use stolen credit card information to purchase digital goods or physical items. They use residential proxies located in the same city or zip code as the stolen credit card's billing address. This geographic consistency easily bypasses simplistic fraud detection systems that flag long-distance mismatches.\n\n::warning\nBlocking entire ISPs or geographic regions to stop these attacks often leads to unacceptable false positive rates. You lock out genuine customers while attempting to stop a handful of malicious actors.\n::\n\n## Utilizing Deep Network Intelligence\n\nIP Shield resolves this challenge by providing deep network intelligence on every request. The platform analyzes the IP address and returns a comprehensive metadata payload. This includes VPN detection flags, proxy network associations, Tor exit node identification, and precise ASN details.\n\nYou use this intelligence to introduce adaptive friction into your user flows. Rather than outright blocking an IP, you challenge high-risk connections with a CAPTCHA, require multi-factor authentication (MFA), or flag the account for manual review.\n\n### The Role of the Autonomous System Number (ASN)\n\nThe Internet is a network of networks. An Autonomous System (AS) is a large network or group of networks that has a unified routing policy. Every AS is assigned an Autonomous System Number (ASN). \n\nBy evaluating the ASN, you determine the organization responsible for the IP address. If the ASN belongs to a known consumer ISP like \"Comcast Cable Communications,\" the traffic is likely residential. If the ASN belongs to \"DigitalOcean, LLC,\" the traffic is from a datacenter.\n\nIP Shield provides the ASN data instantly. You filter traffic based on the network type. For example, you easily block all traffic originating from hosting providers on your consumer-facing login routes, while allowing cellular and residential networks to pass unhindered.\n\n## Implementing the Defense in Code\n\nDefending against residential proxies demands a dynamic security posture. You must integrate real-time intelligence into your edge compute layer or application backend. By doing so, you automatically filter out the noise and focus your resources on serving legitimate users.\n\n### Nuxt 3 and h3 Implementation\n\nIf you are using the modern Nuxt 3 stack, you integrate the IP Shield Network API directly into your server API routes or middleware. You evaluate the IP address before processing sensitive actions like logins, registrations, or checkouts.\n\nHere is an extensive example of how you build a robust, production-ready login handler using Nuxt 3, handling edge cases, proxy headers, and implementing adaptive friction.\n\n~~~typescript [server\u002Fapi\u002Flogin.post.ts]\nimport { IPShield } from '@ip-shield\u002Fsdk';\nimport { sendError, setResponseStatus, createError } from 'h3';\n\n\u002F\u002F Initialize the IP Shield SDK with your secure API key\nconst shield = new IPShield(process.env.IP_SHIELD_API_KEY);\n\nexport default defineEventHandler(async (event) => {\n  \u002F\u002F 1. Safely extract the client IP address\n  \u002F\u002F When behind a CDN or Load Balancer (Cloudflare, AWS ALB), the direct \n  \u002F\u002F connection IP belongs to the CDN. We must inspect the X-Forwarded-For header.\n  const ip = getRequestIP(event, { xForwardedFor: true });\n  \n  if (!ip) {\n    throw createError({\n      statusCode: 400,\n      statusMessage: 'Unable to determine client IP address'\n    });\n  }\n\n  const body = await readBody(event);\n  \n  \u002F\u002F 2. Perform the IP Intelligence Lookup\n  \u002F\u002F We use a try-catch block to ensure that if the IP Shield API is unreachable \n  \u002F\u002F due to network issues, we fail open or handle it gracefully rather than \n  \u002F\u002F blocking all user logins.\n  let networkData;\n  try {\n    networkData = await shield.network.lookup(ip);\n  } catch (err) {\n    console.error('IP Shield lookup failed, failing open for availability', err);\n    \u002F\u002F Proceed with standard authentication, but log the failure\n    return authenticateUser(body.email, body.password);\n  }\n  \n  \u002F\u002F 3. Analyze the Threat Vectors\n  const isHighRisk = networkData.isProxy || networkData.isVpn || networkData.isTor;\n  const isDatacenter = networkData.asn.type === 'hosting';\n  \n  \u002F\u002F 4. Execute the Security Policy\n  if (networkData.isTor) {\n    \u002F\u002F Tor traffic is almost exclusively malicious in an e-commerce context.\n    \u002F\u002F We block it outright.\n    setResponseStatus(event, 403);\n    return { \n      error: 'access_denied', \n      message: 'Connections from the Tor network are not permitted.' \n    };\n  }\n\n  if (isDatacenter) {\n    \u002F\u002F Legitimate users do not log in from AWS servers. This is likely a script.\n    setResponseStatus(event, 403);\n    return { \n      error: 'access_denied', \n      message: 'Datacenter IP ranges are not permitted. Please disable your VPN.' \n    };\n  }\n\n  if (isHighRisk) {\n    \u002F\u002F The IP belongs to a residential proxy or commercial VPN. \n    \u002F\u002F It might be a malicious actor, or it might be a privacy-conscious user.\n    \u002F\u002F We do NOT block them outright. Instead, we introduce adaptive friction.\n    setResponseStatus(event, 401);\n    return { \n      error: 'verification_required', \n      challengeType: 'mfa',\n      message: 'Unusual network detected. Please enter the code sent to your mobile device.' \n    };\n  }\n  \n  \u002F\u002F 5. If all checks pass, proceed with standard authentication\n  const authResult = await authenticateUser(body.email, body.password);\n  \n  if (!authResult.success) {\n    \u002F\u002F Even if the IP is safe, standard credential checks still apply\n    throw createError({\n      statusCode: 401,\n      statusMessage: 'Invalid credentials'\n    });\n  }\n\n  return {\n    success: true,\n    token: authResult.token,\n    user: authResult.user\n  };\n});\n~~~\n\n::tip\nAlways test your IP extraction logic thoroughly. Misconfiguring the `x-forwarded-for` header parsing can lead to IP spoofing vulnerabilities, where an attacker injects a fake IP address to bypass your security checks.\n::\n\n### Express.js Implementation\n\nIf your backend is built on traditional Express.js, the concepts remain identical, though the implementation syntax differs slightly. You implement this as a reusable middleware function that you attach to specific high-risk routes.\n\n~~~javascript [middleware\u002FipIntelligence.js]\nconst { IPShield } = require('@ip-shield\u002Fsdk');\nconst shield = new IPShield(process.env.IP_SHIELD_API_KEY);\n\n\u002F**\n * Express middleware to evaluate IP risk before processing requests\n *\u002F\nasync function ipIntelligenceMiddleware(req, res, next) {\n  \u002F\u002F Extract IP, respecting trust proxy settings in Express\n  const ip = req.ip;\n\n  try {\n    const networkData = await shield.network.lookup(ip);\n    \n    \u002F\u002F Attach the intelligence data to the request object for downstream use\n    req.ipIntelligence = networkData;\n\n    \u002F\u002F Hard block for Tor and Datacenters\n    if (networkData.isTor || networkData.asn.type === 'hosting') {\n      return res.status(403).json({\n        error: 'Forbidden',\n        message: 'Your network type is not permitted to access this resource.'\n      });\n    }\n\n    \u002F\u002F Flag for downstream adaptive friction\n    if (networkData.isProxy || networkData.isVpn) {\n      req.requiresMfa = true;\n    }\n\n    next();\n  } catch (error) {\n    console.error('IP Shield API Error:', error);\n    \u002F\u002F Fail open to prevent locking out legitimate users during an outage\n    next();\n  }\n}\n\nmodule.exports = ipIntelligenceMiddleware;\n~~~\n\nYou then apply this middleware to your sensitive routes:\n\n~~~javascript [routes\u002Fauth.js]\nconst express = require('express');\nconst router = express.Router();\nconst ipIntelligence = require('..\u002Fmiddleware\u002FipIntelligence');\n\n\u002F\u002F Apply the IP intelligence middleware specifically to the login route\nrouter.post('\u002Flogin', ipIntelligence, async (req, res) => {\n  const { email, password } = req.body;\n\n  \u002F\u002F Check if the middleware flagged this request for MFA\n  if (req.requiresMfa) {\n    return res.status(401).json({\n      error: 'MFA_REQUIRED',\n      message: 'Please complete multi-factor authentication.'\n    });\n  }\n\n  \u002F\u002F Standard login logic...\n  res.json({ success: true });\n});\n\nmodule.exports = router;\n~~~\n\n### Implementing at the Edge with Cloudflare Workers\n\nFor maximum performance, you move your security logic as close to the user as possible. Cloudflare Workers allow you to intercept requests at the CDN edge, before they ever reach your origin server. This protects your backend infrastructure from the computational load of processing malicious requests.\n\n~~~javascript [worker.js]\nexport default {\n  async fetch(request, env, ctx) {\n    const url = new URL(request.url);\n    \n    \u002F\u002F Only run the heavy IP check on sensitive endpoints to save costs and latency\n    if (url.pathname !== '\u002Fapi\u002Fv1\u002Flogin' && url.pathname !== '\u002Fapi\u002Fv1\u002Fcheckout') {\n      return fetch(request);\n    }\n\n    \u002F\u002F Cloudflare provides the client IP in the headers\n    const clientIP = request.headers.get('CF-Connecting-IP');\n\n    try {\n      \u002F\u002F Make a subrequest to the IP Shield API\n      const shieldResponse = await fetch(`https:\u002F\u002Fip-shield.riavzon.com\u002Fv1\u002Fnetwork\u002F${clientIP}`, {\n        headers: {\n          'Authorization': `Bearer ${env.IP_SHIELD_API_KEY}`\n        }\n      });\n\n      if (shieldResponse.ok) {\n        const networkData = await shieldResponse.json();\n\n        \u002F\u002F Implement blocking logic at the edge\n        if (networkData.isTor || networkData.asn.type === 'hosting') {\n          return new Response(JSON.stringify({ error: 'Access Denied' }), {\n            status: 403,\n            headers: { 'Content-Type': 'application\u002Fjson' }\n          });\n        }\n        \n        \u002F\u002F Pass intelligence data to the origin server via custom headers\n        const modifiedRequest = new Request(request);\n        if (networkData.isProxy || networkData.isVpn) {\n          modifiedRequest.headers.set('X-Requires-Adaptive-Friction', 'true');\n        }\n        \n        return fetch(modifiedRequest);\n      }\n    } catch (err) {\n      \u002F\u002F Fail open on error\n      console.error('Edge security check failed:', err);\n    }\n\n    return fetch(request);\n  }\n};\n~~~\n\n::important\nWhen implementing edge security, always ensure your origin server is configured to ONLY accept traffic from your Edge provider (e.g., Cloudflare IP ranges). Otherwise, attackers simply bypass the edge worker by connecting to your origin IP directly.\n::\n\n## The Challenge of IPv6 and Subnet Hopping\n\nAs the internet transitions to IPv6, attackers gain access to an unimaginably large address space. Traditional IPv4 blocklists fail against IPv6 because an attacker can cycle through billions of IP addresses within a single `\u002F64` subnet.\n\nWhen dealing with IPv6, you must adjust your defensive strategies. You no longer block or evaluate individual `\u002F128` IP addresses. Instead, you apply your logic to the entire `\u002F64` subnet. IP Shield handles this complexity automatically, aggregating intelligence across IPv6 blocks so that if an attacker hops IPs within their assigned subnet, the threat score remains accurate.\n\n### Subnet Aggregation Strategies\n\n1. **IPv4**: Track and evaluate on a `\u002F32` (individual IP) or `\u002F24` (C-class subnet) basis.\n2. **IPv6**: Always track and evaluate on a minimum of a `\u002F64` basis.\n\nIf you observe malicious activity from `2001:db8:1234:5678:90ab:cdef:0123:4567`, you should apply security friction to the entire `2001:db8:1234:5678::\u002F64` range.\n\n## Advanced Techniques: Correlating Signals\n\nIP intelligence is incredibly powerful, but it becomes exponentially more effective when combined with other security signals. To build a truly resilient system against advanced residential proxies, you must correlate network data with client-side telemetry.\n\n### Device Fingerprinting\n\nAttackers using residential proxies often route traffic from hundreds of IPs, but they might use the same underlying hardware or scraping script for all requests. By implementing device fingerprinting—analyzing the Canvas API rendering, WebGL drivers, audio context, and font stacks—you generate a unique identifier for the machine making the request.\n\nIf you observe 500 different residential IPs logging into 500 different accounts, but all 500 requests share the exact same highly unique device fingerprint, you definitively identify an ongoing attack.\n\n### Behavioral Biometrics\n\nHow does the user interact with the page? Does the mouse move in perfectly straight lines? Are keystrokes registering with zero variance in timing? Human behavior is messy and unpredictable. Scrapers and bots, even those using residential proxies, often exhibit robotic perfection.\n\nBy combining IP Shield's network data with behavioral biometrics, you achieve unprecedented detection accuracy.\n\n## Creating a Splunk Dashboard for Traffic Analysis\n\nMonitoring your traffic is just as important as blocking it. By logging the IP Shield metadata alongside your standard access logs, you create powerful visualizations in tools like Splunk, ELK (Elasticsearch, Logstash, Kibana), or Datadog.\n\nHere is an example Splunk SPL query to identify the top ASNs associated with failed login attempts:\n\n```spl\nindex=production sourcetype=api_logs endpoint=\"\u002Fapi\u002Fv1\u002Flogin\" status=401\n| stats count by ip_intelligence.asn.name, ip_intelligence.asn.type\n| sort - count\n| head 20\n```\n\nThis query instantly reveals if a specific datacenter or proxy network is currently targeting your authentication endpoints, allowing your security team to respond proactively.\n\n## Conclusion\n\nThe era of simple IP blocking is over. The commoditization of residential proxy networks has fundamentally shifted the balance of power, granting attackers the ability to blend seamlessly into legitimate user traffic.\n\nTo survive in this environment, your applications must become contextually aware. By integrating deep network intelligence from tools like IP Shield into your authentication flows, edge routers, and monitoring dashboards, you regain visibility. You transition from a static, reactive security posture to a dynamic, adaptive defense capable of thwarting the most sophisticated modern attacks.\n\nSecurity is not a final destination; it is a continuous arms race. Equip your infrastructure with the intelligence it needs to win.\n","35 min",{"title":129,"description":3068},[3076,3077,3078,3079,3080],"security","api","fraud-prevention","architecture","networking","b6CYd4tNLDxwFPDFru5A8e_pI5HYGT4oPX9HIBKLUxQ",{"id":3083,"title":137,"author":239,"authorGithub":240,"authorGithubUserName":241,"authorImg":242,"body":3084,"date":3067,"description":4576,"extension":231,"featured":61,"icon":3069,"image":4577,"meta":4578,"navigation":10,"path":138,"rawbody":4579,"readingTime":4580,"seo":4581,"stem":139,"tags":4582,"__hash__":4587},"blog\u002Fblog\u002Fthe-evolution-of-bot-management.md",{"type":215,"value":3085,"toc":4558},[3086,3089,3092,3110,3113,3118,3122,3125,3129,3146,3150,3157,3161,3168,3172,3175,3259,3264,3268,3271,3281,3284,3288,3291,3335,3338,3342,3345,3348,3352,3355,4203,4208,4212,4215,4454,4457,4501,4505,4508,4514,4517,4521,4544,4546,4549,4552,4555],[218,3087,137],{"id":3088},"the-evolution-of-bot-management-and-user-agent-parsing",[223,3090,3091],{},"Bot traffic comprises nearly half of all internet traffic today. While some bots index your content for search engines, others scrape your proprietary data, scalp your inventory, probe your applications for vulnerabilities, or consume massive amounts of your bandwidth. Managing this traffic effectively determines the performance, cost-efficiency, and security of your digital infrastructure.",[223,3093,3094,3095,3098,3099,521,3102,3105,3106,3109],{},"In the early days of the web, bot management was incredibly straightforward. It meant reading the ",[325,3096,3097],{},"User-Agent"," HTTP header. Developers simply wrote regular expressions to block strings containing ",[325,3100,3101],{},"python-requests",[325,3103,3104],{},"curl",", or ",[325,3107,3108],{},"Java\u002F1.8.0",". Today, malicious actors spoof their headers to perfectly mimic Chrome running on a macOS device, rendering naive string matching obsolete.",[223,3111,3112],{},"This comprehensive guide explores the multi-generational evolution of bot architecture, why legacy detection mechanisms fail, and how to implement modern, context-aware bot mitigation strategies using IP Shield and advanced server-side architectures.",[255,3114,3115],{},[223,3116,3117],{},"A User-Agent string identifies the client software originating the request. Because the client controls this header entirely, it provides no inherent cryptographic proof of identity. Relying on it for security is equivalent to trusting a visitor's handwritten name tag.",[261,3119,3121],{"id":3120},"the-generations-of-web-scraping","The Generations of Web Scraping",[223,3123,3124],{},"To understand how to defeat modern bots, we must trace their evolutionary history. As defensive mechanisms improved, scraper technology evolved in direct response, creating a fascinating arms race.",[269,3126,3128],{"id":3127},"generation-1-the-scripted-clients","Generation 1: The Scripted Clients",[223,3130,3131,3132,521,3135,3138,3139,3142,3143,3145],{},"The earliest bots were simple HTTP clients. Tools like ",[325,3133,3134],{},"cURL",[325,3136,3137],{},"wget",", and libraries like ",[325,3140,3141],{},"urllib"," or ",[325,3144,3101],{}," made bare-bones HTTP GET and POST requests. They were extremely fast and efficient but completely incapable of executing JavaScript. If a website rendered content client-side via React or Angular, Generation 1 bots failed entirely. They were also easily detected by their default User-Agent strings.",[269,3147,3149],{"id":3148},"generation-2-the-early-headless-browsers","Generation 2: The Early Headless Browsers",[223,3151,3152,3153,3156],{},"As the web moved towards Single Page Applications (SPAs), bots needed to execute JavaScript. Projects like PhantomJS emerged, providing a scriptable, headless WebKit engine. While they could render JS, they leaked massive amounts of identifiable information. Security tools easily detected them by checking for variables like ",[325,3154,3155],{},"window._phantom"," or analyzing their unique TLS fingerprint.",[269,3158,3160],{"id":3159},"generation-3-the-modern-headless-era","Generation 3: The Modern Headless Era",[223,3162,3163,3164,3167],{},"Today, attackers utilize headless versions of modern browsers controlled via frameworks like Puppeteer, Playwright, and Selenium. These tools execute JavaScript, solve simple CAPTCHAs, and mimic human interaction patterns perfectly. Furthermore, developers have created \"stealth\" plugins (e.g., ",[325,3165,3166],{},"puppeteer-extra-plugin-stealth",") designed specifically to patch the JavaScript variables and inconsistencies that anti-bot software looks for. They render pages just like a real user, making detection incredibly difficult at the application layer.",[269,3169,3171],{"id":3170},"generation-4-ai-agents-and-distributed-scrapers","Generation 4: AI Agents and Distributed Scrapers",[223,3173,3174],{},"We are currently entering the fourth generation. Bots are no longer simple scripts; they are AI-driven agents powered by Large Language Models (LLMs) that can navigate complex dynamic UIs, understand semantic page layouts, and dynamically adjust their scraping strategies when website structures change. When an attacker pairs these AI agents with a rotating residential proxy network, the traffic looks indistinguishable from organic human user growth.",[319,3176,3178],{"className":321,"code":3177,"language":323,"meta":227,"style":227},"sequenceDiagram\n    participant AI as AI Scraper Agent\n    participant Proxy as Residential Proxy Pool\n    participant WAF as Web Application Firewall\n    participant App as Your Application\n\n    AI->>Proxy: Request Page (Spoofed Chrome UA)\n    Proxy->>WAF: Forward Request via Home IP\n    WAF->>WAF: Check IP Reputation (Passes)\n    WAF->>WAF: Check User-Agent (Passes)\n    WAF->>App: Forward Request\n    App-->>WAF: Return HTML payload\n    WAF-->>Proxy: Return HTML payload\n    Proxy-->>AI: Return HTML payload\n    AI->>AI: LLM parses unstructured DOM\n    AI->>Proxy: Proceed to next logical step\n",[325,3179,3180,3185,3190,3195,3200,3205,3209,3214,3219,3224,3229,3234,3239,3244,3249,3254],{"__ignoreMap":227},[328,3181,3182],{"class":330,"line":331},[328,3183,3184],{},"sequenceDiagram\n",[328,3186,3187],{"class":330,"line":228},[328,3188,3189],{},"    participant AI as AI Scraper Agent\n",[328,3191,3192],{"class":330,"line":342},[328,3193,3194],{},"    participant Proxy as Residential Proxy Pool\n",[328,3196,3197],{"class":330,"line":348},[328,3198,3199],{},"    participant WAF as Web Application Firewall\n",[328,3201,3202],{"class":330,"line":354},[328,3203,3204],{},"    participant App as Your Application\n",[328,3206,3207],{"class":330,"line":360},[328,3208,546],{"emptyLinePlaceholder":10},[328,3210,3211],{"class":330,"line":366},[328,3212,3213],{},"    AI->>Proxy: Request Page (Spoofed Chrome UA)\n",[328,3215,3216],{"class":330,"line":372},[328,3217,3218],{},"    Proxy->>WAF: Forward Request via Home IP\n",[328,3220,3221],{"class":330,"line":378},[328,3222,3223],{},"    WAF->>WAF: Check IP Reputation (Passes)\n",[328,3225,3226],{"class":330,"line":384},[328,3227,3228],{},"    WAF->>WAF: Check User-Agent (Passes)\n",[328,3230,3231],{"class":330,"line":390},[328,3232,3233],{},"    WAF->>App: Forward Request\n",[328,3235,3236],{"class":330,"line":683},[328,3237,3238],{},"    App-->>WAF: Return HTML payload\n",[328,3240,3241],{"class":330,"line":689},[328,3242,3243],{},"    WAF-->>Proxy: Return HTML payload\n",[328,3245,3246],{"class":330,"line":706},[328,3247,3248],{},"    Proxy-->>AI: Return HTML payload\n",[328,3250,3251],{"class":330,"line":718},[328,3252,3253],{},"    AI->>AI: LLM parses unstructured DOM\n",[328,3255,3256],{"class":330,"line":733},[328,3257,3258],{},"    AI->>Proxy: Proceed to next logical step\n",[423,3260,3261],{},[223,3262,3263],{},"Relying solely on User-Agent parsing to block bots leaves your application completely exposed to modern headless scraping frameworks and AI agents. You must look beyond the header.",[261,3265,3267],{"id":3266},"verifying-legitimate-bots-the-seo-dilemma","Verifying Legitimate Bots: The SEO Dilemma",[223,3269,3270],{},"Not all automated traffic is harmful. Search engine crawlers like Googlebot, Bingbot, Yandex, and specialized SEO tools (Ahrefs, Semrush) must access your site to ensure your business remains visible online. You cannot afford to block them accidentally with overly aggressive anti-bot rules; doing so destroys your organic search rankings.",[223,3272,3273,3274,3277,3278,583],{},"However, malicious scrapers frequently spoof the ",[325,3275,3276],{},"Googlebot"," User-Agent string to bypass security filters. They know that naive WAF configurations include rules like: ",[325,3279,3280],{},"IF User-Agent CONTAINS \"Googlebot\" THEN ALLOW",[223,3282,3283],{},"You must verify that the bot claiming to be Google actually originates from an IP address owned by Google. This requires cross-referencing the claimed identity with the underlying network infrastructure.",[269,3285,3287],{"id":3286},"the-verification-process-reverse-dns","The Verification Process: Reverse DNS",[223,3289,3290],{},"The traditional way to verify a search engine crawler is performing a Reverse DNS (rDNS) lookup followed by a Forward DNS lookup.",[277,3292,3293,3306,3318,3326],{},[280,3294,3295,3298,3299,3302,3303,583],{},[283,3296,3297],{},"Reverse DNS Lookup",": You query the DNS pointer (PTR) record of the incoming IP address. For example, doing an rDNS lookup on ",[325,3300,3301],{},"66.249.66.1"," returns ",[325,3304,3305],{},"crawl-66-249-66-1.googlebot.com",[280,3307,3308,3311,3312,3142,3315,583],{},[283,3309,3310],{},"Domain Verification",": You verify that the domain ends in ",[325,3313,3314],{},"googlebot.com",[325,3316,3317],{},"google.com",[280,3319,3320,3323,3324,1799],{},[283,3321,3322],{},"Forward DNS Lookup",": To prevent an attacker from simply setting up a fake PTR record on their own server, you must do a forward DNS lookup on the domain returned in step 1 (",[325,3325,3305],{},[280,3327,3328,3331,3332,3334],{},[283,3329,3330],{},"Final Match",": If the IP returned in step 3 matches the original IP ",[325,3333,3301],{},", the crawler is verified.",[223,3336,3337],{},"Performing this three-step DNS dance for every single incoming request introduces massive latency to your application. It is computationally expensive and slow.",[269,3339,3341],{"id":3340},"the-modern-solution-ip-shield-bot-api","The Modern Solution: IP Shield Bot API",[223,3343,3344],{},"IP Shield simplifies this verification process dramatically. The User Agent & Bot Parser API analyzes the header string and automatically performs the reverse DNS lookups, ASN verification, and signature matching in real-time. It explicitly flags whether a known crawler is verified or spoofed.",[223,3346,3347],{},"You implement this check in your edge routing layer or middleware. This ensures fake crawlers get dropped before they consume your application resources, while legitimate SEO bots pass through smoothly.",[261,3349,3351],{"id":3350},"implementing-bot-protection-middleware","Implementing Bot Protection Middleware",[223,3353,3354],{},"Here is a comprehensive example of verifying search engine crawlers and blocking malicious bots using a Nuxt 3 server middleware. This implementation handles rate limiting, safe-listing, spoof detection, and adaptive responses.",[319,3356,3359],{"className":470,"code":3357,"filename":3358,"language":473,"meta":227,"style":227},"import { IPShield } from '@ip-shield\u002Fsdk';\nimport { sendError, setResponseStatus, createError } from 'h3';\n\n\u002F\u002F Initialize the SDK\nconst shield = new IPShield(process.env.IP_SHIELD_API_KEY);\n\n\u002F\u002F Cache verified IPs in memory to reduce API calls and latency\n\u002F\u002F In production, use Redis or unstorage for distributed caching\nconst verifiedBotCache = new Set\u003Cstring>();\n\nexport default defineEventHandler(async (event) => {\n  \u002F\u002F Extract essential request metadata\n  const ip = getRequestIP(event, { xForwardedFor: true }) || '';\n  const userAgent = getRequestHeader(event, 'user-agent') || '';\n  const path = event.path;\n  \n  \u002F\u002F Skip static assets to save compute resources\n  if (path.startsWith('\u002F_nuxt\u002F') || path.match(\u002F\\.(js|css|png|jpg|svg|ico)$\u002F)) {\n    return;\n  }\n\n  \u002F\u002F Fast path: if we've already verified this IP recently, let it through\n  if (verifiedBotCache.has(ip)) {\n    return;\n  }\n  \n  try {\n    \u002F\u002F Cross-reference the IP and User-Agent with IP Shield\n    const botData = await shield.bots.analyze({ ip, userAgent });\n    \n    \u002F\u002F Scenario 1: The request claims to be a good bot but the IP doesn't match\n    if (botData.isBot && botData.isSpoofed) {\n      console.warn(`Spoofed bot detected from IP: ${ip} claiming to be: ${userAgent}`);\n      \n      \u002F\u002F We drop spoofed bots immediately with a 403 Forbidden.\n      setResponseStatus(event, 403);\n      return { \n        error: 'spoofed_identity_detected',\n        message: 'Your network origin does not match your claimed identity.'\n      };\n    }\n    \n    \u002F\u002F Scenario 2: It is a verified, legitimate search engine crawler\n    if (botData.isVerifiedCrawler) {\n      \u002F\u002F Cache the IP to speed up subsequent requests from this crawler\n      verifiedBotCache.add(ip);\n      \n      \u002F\u002F Optionally limit the cache size to prevent memory leaks\n      if (verifiedBotCache.size > 10000) verifiedBotCache.clear();\n      \n      return; \u002F\u002F Allow the request to proceed\n    }\n    \n    \u002F\u002F Scenario 3: It is an unverified, generic scraper script (e.g., python-requests)\n    \u002F\u002F We don't want these consuming our server rendering resources.\n    if (botData.isBot && !botData.isVerifiedCrawler) {\n      setResponseStatus(event, 429);\n      return { \n        error: 'automated_traffic_blocked',\n        message: 'Automated access is restricted. Please use our official API.'\n      };\n    }\n\n    \u002F\u002F Scenario 4: It appears to be a legitimate human user.\n    \u002F\u002F Proceed to the next middleware or route handler.\n    return;\n    \n  } catch (err) {\n    \u002F\u002F Fail open: if the IP Shield API is down, we don't want to block organic traffic\n    console.error('Bot analysis failed:', err);\n    return;\n  }\n});\n","server\u002Fmiddleware\u002Fbot-protection.ts",[325,3360,3361,3381,3409,3413,3418,3444,3448,3453,3458,3481,3485,3507,3512,3545,3578,3597,3601,3606,3694,3700,3704,3708,3713,3733,3739,3743,3747,3753,3758,3792,3796,3801,3826,3859,3864,3869,3884,3890,3905,3918,3923,3927,3931,3936,3951,3956,3972,3976,3981,4011,4015,4025,4029,4033,4038,4043,4068,4083,4089,4104,4117,4121,4125,4129,4134,4139,4145,4149,4161,4166,4189,4195,4199],{"__ignoreMap":227},[328,3362,3363,3365,3367,3369,3371,3373,3375,3377,3379],{"class":330,"line":331},[328,3364,481],{"class":480},[328,3366,485],{"class":484},[328,3368,489],{"class":488},[328,3370,492],{"class":484},[328,3372,495],{"class":480},[328,3374,499],{"class":498},[328,3376,503],{"class":502},[328,3378,506],{"class":498},[328,3380,509],{"class":484},[328,3382,3383,3385,3387,3389,3391,3393,3395,3397,3399,3401,3403,3405,3407],{"class":330,"line":228},[328,3384,481],{"class":480},[328,3386,485],{"class":484},[328,3388,518],{"class":488},[328,3390,521],{"class":484},[328,3392,524],{"class":488},[328,3394,521],{"class":484},[328,3396,529],{"class":488},[328,3398,492],{"class":484},[328,3400,495],{"class":480},[328,3402,499],{"class":498},[328,3404,269],{"class":502},[328,3406,506],{"class":498},[328,3408,509],{"class":484},[328,3410,3411],{"class":330,"line":342},[328,3412,546],{"emptyLinePlaceholder":10},[328,3414,3415],{"class":330,"line":348},[328,3416,3417],{"class":551},"\u002F\u002F Initialize the SDK\n",[328,3419,3420,3422,3424,3426,3428,3430,3432,3434,3436,3438,3440,3442],{"class":330,"line":354},[328,3421,558],{"class":557},[328,3423,562],{"class":561},[328,3425,566],{"class":565},[328,3427,570],{"class":569},[328,3429,574],{"class":573},[328,3431,577],{"class":484},[328,3433,580],{"class":488},[328,3435,583],{"class":484},[328,3437,586],{"class":488},[328,3439,583],{"class":484},[328,3441,592],{"class":591},[328,3443,595],{"class":484},[328,3445,3446],{"class":330,"line":360},[328,3447,546],{"emptyLinePlaceholder":10},[328,3449,3450],{"class":330,"line":366},[328,3451,3452],{"class":551},"\u002F\u002F Cache verified IPs in memory to reduce API calls and latency\n",[328,3454,3455],{"class":330,"line":372},[328,3456,3457],{"class":551},"\u002F\u002F In production, use Redis or unstorage for distributed caching\n",[328,3459,3460,3462,3465,3467,3469,3472,3475,3478],{"class":330,"line":378},[328,3461,558],{"class":557},[328,3463,3464],{"class":561}," verifiedBotCache",[328,3466,566],{"class":565},[328,3468,570],{"class":569},[328,3470,3471],{"class":573}," Set",[328,3473,3474],{"class":484},"\u003C",[328,3476,3477],{"class":1970},"string",[328,3479,3480],{"class":484},">();\n",[328,3482,3483],{"class":330,"line":384},[328,3484,546],{"emptyLinePlaceholder":10},[328,3486,3487,3489,3491,3493,3495,3497,3499,3501,3503,3505],{"class":330,"line":390},[328,3488,604],{"class":480},[328,3490,607],{"class":480},[328,3492,610],{"class":573},[328,3494,577],{"class":484},[328,3496,615],{"class":557},[328,3498,618],{"class":484},[328,3500,622],{"class":621},[328,3502,625],{"class":484},[328,3504,628],{"class":557},[328,3506,631],{"class":484},[328,3508,3509],{"class":330,"line":683},[328,3510,3511],{"class":551},"  \u002F\u002F Extract essential request metadata\n",[328,3513,3514,3516,3518,3520,3522,3524,3526,3528,3530,3532,3534,3537,3540,3543],{"class":330,"line":689},[328,3515,651],{"class":557},[328,3517,654],{"class":561},[328,3519,566],{"class":565},[328,3521,659],{"class":573},[328,3523,577],{"class":484},[328,3525,622],{"class":488},[328,3527,666],{"class":484},[328,3529,669],{"class":488},[328,3531,673],{"class":672},[328,3533,677],{"class":676},[328,3535,3536],{"class":484}," }) ",[328,3538,3539],{"class":565},"||",[328,3541,3542],{"class":498}," ''",[328,3544,509],{"class":484},[328,3546,3547,3549,3552,3554,3557,3559,3561,3563,3565,3568,3570,3572,3574,3576],{"class":330,"line":706},[328,3548,651],{"class":557},[328,3550,3551],{"class":561}," userAgent",[328,3553,566],{"class":565},[328,3555,3556],{"class":573}," getRequestHeader",[328,3558,577],{"class":484},[328,3560,622],{"class":488},[328,3562,521],{"class":484},[328,3564,506],{"class":498},[328,3566,3567],{"class":502},"user-agent",[328,3569,506],{"class":498},[328,3571,625],{"class":484},[328,3573,3539],{"class":565},[328,3575,3542],{"class":498},[328,3577,509],{"class":484},[328,3579,3580,3582,3585,3587,3590,3592,3595],{"class":330,"line":718},[328,3581,651],{"class":557},[328,3583,3584],{"class":561}," path",[328,3586,566],{"class":565},[328,3588,3589],{"class":488}," event",[328,3591,583],{"class":484},[328,3593,3594],{"class":488},"path",[328,3596,509],{"class":484},[328,3598,3599],{"class":330,"line":733},[328,3600,686],{"class":484},[328,3602,3603],{"class":330,"line":749},[328,3604,3605],{"class":551},"  \u002F\u002F Skip static assets to save compute resources\n",[328,3607,3608,3610,3612,3614,3616,3619,3621,3623,3626,3628,3630,3632,3634,3636,3639,3641,3645,3649,3652,3656,3660,3663,3665,3668,3670,3673,3675,3678,3680,3683,3686,3689,3691],{"class":330,"line":755},[328,3609,692],{"class":480},[328,3611,618],{"class":484},[328,3613,3594],{"class":488},[328,3615,583],{"class":484},[328,3617,3618],{"class":573},"startsWith",[328,3620,577],{"class":484},[328,3622,506],{"class":498},[328,3624,3625],{"class":502},"\u002F_nuxt\u002F",[328,3627,506],{"class":498},[328,3629,625],{"class":484},[328,3631,3539],{"class":565},[328,3633,3584],{"class":488},[328,3635,583],{"class":484},[328,3637,3638],{"class":573},"match",[328,3640,577],{"class":484},[328,3642,3644],{"class":3643},"sRg35","\u002F",[328,3646,3648],{"class":3647},"skAEd","\\.",[328,3650,577],{"class":3651},"s63D3",[328,3653,3655],{"class":3654},"sIcdS","js",[328,3657,3659],{"class":3658},"st6lo","|",[328,3661,3662],{"class":3654},"css",[328,3664,3659],{"class":3658},[328,3666,3667],{"class":3654},"png",[328,3669,3659],{"class":3658},[328,3671,3672],{"class":3654},"jpg",[328,3674,3659],{"class":3658},[328,3676,3677],{"class":3654},"svg",[328,3679,3659],{"class":3658},[328,3681,3682],{"class":3654},"ico",[328,3684,3685],{"class":3651},")",[328,3687,3688],{"class":3658},"$",[328,3690,3644],{"class":3643},[328,3692,3693],{"class":484},")) {\n",[328,3695,3696,3698],{"class":330,"line":761},[328,3697,915],{"class":480},[328,3699,509],{"class":484},[328,3701,3702],{"class":330,"line":766},[328,3703,758],{"class":484},[328,3705,3706],{"class":330,"line":788},[328,3707,546],{"emptyLinePlaceholder":10},[328,3709,3710],{"class":330,"line":793},[328,3711,3712],{"class":551},"  \u002F\u002F Fast path: if we've already verified this IP recently, let it through\n",[328,3714,3715,3717,3719,3722,3724,3727,3729,3731],{"class":330,"line":799},[328,3716,692],{"class":480},[328,3718,618],{"class":484},[328,3720,3721],{"class":488},"verifiedBotCache",[328,3723,583],{"class":484},[328,3725,3726],{"class":573},"has",[328,3728,577],{"class":484},[328,3730,700],{"class":488},[328,3732,3693],{"class":484},[328,3734,3735,3737],{"class":330,"line":805},[328,3736,915],{"class":480},[328,3738,509],{"class":484},[328,3740,3741],{"class":330,"line":811},[328,3742,758],{"class":484},[328,3744,3745],{"class":330,"line":817},[328,3746,686],{"class":484},[328,3748,3749,3751],{"class":330,"line":828},[328,3750,831],{"class":480},[328,3752,631],{"class":484},[328,3754,3755],{"class":330,"line":836},[328,3756,3757],{"class":551},"    \u002F\u002F Cross-reference the IP and User-Agent with IP Shield\n",[328,3759,3760,3762,3765,3767,3769,3771,3773,3776,3778,3781,3783,3785,3787,3790],{"class":330,"line":864},[328,3761,1688],{"class":557},[328,3763,3764],{"class":561}," botData",[328,3766,566],{"class":565},[328,3768,776],{"class":480},[328,3770,562],{"class":488},[328,3772,583],{"class":484},[328,3774,3775],{"class":488},"bots",[328,3777,583],{"class":484},[328,3779,3780],{"class":573},"analyze",[328,3782,2227],{"class":484},[328,3784,700],{"class":488},[328,3786,521],{"class":484},[328,3788,3789],{"class":488},"userAgent",[328,3791,680],{"class":484},[328,3793,3794],{"class":330,"line":880},[328,3795,381],{"class":484},[328,3797,3798],{"class":330,"line":906},[328,3799,3800],{"class":551},"    \u002F\u002F Scenario 1: The request claims to be a good bot but the IP doesn't match\n",[328,3802,3803,3805,3807,3810,3812,3815,3817,3819,3821,3824],{"class":330,"line":912},[328,3804,1749],{"class":480},[328,3806,618],{"class":484},[328,3808,3809],{"class":488},"botData",[328,3811,583],{"class":484},[328,3813,3814],{"class":488},"isBot",[328,3816,2362],{"class":565},[328,3818,3764],{"class":488},[328,3820,583],{"class":484},[328,3822,3823],{"class":488},"isSpoofed",[328,3825,703],{"class":484},[328,3827,3828,3830,3832,3835,3837,3840,3842,3844,3846,3849,3851,3853,3855,3857],{"class":330,"line":942},[328,3829,2839],{"class":488},[328,3831,583],{"class":484},[328,3833,3834],{"class":573},"warn",[328,3836,577],{"class":484},[328,3838,3839],{"class":502},"`Spoofed bot detected from IP: ",[328,3841,2475],{"class":557},[328,3843,700],{"class":488},[328,3845,2481],{"class":557},[328,3847,3848],{"class":502}," claiming to be: ",[328,3850,2475],{"class":557},[328,3852,3789],{"class":488},[328,3854,2481],{"class":557},[328,3856,2484],{"class":502},[328,3858,595],{"class":484},[328,3860,3861],{"class":330,"line":947},[328,3862,3863],{"class":484},"      \n",[328,3865,3866],{"class":330,"line":952},[328,3867,3868],{"class":551},"      \u002F\u002F We drop spoofed bots immediately with a 403 Forbidden.\n",[328,3870,3871,3874,3876,3878,3880,3882],{"class":330,"line":958},[328,3872,3873],{"class":573},"      setResponseStatus",[328,3875,577],{"class":484},[328,3877,622],{"class":488},[328,3879,521],{"class":484},[328,3881,1081],{"class":726},[328,3883,595],{"class":484},[328,3885,3886,3888],{"class":330,"line":996},[328,3887,1784],{"class":480},[328,3889,1091],{"class":484},[328,3891,3892,3894,3896,3898,3901,3903],{"class":330,"line":1030},[328,3893,1808],{"class":488},[328,3895,673],{"class":672},[328,3897,499],{"class":498},[328,3899,3900],{"class":502},"spoofed_identity_detected",[328,3902,506],{"class":498},[328,3904,730],{"class":484},[328,3906,3907,3909,3911,3913,3916],{"class":330,"line":1035},[328,3908,1824],{"class":488},[328,3910,673],{"class":672},[328,3912,499],{"class":498},[328,3914,3915],{"class":502},"Your network origin does not match your claimed identity.",[328,3917,746],{"class":498},[328,3919,3920],{"class":330,"line":1041},[328,3921,3922],{"class":484},"      };\n",[328,3924,3925],{"class":330,"line":1057},[328,3926,1843],{"class":484},[328,3928,3929],{"class":330,"line":1063},[328,3930,381],{"class":484},[328,3932,3933],{"class":330,"line":1069},[328,3934,3935],{"class":551},"    \u002F\u002F Scenario 2: It is a verified, legitimate search engine crawler\n",[328,3937,3938,3940,3942,3944,3946,3949],{"class":330,"line":1086},[328,3939,1749],{"class":480},[328,3941,618],{"class":484},[328,3943,3809],{"class":488},[328,3945,583],{"class":484},[328,3947,3948],{"class":488},"isVerifiedCrawler",[328,3950,703],{"class":484},[328,3952,3953],{"class":330,"line":1094},[328,3954,3955],{"class":551},"      \u002F\u002F Cache the IP to speed up subsequent requests from this crawler\n",[328,3957,3958,3961,3963,3966,3968,3970],{"class":330,"line":1112},[328,3959,3960],{"class":488},"      verifiedBotCache",[328,3962,583],{"class":484},[328,3964,3965],{"class":573},"add",[328,3967,577],{"class":484},[328,3969,700],{"class":488},[328,3971,595],{"class":484},[328,3973,3974],{"class":330,"line":1130},[328,3975,3863],{"class":484},[328,3977,3978],{"class":330,"line":1136},[328,3979,3980],{"class":551},"      \u002F\u002F Optionally limit the cache size to prevent memory leaks\n",[328,3982,3983,3985,3987,3989,3991,3994,3997,4000,4002,4004,4006,4009],{"class":330,"line":1141},[328,3984,2543],{"class":480},[328,3986,618],{"class":484},[328,3988,3721],{"class":488},[328,3990,583],{"class":484},[328,3992,3993],{"class":488},"size",[328,3995,3996],{"class":565}," >",[328,3998,3999],{"class":726}," 10000",[328,4001,625],{"class":484},[328,4003,3721],{"class":488},[328,4005,583],{"class":484},[328,4007,4008],{"class":573},"clear",[328,4010,1906],{"class":484},[328,4012,4013],{"class":330,"line":1146},[328,4014,3863],{"class":484},[328,4016,4017,4019,4022],{"class":330,"line":1158},[328,4018,1784],{"class":480},[328,4020,4021],{"class":484},"; ",[328,4023,4024],{"class":551},"\u002F\u002F Allow the request to proceed\n",[328,4026,4027],{"class":330,"line":1164},[328,4028,1843],{"class":484},[328,4030,4031],{"class":330,"line":1179},[328,4032,381],{"class":484},[328,4034,4035],{"class":330,"line":1186},[328,4036,4037],{"class":551},"    \u002F\u002F Scenario 3: It is an unverified, generic scraper script (e.g., python-requests)\n",[328,4039,4040],{"class":330,"line":1201},[328,4041,4042],{"class":551},"    \u002F\u002F We don't want these consuming our server rendering resources.\n",[328,4044,4045,4047,4049,4051,4053,4055,4057,4060,4062,4064,4066],{"class":330,"line":1217},[328,4046,1749],{"class":480},[328,4048,618],{"class":484},[328,4050,3809],{"class":488},[328,4052,583],{"class":484},[328,4054,3814],{"class":488},[328,4056,2362],{"class":565},[328,4058,4059],{"class":565}," !",[328,4061,3809],{"class":488},[328,4063,583],{"class":484},[328,4065,3948],{"class":488},[328,4067,703],{"class":484},[328,4069,4070,4072,4074,4076,4078,4081],{"class":330,"line":1222},[328,4071,3873],{"class":573},[328,4073,577],{"class":484},[328,4075,622],{"class":488},[328,4077,521],{"class":484},[328,4079,4080],{"class":726},"429",[328,4082,595],{"class":484},[328,4084,4085,4087],{"class":330,"line":1227},[328,4086,1784],{"class":480},[328,4088,1091],{"class":484},[328,4090,4091,4093,4095,4097,4100,4102],{"class":330,"line":1232},[328,4092,1808],{"class":488},[328,4094,673],{"class":672},[328,4096,499],{"class":498},[328,4098,4099],{"class":502},"automated_traffic_blocked",[328,4101,506],{"class":498},[328,4103,730],{"class":484},[328,4105,4106,4108,4110,4112,4115],{"class":330,"line":1244},[328,4107,1824],{"class":488},[328,4109,673],{"class":672},[328,4111,499],{"class":498},[328,4113,4114],{"class":502},"Automated access is restricted. Please use our official API.",[328,4116,746],{"class":498},[328,4118,4119],{"class":330,"line":1250},[328,4120,3922],{"class":484},[328,4122,4123],{"class":330,"line":1256},[328,4124,1843],{"class":484},[328,4126,4127],{"class":330,"line":1262},[328,4128,546],{"emptyLinePlaceholder":10},[328,4130,4131],{"class":330,"line":1278},[328,4132,4133],{"class":551},"    \u002F\u002F Scenario 4: It appears to be a legitimate human user.\n",[328,4135,4136],{"class":330,"line":1285},[328,4137,4138],{"class":551},"    \u002F\u002F Proceed to the next middleware or route handler.\n",[328,4140,4141,4143],{"class":330,"line":1301},[328,4142,915],{"class":480},[328,4144,509],{"class":484},[328,4146,4147],{"class":330,"line":1318},[328,4148,381],{"class":484},[328,4150,4151,4153,4155,4157,4159],{"class":330,"line":1334},[328,4152,867],{"class":484},[328,4154,870],{"class":480},[328,4156,618],{"class":484},[328,4158,875],{"class":488},[328,4160,703],{"class":484},[328,4162,4163],{"class":330,"line":1339},[328,4164,4165],{"class":551},"    \u002F\u002F Fail open: if the IP Shield API is down, we don't want to block organic traffic\n",[328,4167,4168,4170,4172,4174,4176,4178,4181,4183,4185,4187],{"class":330,"line":1344},[328,4169,883],{"class":488},[328,4171,583],{"class":484},[328,4173,888],{"class":573},[328,4175,577],{"class":484},[328,4177,506],{"class":498},[328,4179,4180],{"class":502},"Bot analysis failed:",[328,4182,506],{"class":498},[328,4184,521],{"class":484},[328,4186,875],{"class":488},[328,4188,595],{"class":484},[328,4190,4191,4193],{"class":330,"line":1349},[328,4192,915],{"class":480},[328,4194,509],{"class":484},[328,4196,4197],{"class":330,"line":1355},[328,4198,758],{"class":484},[328,4200,4201],{"class":330,"line":1387},[328,4202,1528],{"class":484},[2889,4204,4205],{},[223,4206,4207],{},"Always deploy bot protection logic as early in the request lifecycle as possible. Blocking requests at the edge or middleware layer prevents expensive database queries, business logic execution, and Server-Side Rendering (SSR) cycles from running unnecessarily.",[261,4209,4211],{"id":4210},"advanced-implementations-python-fastapi","Advanced Implementations: Python FastAPI",[223,4213,4214],{},"For data science teams or Python-heavy backends, integrating IP Shield into FastAPI is highly effective for protecting API endpoints from scrapers.",[319,4216,4221],{"className":4217,"code":4218,"filename":4219,"language":4220,"meta":227,"style":227},"language-python shiki shiki-themes light-plus light-plus dracula","from fastapi import Request, HTTPException, status\nimport httpx\nimport os\n\nIP_SHIELD_API_KEY = os.getenv(\"IP_SHIELD_API_KEY\")\n\nasync def verify_bot_traffic(request: Request):\n    \"\"\"\n    FastAPI dependency to intercept and analyze incoming traffic.\n    \"\"\"\n    client_ip = request.client.host\n    user_agent = request.headers.get('user-agent', '')\n    \n    # Handle proxy headers if behind an ingress controller\n    forwarded_for = request.headers.get('x-forwarded-for')\n    if forwarded_for:\n        client_ip = forwarded_for.split(',')[0].strip()\n\n    async with httpx.AsyncClient() as client:\n        try:\n            response = await client.post(\n                \"https:\u002F\u002Fip-shield.riavzon.com\u002Fv1\u002Fcheck\u002Fbot\",\n                json={\"ip\": client_ip, \"userAgent\": user_agent},\n                headers={\"Authorization\": f\"Bearer {IP_SHIELD_API_KEY}\"},\n                timeout=2.0\n            )\n            \n            if response.status_code == 200:\n                data = response.json()\n                \n                if data.get(\"isSpoofed\"):\n                    raise HTTPException(\n                        status_code=status.HTTP_403_FORBIDDEN,\n                        detail=\"Spoofed User-Agent identity detected.\"\n                    )\n                    \n                if data.get(\"isBot\") and not data.get(\"isVerifiedCrawler\"):\n                    raise HTTPException(\n                        status_code=status.HTTP_429_TOO_MANY_REQUESTS,\n                        detail=\"Automated access restricted.\"\n                    )\n                    \n        except httpx.RequestError as exc:\n            # Fail open on timeout or network error\n            print(f\"IP Shield validation error: {exc}\")\n            pass\n            \n    return True\n","app\u002Fdependencies\u002Fbot_protection.py","python",[325,4222,4223,4228,4233,4238,4242,4247,4251,4256,4261,4266,4270,4275,4280,4284,4289,4294,4299,4304,4308,4313,4318,4323,4328,4333,4338,4343,4348,4353,4358,4363,4368,4373,4378,4383,4388,4393,4398,4403,4407,4412,4417,4421,4425,4430,4435,4440,4445,4449],{"__ignoreMap":227},[328,4224,4225],{"class":330,"line":331},[328,4226,4227],{},"from fastapi import Request, HTTPException, status\n",[328,4229,4230],{"class":330,"line":228},[328,4231,4232],{},"import httpx\n",[328,4234,4235],{"class":330,"line":342},[328,4236,4237],{},"import os\n",[328,4239,4240],{"class":330,"line":348},[328,4241,546],{"emptyLinePlaceholder":10},[328,4243,4244],{"class":330,"line":354},[328,4245,4246],{},"IP_SHIELD_API_KEY = os.getenv(\"IP_SHIELD_API_KEY\")\n",[328,4248,4249],{"class":330,"line":360},[328,4250,546],{"emptyLinePlaceholder":10},[328,4252,4253],{"class":330,"line":366},[328,4254,4255],{},"async def verify_bot_traffic(request: Request):\n",[328,4257,4258],{"class":330,"line":372},[328,4259,4260],{},"    \"\"\"\n",[328,4262,4263],{"class":330,"line":378},[328,4264,4265],{},"    FastAPI dependency to intercept and analyze incoming traffic.\n",[328,4267,4268],{"class":330,"line":384},[328,4269,4260],{},[328,4271,4272],{"class":330,"line":390},[328,4273,4274],{},"    client_ip = request.client.host\n",[328,4276,4277],{"class":330,"line":683},[328,4278,4279],{},"    user_agent = request.headers.get('user-agent', '')\n",[328,4281,4282],{"class":330,"line":689},[328,4283,381],{},[328,4285,4286],{"class":330,"line":706},[328,4287,4288],{},"    # Handle proxy headers if behind an ingress controller\n",[328,4290,4291],{"class":330,"line":718},[328,4292,4293],{},"    forwarded_for = request.headers.get('x-forwarded-for')\n",[328,4295,4296],{"class":330,"line":733},[328,4297,4298],{},"    if forwarded_for:\n",[328,4300,4301],{"class":330,"line":749},[328,4302,4303],{},"        client_ip = forwarded_for.split(',')[0].strip()\n",[328,4305,4306],{"class":330,"line":755},[328,4307,546],{"emptyLinePlaceholder":10},[328,4309,4310],{"class":330,"line":761},[328,4311,4312],{},"    async with httpx.AsyncClient() as client:\n",[328,4314,4315],{"class":330,"line":766},[328,4316,4317],{},"        try:\n",[328,4319,4320],{"class":330,"line":788},[328,4321,4322],{},"            response = await client.post(\n",[328,4324,4325],{"class":330,"line":793},[328,4326,4327],{},"                \"https:\u002F\u002Fip-shield.riavzon.com\u002Fv1\u002Fcheck\u002Fbot\",\n",[328,4329,4330],{"class":330,"line":799},[328,4331,4332],{},"                json={\"ip\": client_ip, \"userAgent\": user_agent},\n",[328,4334,4335],{"class":330,"line":805},[328,4336,4337],{},"                headers={\"Authorization\": f\"Bearer {IP_SHIELD_API_KEY}\"},\n",[328,4339,4340],{"class":330,"line":811},[328,4341,4342],{},"                timeout=2.0\n",[328,4344,4345],{"class":330,"line":817},[328,4346,4347],{},"            )\n",[328,4349,4350],{"class":330,"line":828},[328,4351,4352],{},"            \n",[328,4354,4355],{"class":330,"line":836},[328,4356,4357],{},"            if response.status_code == 200:\n",[328,4359,4360],{"class":330,"line":864},[328,4361,4362],{},"                data = response.json()\n",[328,4364,4365],{"class":330,"line":880},[328,4366,4367],{},"                \n",[328,4369,4370],{"class":330,"line":906},[328,4371,4372],{},"                if data.get(\"isSpoofed\"):\n",[328,4374,4375],{"class":330,"line":912},[328,4376,4377],{},"                    raise HTTPException(\n",[328,4379,4380],{"class":330,"line":942},[328,4381,4382],{},"                        status_code=status.HTTP_403_FORBIDDEN,\n",[328,4384,4385],{"class":330,"line":947},[328,4386,4387],{},"                        detail=\"Spoofed User-Agent identity detected.\"\n",[328,4389,4390],{"class":330,"line":952},[328,4391,4392],{},"                    )\n",[328,4394,4395],{"class":330,"line":958},[328,4396,4397],{},"                    \n",[328,4399,4400],{"class":330,"line":996},[328,4401,4402],{},"                if data.get(\"isBot\") and not data.get(\"isVerifiedCrawler\"):\n",[328,4404,4405],{"class":330,"line":1030},[328,4406,4377],{},[328,4408,4409],{"class":330,"line":1035},[328,4410,4411],{},"                        status_code=status.HTTP_429_TOO_MANY_REQUESTS,\n",[328,4413,4414],{"class":330,"line":1041},[328,4415,4416],{},"                        detail=\"Automated access restricted.\"\n",[328,4418,4419],{"class":330,"line":1057},[328,4420,4392],{},[328,4422,4423],{"class":330,"line":1063},[328,4424,4397],{},[328,4426,4427],{"class":330,"line":1069},[328,4428,4429],{},"        except httpx.RequestError as exc:\n",[328,4431,4432],{"class":330,"line":1086},[328,4433,4434],{},"            # Fail open on timeout or network error\n",[328,4436,4437],{"class":330,"line":1094},[328,4438,4439],{},"            print(f\"IP Shield validation error: {exc}\")\n",[328,4441,4442],{"class":330,"line":1112},[328,4443,4444],{},"            pass\n",[328,4446,4447],{"class":330,"line":1130},[328,4448,4352],{},[328,4450,4451],{"class":330,"line":1136},[328,4452,4453],{},"    return True\n",[223,4455,4456],{},"You then inject this dependency into your highly targeted routes:",[319,4458,4461],{"className":4217,"code":4459,"filename":4460,"language":4220,"meta":227,"style":227},"from fastapi import FastAPI, Depends\nfrom app.dependencies.bot_protection import verify_bot_traffic\n\napp = FastAPI()\n\n@app.get(\"\u002Fapi\u002Fv1\u002Fsensitive-data\", dependencies=[Depends(verify_bot_traffic)])\nasync def get_sensitive_data():\n    return {\"data\": \"This data is protected from unauthorized scrapers.\"}\n","app\u002Fmain.py",[325,4462,4463,4468,4473,4477,4482,4486,4491,4496],{"__ignoreMap":227},[328,4464,4465],{"class":330,"line":331},[328,4466,4467],{},"from fastapi import FastAPI, Depends\n",[328,4469,4470],{"class":330,"line":228},[328,4471,4472],{},"from app.dependencies.bot_protection import verify_bot_traffic\n",[328,4474,4475],{"class":330,"line":342},[328,4476,546],{"emptyLinePlaceholder":10},[328,4478,4479],{"class":330,"line":348},[328,4480,4481],{},"app = FastAPI()\n",[328,4483,4484],{"class":330,"line":354},[328,4485,546],{"emptyLinePlaceholder":10},[328,4487,4488],{"class":330,"line":360},[328,4489,4490],{},"@app.get(\"\u002Fapi\u002Fv1\u002Fsensitive-data\", dependencies=[Depends(verify_bot_traffic)])\n",[328,4492,4493],{"class":330,"line":366},[328,4494,4495],{},"async def get_sensitive_data():\n",[328,4497,4498],{"class":330,"line":372},[328,4499,4500],{},"    return {\"data\": \"This data is protected from unauthorized scrapers.\"}\n",[261,4502,4504],{"id":4503},"handling-false-positives-with-adaptive-friction","Handling False Positives with Adaptive Friction",[223,4506,4507],{},"No detection system is perfect. Occasionally, a legitimate user might be using a niche browser extension, a privacy-focused corporate VPN, or an outdated operating system that triggers a high bot-probability score.",[223,4509,4510,4511,583],{},"If you institute a hard block (returning a 403 Forbidden page), you permanently lose that user. The modern approach utilizes ",[283,4512,4513],{},"Adaptive Friction",[223,4515,4516],{},"When a request's threat score falls into a \"gray area\" (e.g., highly suspicious, but not definitively proven to be a malicious script), you intercept the request and present a challenge.",[269,4518,4520],{"id":4519},"types-of-adaptive-challenges","Types of Adaptive Challenges:",[277,4522,4523,4529,4535],{},[280,4524,4525,4528],{},[283,4526,4527],{},"Visual CAPTCHAs",": The traditional approach (reCAPTCHA, hCaptcha). Effective, but heavily degrades the user experience and lowers conversion rates.",[280,4530,4531,4534],{},[283,4532,4533],{},"Proof of Work (PoW)",": Your server sends a cryptographic puzzle to the client's browser. The browser must spend a few seconds of CPU time computing the hash before it is allowed to proceed. Legitimate users barely notice the slight delay, but an attacker trying to scrape 10,000 pages per minute finds their operation crippled by CPU costs.",[280,4536,4537,4540,4541,4543],{},[283,4538,4539],{},"JavaScript Execution Challenges",": The server returns an obfuscated JavaScript payload that must execute and return a specific token. Since Generation 1 bots (like ",[325,4542,3134],{},") cannot execute JavaScript, they fail immediately without bothering human users.",[261,4545,3025],{"id":3024},[223,4547,4548],{},"Effective bot management requires looking at the holistic picture. You analyze the IP reputation, the ASN, the behavioral patterns, the reverse DNS records, and the HTTP headers collectively. IP Shield aggregates these vast, complex signals into a unified threat intelligence layer.",[223,4550,4551],{},"This unified approach allows you to set dynamic, highly granular thresholds. You block requests with a definitive spoofing flag outright, challenge suspicious gray-area requests with invisible Proof of Work puzzles, and allow verified SEO traffic seamless, accelerated access.",[223,4553,4554],{},"The evolution of bot management has moved definitively away from static string-matching rules. To protect modern infrastructure, engineering teams must embrace dynamic, context-aware intelligence networks.",[3036,4556,4557],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZ328, html code.shiki .sZ328{--shiki-light:#AF00DB;--shiki-default:#AF00DB;--shiki-dark:#FF79C6}html pre.shiki code .sDd4n, html code.shiki .sDd4n{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#F8F8F2}html pre.shiki code .sjsA6, html code.shiki .sjsA6{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#F8F8F2}html pre.shiki code .sFkSl, html code.shiki .sFkSl{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#E9F284}html pre.shiki code .sFB1V, html code.shiki .sFB1V{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#F1FA8C}html pre.shiki code .sghk6, html code.shiki .sghk6{--shiki-light:#008000;--shiki-default:#008000;--shiki-dark:#6272A4}html pre.shiki code .sl46w, html code.shiki .sl46w{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#FF79C6}html pre.shiki code .s3JHE, html code.shiki .s3JHE{--shiki-light:#0070C1;--shiki-default:#0070C1;--shiki-dark:#F8F8F2}html pre.shiki code .saOXh, html code.shiki .saOXh{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#FF79C6}html pre.shiki code .sakC6, html code.shiki .sakC6{--shiki-light:#0000FF;--shiki-light-font-weight:inherit;--shiki-default:#0000FF;--shiki-default-font-weight:inherit;--shiki-dark:#FF79C6;--shiki-dark-font-weight:bold}html pre.shiki code .sHOzp, html code.shiki .sHOzp{--shiki-light:#795E26;--shiki-default:#795E26;--shiki-dark:#50FA7B}html pre.shiki code .sPzPf, html code.shiki .sPzPf{--shiki-light:#0070C1;--shiki-default:#0070C1;--shiki-dark:#BD93F9}html pre.shiki code .sFs1U, html code.shiki .sFs1U{--shiki-light:#267F99;--shiki-light-font-style:inherit;--shiki-default:#267F99;--shiki-default-font-style:inherit;--shiki-dark:#8BE9FD;--shiki-dark-font-style:italic}html pre.shiki code .sygFZ, html code.shiki .sygFZ{--shiki-light:#001080;--shiki-light-font-style:inherit;--shiki-default:#001080;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}html pre.shiki code .s34zl, html code.shiki .s34zl{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#FF79C6}html pre.shiki code .sjR7W, html code.shiki .sjR7W{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#BD93F9}html pre.shiki code .sRg35, html code.shiki .sRg35{--shiki-light:#811F3F;--shiki-default:#811F3F;--shiki-dark:#FF5555}html pre.shiki code .skAEd, html code.shiki .skAEd{--shiki-light:#EE0000;--shiki-default:#EE0000;--shiki-dark:#F1FA8C}html pre.shiki code .s63D3, html code.shiki .s63D3{--shiki-light:#D16969;--shiki-default:#D16969;--shiki-dark:#FFB86C}html pre.shiki code .sIcdS, html code.shiki .sIcdS{--shiki-light:#811F3F;--shiki-default:#811F3F;--shiki-dark:#F1FA8C}html pre.shiki code .st6lo, html code.shiki .st6lo{--shiki-light:#EE0000;--shiki-default:#EE0000;--shiki-dark:#FF79C6}html pre.shiki code .spgvN, html code.shiki .spgvN{--shiki-light:#098658;--shiki-default:#098658;--shiki-dark:#BD93F9}",{"title":227,"searchDepth":228,"depth":228,"links":4559},[4560,4566,4570,4571,4572,4575],{"id":3120,"depth":228,"text":3121,"children":4561},[4562,4563,4564,4565],{"id":3127,"depth":342,"text":3128},{"id":3148,"depth":342,"text":3149},{"id":3159,"depth":342,"text":3160},{"id":3170,"depth":342,"text":3171},{"id":3266,"depth":228,"text":3267,"children":4567},[4568,4569],{"id":3286,"depth":342,"text":3287},{"id":3340,"depth":342,"text":3341},{"id":3350,"depth":228,"text":3351},{"id":4210,"depth":228,"text":4211},{"id":4503,"depth":228,"text":4504,"children":4573},[4574],{"id":4519,"depth":342,"text":4520},{"id":3024,"depth":228,"text":3025},"An exhaustive technical deep-dive into how bot management has evolved from simple User-Agent parsing to complex behavioral analysis, reverse DNS verification, and AI scraper mitigation.","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1485827404703-89b55fcc595e?auto=format&fit=crop&q=80&w=800",{},"---\ntitle: The Evolution of Bot Management and User Agent Parsing\ndescription: An exhaustive technical deep-dive into how bot management has evolved from simple User-Agent parsing to complex behavioral analysis, reverse DNS verification, and AI scraper mitigation.\ntags: [\"engineering\", \"bot-management\", \"seo\", \"architecture\", \"web-scraping\"]\nimage: \"https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1485827404703-89b55fcc595e?auto=format&fit=crop&q=80&w=800\"\nauthor: \"Sergio\"\nauthorImg: \"https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F187537278?v=4\"\nauthorGithub: \"https:\u002F\u002Fgithub.com\u002FSergo706\"\nauthorGithubUserName: \"Sergo706\"\nfeatured: false\ndate: 2026-06-11T00:00:00.000Z\nreadingTime: \"40 min\"\n---\n\n# The Evolution of Bot Management and User Agent Parsing\n\nBot traffic comprises nearly half of all internet traffic today. While some bots index your content for search engines, others scrape your proprietary data, scalp your inventory, probe your applications for vulnerabilities, or consume massive amounts of your bandwidth. Managing this traffic effectively determines the performance, cost-efficiency, and security of your digital infrastructure.\n\nIn the early days of the web, bot management was incredibly straightforward. It meant reading the `User-Agent` HTTP header. Developers simply wrote regular expressions to block strings containing `python-requests`, `curl`, or `Java\u002F1.8.0`. Today, malicious actors spoof their headers to perfectly mimic Chrome running on a macOS device, rendering naive string matching obsolete.\n\nThis comprehensive guide explores the multi-generational evolution of bot architecture, why legacy detection mechanisms fail, and how to implement modern, context-aware bot mitigation strategies using IP Shield and advanced server-side architectures.\n\n::note\nA User-Agent string identifies the client software originating the request. Because the client controls this header entirely, it provides no inherent cryptographic proof of identity. Relying on it for security is equivalent to trusting a visitor's handwritten name tag.\n::\n\n## The Generations of Web Scraping\n\nTo understand how to defeat modern bots, we must trace their evolutionary history. As defensive mechanisms improved, scraper technology evolved in direct response, creating a fascinating arms race.\n\n### Generation 1: The Scripted Clients\nThe earliest bots were simple HTTP clients. Tools like `cURL`, `wget`, and libraries like `urllib` or `python-requests` made bare-bones HTTP GET and POST requests. They were extremely fast and efficient but completely incapable of executing JavaScript. If a website rendered content client-side via React or Angular, Generation 1 bots failed entirely. They were also easily detected by their default User-Agent strings.\n\n### Generation 2: The Early Headless Browsers\nAs the web moved towards Single Page Applications (SPAs), bots needed to execute JavaScript. Projects like PhantomJS emerged, providing a scriptable, headless WebKit engine. While they could render JS, they leaked massive amounts of identifiable information. Security tools easily detected them by checking for variables like `window._phantom` or analyzing their unique TLS fingerprint.\n\n### Generation 3: The Modern Headless Era\nToday, attackers utilize headless versions of modern browsers controlled via frameworks like Puppeteer, Playwright, and Selenium. These tools execute JavaScript, solve simple CAPTCHAs, and mimic human interaction patterns perfectly. Furthermore, developers have created \"stealth\" plugins (e.g., `puppeteer-extra-plugin-stealth`) designed specifically to patch the JavaScript variables and inconsistencies that anti-bot software looks for. They render pages just like a real user, making detection incredibly difficult at the application layer.\n\n### Generation 4: AI Agents and Distributed Scrapers\nWe are currently entering the fourth generation. Bots are no longer simple scripts; they are AI-driven agents powered by Large Language Models (LLMs) that can navigate complex dynamic UIs, understand semantic page layouts, and dynamically adjust their scraping strategies when website structures change. When an attacker pairs these AI agents with a rotating residential proxy network, the traffic looks indistinguishable from organic human user growth.\n\n```mermaid\nsequenceDiagram\n    participant AI as AI Scraper Agent\n    participant Proxy as Residential Proxy Pool\n    participant WAF as Web Application Firewall\n    participant App as Your Application\n\n    AI->>Proxy: Request Page (Spoofed Chrome UA)\n    Proxy->>WAF: Forward Request via Home IP\n    WAF->>WAF: Check IP Reputation (Passes)\n    WAF->>WAF: Check User-Agent (Passes)\n    WAF->>App: Forward Request\n    App-->>WAF: Return HTML payload\n    WAF-->>Proxy: Return HTML payload\n    Proxy-->>AI: Return HTML payload\n    AI->>AI: LLM parses unstructured DOM\n    AI->>Proxy: Proceed to next logical step\n```\n\n::warning\nRelying solely on User-Agent parsing to block bots leaves your application completely exposed to modern headless scraping frameworks and AI agents. You must look beyond the header.\n::\n\n## Verifying Legitimate Bots: The SEO Dilemma\n\nNot all automated traffic is harmful. Search engine crawlers like Googlebot, Bingbot, Yandex, and specialized SEO tools (Ahrefs, Semrush) must access your site to ensure your business remains visible online. You cannot afford to block them accidentally with overly aggressive anti-bot rules; doing so destroys your organic search rankings.\n\nHowever, malicious scrapers frequently spoof the `Googlebot` User-Agent string to bypass security filters. They know that naive WAF configurations include rules like: `IF User-Agent CONTAINS \"Googlebot\" THEN ALLOW`. \n\nYou must verify that the bot claiming to be Google actually originates from an IP address owned by Google. This requires cross-referencing the claimed identity with the underlying network infrastructure.\n\n### The Verification Process: Reverse DNS\n\nThe traditional way to verify a search engine crawler is performing a Reverse DNS (rDNS) lookup followed by a Forward DNS lookup.\n\n1. **Reverse DNS Lookup**: You query the DNS pointer (PTR) record of the incoming IP address. For example, doing an rDNS lookup on `66.249.66.1` returns `crawl-66-249-66-1.googlebot.com`.\n2. **Domain Verification**: You verify that the domain ends in `googlebot.com` or `google.com`.\n3. **Forward DNS Lookup**: To prevent an attacker from simply setting up a fake PTR record on their own server, you must do a forward DNS lookup on the domain returned in step 1 (`crawl-66-249-66-1.googlebot.com`).\n4. **Final Match**: If the IP returned in step 3 matches the original IP `66.249.66.1`, the crawler is verified.\n\nPerforming this three-step DNS dance for every single incoming request introduces massive latency to your application. It is computationally expensive and slow.\n\n### The Modern Solution: IP Shield Bot API\n\nIP Shield simplifies this verification process dramatically. The User Agent & Bot Parser API analyzes the header string and automatically performs the reverse DNS lookups, ASN verification, and signature matching in real-time. It explicitly flags whether a known crawler is verified or spoofed.\n\nYou implement this check in your edge routing layer or middleware. This ensures fake crawlers get dropped before they consume your application resources, while legitimate SEO bots pass through smoothly.\n\n## Implementing Bot Protection Middleware\n\nHere is a comprehensive example of verifying search engine crawlers and blocking malicious bots using a Nuxt 3 server middleware. This implementation handles rate limiting, safe-listing, spoof detection, and adaptive responses.\n\n~~~typescript [server\u002Fmiddleware\u002Fbot-protection.ts]\nimport { IPShield } from '@ip-shield\u002Fsdk';\nimport { sendError, setResponseStatus, createError } from 'h3';\n\n\u002F\u002F Initialize the SDK\nconst shield = new IPShield(process.env.IP_SHIELD_API_KEY);\n\n\u002F\u002F Cache verified IPs in memory to reduce API calls and latency\n\u002F\u002F In production, use Redis or unstorage for distributed caching\nconst verifiedBotCache = new Set\u003Cstring>();\n\nexport default defineEventHandler(async (event) => {\n  \u002F\u002F Extract essential request metadata\n  const ip = getRequestIP(event, { xForwardedFor: true }) || '';\n  const userAgent = getRequestHeader(event, 'user-agent') || '';\n  const path = event.path;\n  \n  \u002F\u002F Skip static assets to save compute resources\n  if (path.startsWith('\u002F_nuxt\u002F') || path.match(\u002F\\.(js|css|png|jpg|svg|ico)$\u002F)) {\n    return;\n  }\n\n  \u002F\u002F Fast path: if we've already verified this IP recently, let it through\n  if (verifiedBotCache.has(ip)) {\n    return;\n  }\n  \n  try {\n    \u002F\u002F Cross-reference the IP and User-Agent with IP Shield\n    const botData = await shield.bots.analyze({ ip, userAgent });\n    \n    \u002F\u002F Scenario 1: The request claims to be a good bot but the IP doesn't match\n    if (botData.isBot && botData.isSpoofed) {\n      console.warn(`Spoofed bot detected from IP: ${ip} claiming to be: ${userAgent}`);\n      \n      \u002F\u002F We drop spoofed bots immediately with a 403 Forbidden.\n      setResponseStatus(event, 403);\n      return { \n        error: 'spoofed_identity_detected',\n        message: 'Your network origin does not match your claimed identity.'\n      };\n    }\n    \n    \u002F\u002F Scenario 2: It is a verified, legitimate search engine crawler\n    if (botData.isVerifiedCrawler) {\n      \u002F\u002F Cache the IP to speed up subsequent requests from this crawler\n      verifiedBotCache.add(ip);\n      \n      \u002F\u002F Optionally limit the cache size to prevent memory leaks\n      if (verifiedBotCache.size > 10000) verifiedBotCache.clear();\n      \n      return; \u002F\u002F Allow the request to proceed\n    }\n    \n    \u002F\u002F Scenario 3: It is an unverified, generic scraper script (e.g., python-requests)\n    \u002F\u002F We don't want these consuming our server rendering resources.\n    if (botData.isBot && !botData.isVerifiedCrawler) {\n      setResponseStatus(event, 429);\n      return { \n        error: 'automated_traffic_blocked',\n        message: 'Automated access is restricted. Please use our official API.'\n      };\n    }\n\n    \u002F\u002F Scenario 4: It appears to be a legitimate human user.\n    \u002F\u002F Proceed to the next middleware or route handler.\n    return;\n    \n  } catch (err) {\n    \u002F\u002F Fail open: if the IP Shield API is down, we don't want to block organic traffic\n    console.error('Bot analysis failed:', err);\n    return;\n  }\n});\n~~~\n\n::important\nAlways deploy bot protection logic as early in the request lifecycle as possible. Blocking requests at the edge or middleware layer prevents expensive database queries, business logic execution, and Server-Side Rendering (SSR) cycles from running unnecessarily.\n::\n\n## Advanced Implementations: Python FastAPI\n\nFor data science teams or Python-heavy backends, integrating IP Shield into FastAPI is highly effective for protecting API endpoints from scrapers.\n\n~~~python [app\u002Fdependencies\u002Fbot_protection.py]\nfrom fastapi import Request, HTTPException, status\nimport httpx\nimport os\n\nIP_SHIELD_API_KEY = os.getenv(\"IP_SHIELD_API_KEY\")\n\nasync def verify_bot_traffic(request: Request):\n    \"\"\"\n    FastAPI dependency to intercept and analyze incoming traffic.\n    \"\"\"\n    client_ip = request.client.host\n    user_agent = request.headers.get('user-agent', '')\n    \n    # Handle proxy headers if behind an ingress controller\n    forwarded_for = request.headers.get('x-forwarded-for')\n    if forwarded_for:\n        client_ip = forwarded_for.split(',')[0].strip()\n\n    async with httpx.AsyncClient() as client:\n        try:\n            response = await client.post(\n                \"https:\u002F\u002Fip-shield.riavzon.com\u002Fv1\u002Fcheck\u002Fbot\",\n                json={\"ip\": client_ip, \"userAgent\": user_agent},\n                headers={\"Authorization\": f\"Bearer {IP_SHIELD_API_KEY}\"},\n                timeout=2.0\n            )\n            \n            if response.status_code == 200:\n                data = response.json()\n                \n                if data.get(\"isSpoofed\"):\n                    raise HTTPException(\n                        status_code=status.HTTP_403_FORBIDDEN,\n                        detail=\"Spoofed User-Agent identity detected.\"\n                    )\n                    \n                if data.get(\"isBot\") and not data.get(\"isVerifiedCrawler\"):\n                    raise HTTPException(\n                        status_code=status.HTTP_429_TOO_MANY_REQUESTS,\n                        detail=\"Automated access restricted.\"\n                    )\n                    \n        except httpx.RequestError as exc:\n            # Fail open on timeout or network error\n            print(f\"IP Shield validation error: {exc}\")\n            pass\n            \n    return True\n~~~\n\nYou then inject this dependency into your highly targeted routes:\n\n~~~python [app\u002Fmain.py]\nfrom fastapi import FastAPI, Depends\nfrom app.dependencies.bot_protection import verify_bot_traffic\n\napp = FastAPI()\n\n@app.get(\"\u002Fapi\u002Fv1\u002Fsensitive-data\", dependencies=[Depends(verify_bot_traffic)])\nasync def get_sensitive_data():\n    return {\"data\": \"This data is protected from unauthorized scrapers.\"}\n~~~\n\n## Handling False Positives with Adaptive Friction\n\nNo detection system is perfect. Occasionally, a legitimate user might be using a niche browser extension, a privacy-focused corporate VPN, or an outdated operating system that triggers a high bot-probability score. \n\nIf you institute a hard block (returning a 403 Forbidden page), you permanently lose that user. The modern approach utilizes **Adaptive Friction**.\n\nWhen a request's threat score falls into a \"gray area\" (e.g., highly suspicious, but not definitively proven to be a malicious script), you intercept the request and present a challenge.\n\n### Types of Adaptive Challenges:\n\n1. **Visual CAPTCHAs**: The traditional approach (reCAPTCHA, hCaptcha). Effective, but heavily degrades the user experience and lowers conversion rates.\n2. **Proof of Work (PoW)**: Your server sends a cryptographic puzzle to the client's browser. The browser must spend a few seconds of CPU time computing the hash before it is allowed to proceed. Legitimate users barely notice the slight delay, but an attacker trying to scrape 10,000 pages per minute finds their operation crippled by CPU costs.\n3. **JavaScript Execution Challenges**: The server returns an obfuscated JavaScript payload that must execute and return a specific token. Since Generation 1 bots (like `cURL`) cannot execute JavaScript, they fail immediately without bothering human users.\n\n## Conclusion\n\nEffective bot management requires looking at the holistic picture. You analyze the IP reputation, the ASN, the behavioral patterns, the reverse DNS records, and the HTTP headers collectively. IP Shield aggregates these vast, complex signals into a unified threat intelligence layer.\n\nThis unified approach allows you to set dynamic, highly granular thresholds. You block requests with a definitive spoofing flag outright, challenge suspicious gray-area requests with invisible Proof of Work puzzles, and allow verified SEO traffic seamless, accelerated access. \n\nThe evolution of bot management has moved definitively away from static string-matching rules. To protect modern infrastructure, engineering teams must embrace dynamic, context-aware intelligence networks.\n","40 min",{"title":137,"description":4576},[4583,4584,4585,3079,4586],"engineering","bot-management","seo","web-scraping","kvjQkw6JxRHjk5WKFXl4xVLb9a-yS8apUi25NFIEkCY",{"id":4589,"title":133,"author":239,"authorGithub":240,"authorGithubUserName":241,"authorImg":242,"body":4590,"date":4653,"description":4654,"extension":231,"featured":61,"icon":3069,"image":4655,"meta":4656,"navigation":10,"path":134,"rawbody":4657,"readingTime":4658,"seo":4659,"stem":135,"tags":4660,"__hash__":4664},"blog\u002Fblog\u002Fintroducing-ip-shield.md",{"type":215,"value":4591,"toc":4649},[4592,4596,4602,4605,4609,4612,4639,4643,4646],[218,4593,4595],{"id":4594},"introducing-ip-shield","Introducing IP Shield",[223,4597,4598,4599,697],{},"We are thrilled to announce the official launch of ",[283,4600,4601],{},"IP Shield",[223,4603,4604],{},"After months of rigorous testing and development, we are bringing you a powerful, ultra-fast API designed to provide comprehensive IP intelligence to developers and businesses worldwide.",[261,4606,4608],{"id":4607},"why-ip-shield","Why IP Shield?",[223,4610,4611],{},"In today's digital landscape, knowing who is accessing your application is critical. IP Shield provides:",[4613,4614,4615,4621,4627,4633],"ul",{},[280,4616,4617,4620],{},[283,4618,4619],{},"Blazing Fast Speeds",": Built on Edge architecture to deliver responses in under 50ms globally.",[280,4622,4623,4626],{},[283,4624,4625],{},"Accurate Threat Detection",": Instantly identify VPNs, Tor nodes, and malicious proxies.",[280,4628,4629,4632],{},[283,4630,4631],{},"Detailed Geolocation",": Get precise location data to localize your user experiences seamlessly.",[280,4634,4635,4638],{},[283,4636,4637],{},"Developer-First Design",": Easy-to-use endpoints, robust SDKs, and comprehensive documentation.",[261,4640,4642],{"id":4641},"whats-next","What's Next?",[223,4644,4645],{},"We're just getting started. Over the coming weeks, we will be rolling out additional features including real-time webhook alerts and a robust analytics dashboard.",[223,4647,4648],{},"Stay tuned for more updates, and happy building!",{"title":227,"searchDepth":228,"depth":228,"links":4650},[4651,4652],{"id":4607,"depth":228,"text":4608},{"id":4641,"depth":228,"text":4642},"2026-05-26","Learn how background automation, local database tracking, and coordinated trading cycles work together in Solana Bots.","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1642104704074-907c0698cbd9?auto=format&fit=crop&q=80&w=800",{},"---\ntitle: Ultimate Guide to Trading Automation & Volume Strategies\ndescription: Learn how background automation, local database tracking, and coordinated trading cycles work together in Solana Bots.\ntags: [\"tutorial\", \"trading\", \"automation\"]\nimage: \"https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1642104704074-907c0698cbd9?auto=format&fit=crop&q=80&w=800\"\nauthor: \"Sergio\"\nauthorImg: \"https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F187537278?v=4\"\nauthorGithub: \"https:\u002F\u002Fgithub.com\u002FSergo706\"\nauthorGithubUserName: \"Sergo706\"\nfeatured: false\ndate: 2026-05-26T00:00:00.000Z\nreadingTime: \"12 min\"\n---\n\n# Introducing IP Shield\n\nWe are thrilled to announce the official launch of **IP Shield**! \n\nAfter months of rigorous testing and development, we are bringing you a powerful, ultra-fast API designed to provide comprehensive IP intelligence to developers and businesses worldwide.\n\n## Why IP Shield?\n\nIn today's digital landscape, knowing who is accessing your application is critical. IP Shield provides:\n\n- **Blazing Fast Speeds**: Built on Edge architecture to deliver responses in under 50ms globally.\n- **Accurate Threat Detection**: Instantly identify VPNs, Tor nodes, and malicious proxies.\n- **Detailed Geolocation**: Get precise location data to localize your user experiences seamlessly.\n- **Developer-First Design**: Easy-to-use endpoints, robust SDKs, and comprehensive documentation.\n\n## What's Next?\n\nWe're just getting started. Over the coming weeks, we will be rolling out additional features including real-time webhook alerts and a robust analytics dashboard. \n\nStay tuned for more updates, and happy building!\n","12 min",{"title":133,"description":4654},[4661,4662,4663],"tutorial","trading","automation","dgkxQl_B1VhworLCoERiNsTzhfjo_dI4H9RF6dmi66E",1782044511595]