Remote File Download Guard
Validates remote download metadata before fetching or storing files.
Function signature
ogValidateRemoteDownload(metadata = array(), policy = array())
Categories
- APIs and Webhooks
Parameters
metadataURL, headers, and content length metadata. Recognized keys: `content_length`, `content_type`, `url`.policyDownload policy options. Recognized keys: `allowed_content_types`, `max_bytes`.Return value
Short public-safe status message.
- url
- host
- content_length
- max_bytes
- content_type
- approved
Compatibility
Existing function name and call order preserved; metadata signature corrected to source.
Minimum PHP version: 7.4
Security notes
Validate request method, identity, permissions, policy arrays, URLs, signatures, and caller-owned allowlists before use; keep secrets and internal paths out of public output.
Code
<?php
/*
* Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
* Free for personal and internal use. Paid project use requires visible credit
* to Jeffery L. Paris. Corporate use requires a paid license fee unless a
* separate written license states otherwise.
*/
/**
* Validates remote download metadata before a server-side fetch.
*
* The function blocks non-HTTPS URLs, localhost/private IP hosts, oversized
* files, and disallowed content types before any download is attempted.
*
* @param array $metadata URL, headers, and content length metadata.
* @param array $policy Download policy options.
* @return array Approved or rejected remote download metadata.
*/
function ogValidateRemoteDownload($metadata = array(), $policy = array()) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
if (!is_array($metadata)) {
$result['message'] = 'Download metadata must be an array.';
return $result;
}
if (!is_array($policy)) {
$policy = array();
}
$url = '';
if (!empty($metadata['url'])) {
$url = trim((string)$metadata['url']);
}
if (filter_var($url, FILTER_VALIDATE_URL) === false) {
$result['message'] = 'Remote URL is invalid.';
return $result;
}
if (stripos($url, 'https://') !== 0) {
$result['message'] = 'Remote URL must use HTTPS.';
return $result;
}
$parts = parse_url($url);
$host = '';
if (!empty($parts['host'])) {
$host = strtolower($parts['host']);
}
if (empty($host) || $host == 'localhost') {
$result['message'] = 'Remote host is not allowed.';
return $result;
}
if (filter_var($host, FILTER_VALIDATE_IP)) {
if (!filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
$result['message'] = 'Private or reserved IP downloads are not allowed.';
return $result;
}
}
$max_bytes = 10485760;
if (!empty($policy['max_bytes'])) {
$max_bytes = (int)$policy['max_bytes'];
}
if ($max_bytes < 1024) {
$max_bytes = 1024;
}
$content_length = 0;
if (!empty($metadata['content_length'])) {
$content_length = (int)$metadata['content_length'];
}
if ($content_length > 0 && $content_length > $max_bytes) {
$result['message'] = 'Remote file is larger than the allowed limit.';
return $result;
}
$allowed_types = array('image/jpeg', 'image/png', 'image/webp', 'application/pdf', 'text/csv', 'application/json');
if (!empty($policy['allowed_content_types']) && is_array($policy['allowed_content_types'])) {
$allowed_types = $policy['allowed_content_types'];
}
$content_type = '';
if (!empty($metadata['content_type'])) {
$content_type = strtolower(trim((string)$metadata['content_type']));
$content_type = trim(strtok($content_type, ';'));
}
if (!empty($content_type) && !in_array($content_type, $allowed_types, true)) {
$result['message'] = 'Remote content type is not allowed.';
return $result;
}
$result['success'] = true;
$result['message'] = 'Remote download metadata approved.';
$result['data'] = array(
'url' => $url,
'host' => $host,
'content_length' => $content_length,
'max_bytes' => $max_bytes,
'content_type' => $content_type,
'approved' => true
);
return $result;
}