Understandable. Please note however that I said "possible attack vector" and also between parenthesis "which might be combined with other vectors".
Although most (sane) web servers would limit each header to about 8KB (and up to 100 headers in each request), some others, like IIS, allow up to 16KB per header.
Please note that lines 341-342 trim $this->data['session_forwarded_for'] and $this->forwarded_for to 255 chars. So why bother possibly validating 8KB filled with (forged IPs) if we'll later only really look at the first 255 bytes?
To simplify, in 255 bytes, I could send 32 IP addresses, comma seperated. That is: a.b.c.d (7 chars)
32 * 7 = 224 chars
31 commas + 224 chars = 255 bytes
Imagine, with such 255 bytes, causing the foreach loop @ lines 228-237 to call preg_match(get_preg_expression()) 32 times
Edit: and that is after explode creating an array, whose number of elements are up to the number of comma-separated IPs in the forwarded header. Furthermore, foreach works on a copy of the array, rather than the array (which had just been created).
184.108.40.206, .. 220.127.116.11, 18.104.22.168, ... 22.214.171.124 .. etc..
up to 900 IPs just in the range 126.96.36.199 through 188.8.131.52
And with up to 8KB header limit, I can easily fit 900 IPs
900 IPs * 7 chars = 6300 bytes
899 commas + 6300 = 7199 bytes (under 8KB)
I don't think this really needs a PoC. A simple (threaded) script, given enough bandwidth, could make quite a noticeable effect on server's resources (or availability).
And if DEBUG_EXTRA is on, perhaps the attacker could even change the IP at the last few bytes in the 255byte range of the HTTP_X_FORWARDED_FOR header, and maybe emulate a bot in the HTTP_USER_AGENT to bypass the second condition of the if statement (line 437):
$this->data['user_id'] != ANONYMOUS
and flood the log as well (plus 2 extra htmlspecialchars calls, on something that was already previously htmlspecialchar'd, and preg_match ip validated)...
Which reminds me, shouldn't that rather be && $this->data['is_registered'] ?