Can an IP address be spoofed? What a source address in your logs does and does not prove

A firewall log names an address, an abuse report accuses one, a customer swears theirs was spoofed. The honest answer to "can that be forged" is yes and no, and the boundary between them is not the address but the transport it arrived on: a bare datagram can claim any source, a completed session almost never can. Here is how to read the evidence by transport, why the address flooding you is often another victim, and what an address in a log can and cannot prove.

Two lanes: a TCP exchange whose reply must return to the claimed source before the session opens, and a single UDP datagram that arrives with whatever source it claims TCP claimed source your server ok the reply must come back before the session opens UDP any address your server ? one datagram, no reply needed, source unverified
The protocol never checks a source address. What checks it, when anything does, is the round trip: a session that needed a reply to open was reachable at that address; a lone datagram proves only that something sent it.

Yes: the protocol checks nothing

Neither IPv4 (RFC 791) nor IPv6 (RFC 8200) defines any way for a router or receiver to verify a packet's source address; forwarding is by destination only, and the source field holds whatever the sender wrote. What stops forged sources, where anything does, is an operational practice: ingress filtering, BCP 38 (RFC 2827, May 2000) and BCP 84 (RFC 3704, updated by RFC 8704 in 2020), in which a provider drops packets arriving from a customer whose sources fall outside the prefixes that customer holds, and an operator can apply the same check at its own edge. MANRS lists it as Action 2 for operators, recommended rather than compulsory in the current specification (MANRS-003.01, 17 May 2021). Deployment is real but partial: CAIDA's Spoofer summary, as fetched on 18 August 2026, showed roughly one in six IPv4 /24s tested without NAT still letting forged sources out, from volunteer tests that are not a random sample. And even perfect filtering only narrows a forged source to a prefix, since RFC 2827 itself notes it does not stop forging another address in the same range. RFC 3704 draws the conclusion for you: it is impossible to know whether a particular attacker somewhere is being filtered, so a source in a raw packet log is a lead, not an identification.

The tell is the transport, not the address

A bare UDP or ICMP datagram arrives carrying whatever source its sender wrote, because neither protocol has a handshake; some protocols on top of UDP add a return-routability check of their own (DNS Cookies, RFC 7873, weakly, or a truncated answer that forces a TCP retry; QUIC's address validation properly), so judge per protocol. DNS transaction IDs and port randomisation are not that check: they defend a resolver against forged replies, and leave the source of an inbound query as unverified as any other datagram. TCP is different: a session opens only when each side has acknowledged the other's initial sequence number, so the server's reply had to reach whoever was receiving traffic for the claimed source. RFC 9293 carries the initial sequence number rule, a timer plus a keyed function an outsider cannot compute, that makes guessing one from off the path impractical on modern stacks. Two exceptions must stay in view: an attacker on the path, or on the same segment, who can see the reply, and a prefix hijack, where the return path was drawn to the hijacker rather than the holder. Below the session, a lone SYN proves little; RFC 4987 describes SYN floods from addresses that are often forged, and SYN cookies mean a flooded server may show no half-open state at all. So the reading rule: a SYN-only firewall entry is unverified; a completed HTTP request came from the address your server saw as its TCP peer, or from someone on the path to it, and either way not necessarily from the person who holds it. If the client address in your web log was copied out of a header rather than read off the connection, it is an assertion and not a handshake, and the next section but one applies.

When the address in your logs is another victim

In a reflection attack the attacker sends requests to open services with the source forged to the victim, and the services answer the victim. The addresses in the victim's logs are the reflectors' real addresses, and the reflectors' logs show the victim as the apparent requester; both are victims of a third party whose address neither has seen. US-CERT's archived alert on DNS amplification (2013) describes the mechanism, and its UDP-based amplification alert (last revised December 2019) lists the amplification factors of the day. The mirror image reaches abuse desks regularly: a complaint that your address queried someone's resolver or NTP server is what a forged-source event looks like from the reflector's side, and the first thing to check is whether the protocol involved was single-packet UDP. The second is whether you actually run that service and left it reachable, because an open resolver or NTP server of your own being used as somebody else's reflector produces a complaint that looks the same and is yours to fix, and the third is whether a host inside your network is emitting forged sources past your own egress filtering. Single-packet UDP is a reason to look further, not a reason to close the ticket. Backscatter is the same phenomenon seen from a third angle: unsolicited SYN-ACKs, RSTs or ICMP errors from hosts you never contacted usually mean somebody forged your address toward them, once you have confirmed nothing of yours contacted them first, because a compromised or noisy host inside your own network looks the same at the edge, and a freshly reassigned dynamic address can also inherit a previous tenant's stragglers. Moore, Voelker and Savage first measured attacks that way in 2001, and CAIDA's network telescope still watches roughly one 256th of IPv4 for it.

Forgery above IP is a different thing

In practice, most "my IP was spoofed" claims turn out not to be about forged packets at all. Web logs behind a proxy, CDN or load balancer record the intermediary as the TCP peer and take the client address from a header, X-Forwarded-For, X-Real-IP or the standard Forwarded field, and RFC 7239 says plainly that such a header cannot be relied on because every node on the way, including the client, can set it; only the hop appended by a proxy you configured your server to trust is evidence, so know which field your log stores. In mail, the address in the Received line your own server wrote came from a TCP connection and is real, though it is the machine that connected to you, which is often a forwarder, a mailing list or a shared outbound pool rather than the author's own host; the EHLO name, the earlier Received lines and the From header are assertions, which is why authentication exists. And when a customer says their address was spoofed in a completed, authenticated HTTPS session, blind forgery is not a plausible explanation; a shared address (CGNAT, a VPN or proxy exit, an office NAT), a compromised device or stolen credentials are, and each points at different evidence. Remember too that an address is a network location at a moment, not a person: without a source port and a UTC timestamp, even the provider often cannot say which subscriber sat behind a shared address.

What to do with the address

Decide by transport and state before you decide by address. Sources in documentation or other unroutable space at your edge are forged or leaked by definition, though ICMP errors from privately numbered router hops are the ordinary answer to your own traceroutes rather than an attack. For a reflected flood, in practice the useful reports go to the reflector operators, worded as notice that their service is answering forged requests rather than as an accusation, and to your upstream, and for a direct forged-source flood to your upstream alone, which is where filtering and coordination happen; the holder of a forged address cannot stop packets it did not send, though RFC 3704 notes that asking a potential source what it observes can still be a lead. For a completed session, the address is real evidence about a network, and a lookup tells you which one: who holds it, remembering that the registered holder is often an upstream or a reseller rather than whoever operated the address that day, which network announced its block during your time window as far as global BGP collectors saw it and whether that changed, whether the space is tagged as hosting or a proxy service, and which abuse contact answers for it. Check the routing history for the window before treating a completed connection as proof of the holder's involvement, because a hijacked prefix is the clearest case where the session was real and the holder never saw it, and an attacker on the path to the holder is another. More often the session genuinely came from that machine and the holder is still not your culprit: a compromised host, a CGNAT or office NAT shared by thousands, a hosting customer, a VPN or proxy exit. A completed session tells you which network to ask, not who to blame. Then report to the desk that can act, with the transport, the state and the timestamps that make the address mean something.

Look up the address on the front page for the network behind it and its history: the registered holder and abuse contact, the announcing network with first and last seen dates, whether the space is special-use or unannounced, and the confirmed tags and blocklist presence that separate eyeball ISP space from a hosting range or a proxy service. Every claim there names its source and the date it was read, so you can show where each fact came from.