How to get remote page with php cURL securely - php

I will have an app where I will prompt users for a URL (with proper regex url validation) and return the page with cURL and run some checks on it.
What would be the most secure way of returning a remote webpage securely with cURL? As I understand even cURL has some vulnerabilities, like 'safe mode' Security Bypass (http://www.securityfocus.com/bid/27413).

SecurityFocus claims this has been fixed in PHP 5.2.6 . If you can't upgrade to that, you need to manually check for that attack vector. Perhaps check in your user input if the url definitely has "http" in front of it, with if (substr($url, 0, 7) == 'http://'))
Furthermore, according to the comments on this php bug report curl gives you the option to disable specific protocls, including local file access, but only when you configure and compile from source. According to the cURL install manual it must be something like this (untested):
./configure --disable-file

Related

Security vunerability - What is this URL trying to do?

I've just received the following error from a few sites I run:
Error Caught in Application_Error event
Error in:
https:///phppath/php?-d+allow_url_include=on+-d+safe_mode=off+-d+suhosin.simulation=on+-d+disable_functions=""+-d+open_basedir=none+-d+auto_prepend_file=php://input+-n
Error Message:A potentially dangerous Request.Form value was detected
from the client (="Stack Trace: at
System.Web.HttpRequest.ValidateString(String value, String
collectionKey, RequestValidationSource requestCollection)
Obviously, the ASP.NET has just rejected this - a good thing.
But what I do not understand, not being a PHP type chap, is what it is trying to do?
The attacker has sent PHP code in the HTTP request body, and he is trying to have that code executed by your web server.
The php://input references the request body (ie POST data). The auto_prepend_file directive allows the script to include PHP code in the same way that include() and require() work. If successful, the uploaded code would be prepended and executed.
The payload most likely contains a backdoor script and some code to call home to let the developer know that a hack was successful.
This is most likely a bot that has randomly selected your server, as opposed to a human manually attempting it.
The bug that the attacker is trying to exploit is CVE-2012-1823:
sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not properly handle query strings that lack an = (equals sign) character, which allows remote attackers to execute arbitrary code by placing command-line options in the query string, related to lack of skipping a certain php_getopt for the 'd' case.
http://www.cvedetails.com/cve/CVE-2012-1823

When I run following url on my browser it runs fine but when i use php function its getting 505 Page . Can any one help me with that

$output = file_get_contents("http://www.canadapost.ca/cpc2/addrm/hh/current/indexa/caONu-e.asp");
var_dump($output);
HTTP 505 Status means the webserver does not support the HTTP version used by the client (in this case, your PHP program).
What version of PHP are you running, and what HTTP/Web package(s) are you using in your PHP program?
[edit...]
Some servers deliberately block some browsers -- your code may "look like" a browser that the server is configured to ignore. I would particularly check the user agent string that your code is passing along to the server.
Check in your PHP installation (php.ini file) if the allow_url_fopen is enabled.
If not, any calls to file_get_contents will fail.
It works fine for me.
That site could be blocking the server that you're using to access it.
When you run the URL from your browser, your own ISP is used to get the information and display in your browser. But when you run from PHP, the ISP of your web host is used to get the information, then it passes it back to you.
Maybe you can do this to check and see what kind of headers its returning for you?
$headers=get_headers("http://www.canadapost.ca/cpc2/addrm/hh/current/indexa/caONu-e.asp");
print_r($headers);

can you use curl to post to a local file?

I tried using curl to post to a local file and it fails. Can it be done? my two management systems are on the same server and it seems unnecessary to have it traverse the entire internet system just to go to a file on the same hard drive.
Using localhost didn't do the trick.
I also tried to $_SERVER[DOCUMENT_ROOT].'/dir/to/file.php' using post data. It's for an API that is encrypted, so I'm not sure exactly how it works. It's for a billing system I have and I just realized that it sends data back (API).
It's simply post data and an XML response. I could write an html form tag and input fields and get the same result, but there isn't really anything else to know.
The main question is: Does curl have the ability to post to a local file or not?
it is post data. it's for an API that is encrypted so i'm not sure exactly how it works
Without further details nobody can answer then what you should do.
But if it's indeed a POST receival script on the local server, then you can send a POST request to it using the URL:
$url = "https://$_SERVER[SERVER_NAME]/path/to/api.php";
And then receive its output from the cURL call.
$data = curl($url)->post(1)->postdata(array("billing"=>1234345))
->returntransfer(1)->exec();
// (you would use the cumbersome curl_setopt() calls instead)
So you get a XML or JSON or whatever response.
If they're on the same drive, then use file operations instead:
file_put_contents('/path/to/the/file', $contents);
Using CURL should only be done if you absolutely NEED the http layer to get involved for some reason, or if you're dealing with a remote server. Using HTTP would also mean you need to have the 'target' script be able to handle a file upload plus whatever other data you need to send, and then that script would end up having to do file operations ANYWAYS, so in effect you've gone on a round-the-world flight just so you can move from your living room to the kitchen.
file://locafilespec.ext worked for me. I had 2 files in the same folder on a linux box, in a folder that is not served by my webserver, and I used the file:// wrapper to post to file://test.php and it worked great. it's not pretty, but it'll work for dev until I move it to it's final resting place.
Does curl have the ability to post to a local file or not?
To curl local file, you need to setup HTTP server as file:// won't work, so:
npm install http-server -g
Then run the HTTP server in the folder where is the file:
$ http-server
See: Using node.js as a simple web server.
Then test the curl request from the command-line to localhost like:
curl http://127.0.0.1:8081/file.html
Then you can do the same in PHP.

PHP: Curl can't grab a text-only page on my own site

I'm attempting to use curl inside php to grab a page from my own web server. The page is pretty simple, just has some plain text output. However, it returns 'null'. I can successfully retrieve other pages on other domains and on my own server with it. I can see it in the browser just fine, and I can grab it with command line wget just fine, it's just that when I try to grab that one particular page with curl, it simply comes up null. We can't use file_get_contents because our host has it disabled.
Why in the world would this be different behavior be happening?
Found the issue. I was putting my url someplace that was not in curl_init(), and that place was truncating the query string. Once I moved it back to curl_init, it worked.
Try setting curl's user agent. Sometimes hosts will block "bots" by blocking things like wget or curl - but usually they do this just by examining the user agent.
You should check the output of curl_error() and also take a look at your logfiles for the http server.

How to use the PHP built-in server with Windows Authentication (NTLM) to fill $_SERVER["LOGON_USER"]?

I have scripts that use the $_SERVER["LOGON_USER"] which is obtained on my servers through IIS authentication settings. I want this same variable to contain my domain\username when running locally, or at least to have a way to set it when I fire up the PHP built-in server on localhost.
How can I configure PHP on my machine to obtain and fill this variable the same way it does when running through IIS?
PS: I have seen this question, but the answer addresses $_ENV, not $_SERVER.
This is a workaround, if anyone has a better/proper solution (i.e. enabling NTLM), please post it as an answer and I'll accept it.
I was able to fill that variable using a router script. According to the docs, this script is run at the start of each HTTP request, so I use it to set this variable when running locally.
Also in my case, my environment had these two variables set, USERDOMAIN and USERNAME, so I used them to form the LOGON_USER server variable.
routerCredentials.php
<?php
$_SERVER["LOGON_USER"] = getenv("USERDOMAIN") . "\\" . getenv("USERNAME");
return false; // serve the requested resource as-is.
To use it, you just have to point to that file when you start the PHP built-in server:
php -S localhost:8000 "c:\somepath\routerCredentials.php"

Categories