One of my Next.js sites is getting hammered at the moment by some sort of unsophisticated vulnerability scanner, which is trying tends of thousands of URLs (some related to WordPress, others seemingly randomly generated) and causing me to get near to exceeding my tier for function invocations. This scanning has been ongoing for nearly a month. I’m currently on the free tier and the site domain is pointed at Netlify using a simple A record (i.e. no Cloudflare or other external CDN), and am 100% sure this is not real traffic as my Plausible analytics show only a handful of daily visits.
The site uses API Routes and other features which mean it can’t be statically exported with next export. I understand that due to the way Next.js works, it’s necessary to call a function to determine that a given request path is a 404, unless that path is covered by a redirect in netlify.toml. I have added a couple of dozen of the common paths or prefixes being tried by the scanner as 404 redirects in netlify.toml in the hope of reducing the level of function invocations, but as many of the paths it’s trying appear to be random, and netlify.toml doesn’t support proper wildcards in paths (e.g. /*.php) this strategy for blocking isn’t really working.
I don’t think Netlify provides the means to identify the IP sources of this traffic. Is there anything I can do to block this traffic or more effectively reduce the function usage it causes?
@nathanmartin Thanks for the pointer – I hadn’t found this thread in my previous searching. This looks like a very similar situation and I didn’t realise that Edge Functions can be used to perform this blocking. It looks like I can also log Context.ip from an Edge Function to possibly shed more light on where this traffic is coming from and perhaps implement blocking based on that.
Just confirming following the advice in the linked thread provided the solution. I was able to use an Edge Function with a pattern matching all *.php requests to serve 404s at the edge rather than in my application, and that stopped the vast majority of spurious requests reaching the app. Screenshot below shows the point where this was deployed. Thanks again for your help!