Maybe something like:
header('Location: /' . $_GET['redirect']); //start forward slash guarantees domain cant change?
No, a leading forward slash does not protect you against open redirects.
An attacker could query the script as...
Location: //malicious.example which is treated as a protocol-relative URL that your browser will understand as a redirect to
This notation also works for URLs in other contexts, e.g. HTML links:
Is there a simple way (not a whitelist) to ensure that the redirect not leave the domain.
An alternative simple approach to @David's answer is checking for a slash and a subsequent alphanumeric character, or the beginning sequence
/./. Both can never lead to the representation of an absolute URL.
Note that in older versions of PHP you also had to sanitize a user-supplied header value for newlines/carriage returns as you might otherwise enable header injection attacks.
From your follow-up comment:
what if it started with a protocol and hostname? eg,
header('Location: https://domain.com' . $_GET['redirect']) is there a way around that?
This is only safe if you enforce that the first user-supplied character is a slash. Otherwise, a simple attack would be
.malicious.example, redirecting to the attacker-controlled subdomain
@malicious.example works too, since that turns
domain.com into the username for authenticating with the domain