It only depends on IP fragmentation to forge UDP datagrams. It forges TCP segments by padding the previous segment.
But, as gnfargbl points out, the TCP case can be caught by looking at the sequence number, or perhaps some conntrack state.
But, as gnfargbl points out, the TCP case can be caught by looking at the sequence number, or perhaps some conntrack state.
... except these arbitrary tcp/udp packets will be in IP fragments and therefore invalid.
The whole thing hinges on the NAT code NOT reassembling IP packets before passing them to ALG and the ALG also not observing IP fragmentation. These are bugs, and pretty severe at that, so the mitigation is just to patch the code.