Part of my site's application process is that a user must prove ownership of a website. I quickly threw together some code but until now didn't realize that there could be some vulnerabilities with it.
Something like this:
$generatedCode="9s8dfOJDFOIesdsa";
$url="http://anyDomainGivenByUser.com/verification.txt";
if(file_get_contents($url)==$generatedCode){
//verification complete!
}
Is there any threat to having a user-provided url for file_get_contents()?
Edit: The code above is just an example. The generatedCode is obviously a bit more elaborate but still just a string.
Yes, this could possibly be a Server Side Request Forgery vulnerability - if $url
is dynamic, you should validate that it is an external internet address and the scheme specifies the HTTP or HTTPS protocol. Ideally you'd use the HTTPS protocol only and then validate the certificate to guard against any DNS hijacking possibilities.
If $url
is user controllable, they could substitute internal IP addresses and probe the network behind the firewall using your application as a proxy. For example, if they set the host in $url
to 192.168.123.1
, your script would request http://192.168.123.1/verification.txt
and they might be able to ascertain that another machine is in the hosted environment due to differences in response times between valid and invalid internal addresses. This is known as a Timing Attack. This could be a server that you might not necessarily want exposed publicly. Of course, this is unlikely to attack your network in isolation, but it is a form of Information Leakage and might help an attacker enumerate your network ready for another attack.
You would need to validate that the URL or resolved DNS each time it was requested, otherwise an attacker could set this to external to pass the validation, and then immediately re-point it to an internal address in order to begin probing.
file_get_contents()
in itself appears safe, as it retrieves the URL and places it into a string. As long as you're not processing the string in any script engine or using it as any execution parameter you should be safe. file_get_contents()
can also be used to retrieve a local file, but if you validate that it is a valid internet facing HTTP URL as described above, this measure should prevent reading of local files should you decide to show the user what verification.txt
contained in case of mismatch. In addition, if you were to display the contents of verification.txt
anywhere on your site, you should make sure the output is properly encoded to prevent XSS.