Allowing Moodle cURL Requests to Localhost for Development
How to allow Moodle's cURL wrapper to reach localhost services during development, and what security implications to be aware of.
You’re building a Moodle plugin that calls a service on your local machine — a REST API, a microservice, an AI backend, a webhook handler. You send the request through Moodle’s built-in cURL wrapper. Nothing comes back. No connection error, just silence, or a vague failure in your plugin’s response.
The cause: Moodle blocks outbound cURL requests to localhost (127.0.0.1, ::1) by default. This is intentional — it guards against Server-Side Request Forgery (SSRF), where an attacker tricks the server into fetching internal resources. On production that protection is essential. On a local dev machine it just gets in the way.
This guide shows how to lift that restriction.
What you’ll see
With developer debugging enabled, Moodle logs a message from corefilescurl_security_helper indicating the URL was blocked. Without debugging, the cURL call silently returns false or an empty response with no further detail.
Fix: admin UI (recommended)
Go to Site administration > General > Security > HTTP security.
Step 1 — cURL blocked hosts list: clear this field entirely. When empty, Moodle skips the reserved-address check that blocks localhost.
Step 2 — cURL allowed ports list: confirm ports 80 and 443 are listed, then add the port your local service uses (e.g., 8000). If this list contains any entries at all, Moodle blocks every port not listed.
Step 3: click Save changes, then go to Site administration > Development > Purge all caches.
Fix: config.php (alternative)
If you can’t access the admin UI, or want a scripted setup, add these lines to config.php after the require_once(__DIR__ . '/lib/setup.php'); line:
$CFG->curlsecurityblockedhosts = ''; // empty = localhost not blocked
$CFG->curlsecurityallowedport = '80,443,8000'; // add your dev port here
Then purge caches.
Verify
Retry the cURL call from your plugin. If it still fails, enable developer debugging (Site administration > Development > Debugging, set to DEVELOPER) and check the output for messages from curl_security_helper.
Don’t carry this into production
An empty blocked hosts list disables SSRF protection for all local addresses. On a production server, the list should contain at minimum:
127.0.0.0/8
::1/128
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
Only remove entries if you have a specific, trusted internal service and understand the exposure.
Solin specializes in Moodle development environments and plugin testing.
Contact us