But is this class safe?
Well, it’s safe enough. The only input is $ip, and that is passed through
ip2long(), which converts a string like “184.108.40.206” into a signed long int, or returns false.
That’s basic security – take your inputs and validate them, or run them through a function that transforms the input into a trusted value. A trusted value is of a specific type, and falls within a known range, or matches a specific pattern.
For example, if you expect and integer input, use
intval() to convert the string to an integer. There are also the
filter_var() and related functions to test the input, and those are good, as well.
A Comment About Path Traversal Attack Fixes
The article I linked has some advice. Having been bitten by the path traversal attack, I have become more wary of having any flexibility in accepting input.
Rather than rely on regex patterns or whitelists of acceptable paths, I find it’s easier to just use a dictionary to map names to paths.
$pathmap = [ 'foo' => APP_DATA_ROOT.'path/to/foo', 'bar' => APP_DATA_ROOT.'path/to/bar', 'baz' => APP_DATA_ROOT.'some/other/path/to/baz' ];
Note that APP_DATA_ROOT must not be a relative path. Always set the application paths to absolute paths.
Then check that the input is one of the keys, using
in_array($path, array_keys($pathmap)). Based on that, you retrieve the path, and access the file or files. There’s no indeterminacy, and no flexibility, in the code.
For filenames, don’t allow the end user to pick one. If you do, restrict it severely. Split it on the ‘.’ and pluck out the first and last elements, and validate it it to contain only the alphabet and numbers.
preg_match('/^[a-zA-Z0-9]+$/'). If there’s a name clash, append a random string to the name.
All the other characters belong to you. Use dashes to separate fields, so you can make variations on the file.