I ran into an interesting issue today when I was working on an application I'm developing. Hopefully someone knows why this is happening / how to adjust my work flow for it!
Background:
I'm writing an application that helps students at universities get in touch with each other. The basic workflow is as follows:
User registers for the service
The application uses CURL to poll the university directory for their name
Store their contact info in a database table
My test site is the Rutgers University directory (http://www.acs.rutgers.edu/directory)
I can access the service fine through my browser (Posts to http://www.acs.rutgers.edu/pls/pdb_p/Pdb_Display.search_results), but if I try to post the same information via CURL, I get a 404 error.
Note: I get the same error if I open that url directly from a browser and don't use their form to submit the data.
Code:
Here is the code they use on the directory site:
<fieldset>
<legend>Search For People</legend>
<div style="width:50%;margin-left:auto;margin-right:auto;">
<form method="post" action="http://www.acs.rutgers.edu/pls/pdb_p/Pdb_Display.search_results" name="thisform" onkeyup="highlight()" onclick="highlight()">
<p>
<label for="p_name_last">Last Name: [Required]</label><br>
<input tabindex="1" accesskey="L" class="required" type="text" id="p_name_last" name="p_name_last" size="25" maxlength="23">
</p>
<p>
<label for="p_name_first">First Name: [or initial]</label><br>
<input tabindex="2" accesskey="f" type="text" id="p_name_first" name="p_name_first" size="25" maxlength="23">
</p>
<input tabindex="3" type="submit" value="Search">
</form>
</div>
And here is the code I am using to CURL the service:
<?php
$p_name_last = "doe";
$p_name_first = "";
$curlPost = 'p_name_last=' . urlencode($p_name_last) . '&p_name_first=' . urlencode($p_name_first) . '&SUBMIT=Search';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.acs.rutgers.edu/pls/pdb_p/Pdb_Display.search_results');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
if( ! $result = curl_exec($ch))
{
trigger_error(curl_error($ch));
}
curl_close($ch);
echo "<pre>";
print_r($result);
?>
Any thoughts or suggestions would be greatly appreciated!
Thanks,
Mike
Web servers can choose what response to send after processing the request. That'll be why you are seeing the 404 - there's a resource there but it's responding in a unintuitive manner.
Anyway, I can post with curl to this page and get a response;
curl http://www.acs.rutgers.edu/pls/pdb_p/Pdb_Display.search_results --data-urlencode p_name_last=test --data-urlencode p_name_first=test
If I post with your SUBMIT=... param I get a 404. Try it with just the two name parameters.
Update: in fact, you can send just the last name parameter so long as the first name parameter is present - the first name parameter can be empty.
The problem seems to be that the form's input element
<input tabindex="3" type="submit" value="Search">
contains no name attribute, hence is not sent along in the POST data in the form SUBMIT=search, or at least it shouldn't be, according to http://www.w3schools.com/tags/att_input_name.asp, where it is stated that
"Only form elements with a name attribute will have their values passed when submitting a form."
I suppose your attempt resulted in a 404 response because the script accepting your request never expects a SUBMIT variable, and that's why the accepted solution works.
check your browser proxy setting.
I had the same problem. It turned out it was caused by my proxy setting, which directed the request to the proxy server.
Indeed page http://www.acs.rutgers.edu/pls/pdb_p/Pdb_Display.search_results do not exists.
You have redirection to New Address: http://eas.rutgers.edu, browser can follow redirection but CURL might have a problem with it.
The web page you are trying to reach has moved!
New Address: http://eas.rutgers.edu
Please remember to update your bookmarks.
This page will automatically redirect in 10 seconds.
If redirect fails, click http://eas.rutgers.edu to continue.
The web page you are trying to reach has moved!
New Address: http://eas.rutgers.edu
Please remember to update your bookmarks.
This page will automatically redirect in 10 seconds.
If redirect fails, click http://eas.rutgers.edu to continue.
Related
What I am trying is submit a form on remote site, the output of that form is a pdf file which I want to store to my site locally. I want to automate this via cron job, using PHP and cURL.
Problems:
Remote site is https (even worse it is not properly setup)
The site is html and not PHP but it gives result as if PHP
What I have tried so far
I used cURL in PHP but did not quite work. It simply submits a response which does not include the response from the form submission.
I tried to create remote form on my local host and when I submit form, it does return pdf file but this solution does not uses Curl and hence I cannot automate it.
Code that I have tried so far
<?php
// set post fields
$post = [
'bench_sno' => '1',
'causelist_date' => '2010-10-1',
'btnSearch' => 'Search Causelist',
];
$ch = curl_init('http://peshawarhighcourt.gov.pk/app/site/4/p/Causelists_List.html');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
// do anything you want with your response
//var_dump($response);
echo $response;
?>
When I just copy the remote form to my site and submit the form, it does work fine Working Example but the problem is it does not work with cURL. I need to automate this task via cron job, any other solution if available, I can consider.
As came under discussion in the question itself, and pointed out by #vivek_23 to include it in the fields, the form now works
<input type="hidden" name="url" value="http://peshawarhighcourt.gov.pk:443/app/site/4/p/Causelists_List.html">
Below is my code using curl and it's not really redirect like HTML form :
$curl = new \Curl\Curl();
$curl->setHeader('Content-Type', 'application/x-www-form-urlencoded');
$curl->setOpt(CURLOPT_FOLLOWLOCATION,true);
$curl->setOpt(CURLOPT_POST,true);
$curl->setOpt(CURLOPT_RETURNTRANSFER,true);
$curl->post('http://localpay.sample.test/make-payment',$params);
Hi guys,above are the sample code that I made using php package : curl/curl ,
but don't worry,I'm looking forward for any answer,answer using pure curl also can and any other answer also can as long it's working with php language.
What I'm trying to achieve is how to do an API call works exactly the same like HTML form. Why I want to achieve this ? because in the HTML form we need to click the submit button,I know javascript can do the trigger but I'm trying to build my own package with totally back-end language.
I already tried search for the questions on the internet, but none was what I expected.
And below is my simple html form and it does redirect to the desired url :
<form id="payment_confirmation" action="http://localpay.sample.test/make-payment" method="post"/>
Payer ID : <input type="text" name="payer_acc_id"><br>
Payee ID : <input type="text" name="payer_acc_id"><br>
<input type="hidden" name="signature" value="somePhpFunction()">
<button type="submit" value="Submit"> Submit</button>
</form>
Above is the sample working HTML form and it's redirect to that action url path but in curl I fail to achieve it, so how do I achieve this by using curl or any other ways also can.
setting the Content-Type header does not dictate which format curl will use to send the post data. if you give CURLOPT_POSTFIELDS an array then curl will send the data using the multipart/form-data format, regardless of what you put in the Content-Type header. most likely your curl code sends the data in the Multipart/form-data format and $params is an array, and because you tell the server this is application/x-www-form-urlencoded, the server ties to parse the multipart/form-data data as application/x-www-form-urlencoded,
(which is a completely incompatible format), and doesn't understand the data at all. if you want to convert an array of post data to the application/x-www-form-urlencoded-format, use the http_build_query function, eg
$curl->post('http://localpay.sample.test/make-payment',http_build_query($params));
I found the answer for POST redirect using curl :
$params = ['payee_id' => 1 , 'amount' => 300];
$curl = curl_init('http://someurl.com/silent/pay');
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params));
curl_exec($curl);
curl will follow the redirect for POST method, if you guys want more explanation,go here.
I'm all in a security funk right now so I'm going through making everything as secure as possible. I got a login going and I'm referencing this:
http://www.addedbytes.com/writing-secure-php/writing-secure-php-1/
The first example is that of a login and if you say ?authorization=1 you get in. But if I wrap my code around a if($_POST) then the user MUST make a post. Can a user fake a $_POST? How do I go about faking a $_POST?
A user can simply create a file on their local machine with:
<form action="http://yoursite.com/login.php" method="post">
<input type="text" name="username" value="hahaha faked it!" />
<input type="text" name="password" value="hee hee you can't tell this is fake" />
<input type="submit">
</form>
and boom, "fake" post. In other words, you have to assume that anything and everything the user sends is potentially fake.
Two ways, make a curl request, or actually set the post variable on top of the php. E.g:
$_POST['var'] = "WHAT I WANT";
Yes they can.
With cURL and other HTTP clients, anybody can fake this.
Watch this
<form method="post" action="http://yoursite/index.php">
<input type="text" name="authorization" value="1" /><input type="submit">
</form>
Then user saves this as .html in their computer, opens in theirbrowser. Then posts the form.
You can use cURL in PHP to POST like so:
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch,CURLOPT_POST, 1);
curl_exec($ch);
curl_close($ch);
The $_POST superglobal variable is populated from the query string that's contained in the body of an HTTP POST request. Since the user/client is the one who initiates the HTTP (POST & others) requests to the HTTP server, then yes - the client can "fake" a $_POST array's values & keys.
Refer:
POST (HTTP) # wikipedia.org
Methods GET and POST in HTML forms - what's the difference?
Tamper Data - Firefox add-on # addons.mozilla.org
In whatever page where the HTML is. Do this very first thing.
<?php
session_start();
/** Generate some random numbers */
$wipit = rand(0,999999999);
/** Store the WIPIT Generators value in the SESSSION */
$_SESSION["WIPIT"] = $wipit;
?>
And do this in whatever page you are doing the POSTING validation and other things.
<?php
session_start();
/** Check for the REQUEST TYPE and SESSION WIPIT */
if( isset( $_SERVER['REQUEST_METHOD']) == "POST" and isset($_SESSION["WIPIT"]) and !empty($_SESSION["WIPIT"]) ){
/* Rest of your code goes here... */
}
?>
...yes a user can "fake" a post (whatever that means). Try tamper data on for size.
If your website has the problem of not escaping all text properly, it is an XSS weakness that can be exploited by a third party by injecting a (javascript-)script into the page which can use AJAX to send post requests with the users cookies and authority, with the least worst effect being that it could for example log out the user.
I want to make a http post to an outside url using php. By outside url I mean the url i not hosted on my servers.The url is called in an iframe. I need to know if this is technically possible to do this.
I tried doing this using curl but curl creates its own session with the remote server while I want to use the session which the browser has already created.
Please let me know your thoughts on this.
<?php
php code to make http post.
?>
<iframe src="outside url to be posted" height="100" width="100"/>
The outside url is google calender, so when I call it, if the user is already logged into google, his calender should display and I need to make a post to the calender using http post to save a calender event.
I hope this makes myself more clear on what am trying to achieve.
Update - Current Answer
After the update to your question, here's a different answer that I think addresses your issue more closely.
I think the question you are asking involves doing things with a user's credentials on another site. This is dancing dangerously close to Cross-site Request Forgery.
If you only do the POSTing when the user requests that you do it, it's a little better (I guess) but still inadvisable.
Why don't you use the Google Calendar API to do what you need?
Previous Answer
You need to tell cURL to use a particular session. Because PHP is managing the session, you'll also need to tell php to stop writing to the session while cURL uses it.
Try this:
$strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=/';
session_write_close();
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt( $ch, CURLOPT_COOKIE, $strCookie );
$response = curl_exec($ch);
curl_close($ch);
$_COOKIE['PHPSESSID'] will be the identifier for your PHP session, and $url will be the URL you've pulled out of the iframe.
This is taken virtually verbatim from this blog post. It was one of the first links on Google, so I didn't do a lot of extra digging.
I've done a bit of messing with cURL and PHP sessions, so this looks right based on what I remember.
Edit:
By the way, you should reference this SO question for the method to do POSTs with cURL. I assume you at least have some idea of how to do this, but there it is in case you need a refresher.
Also (in case it's not clear already), you can run as many
curl_setopt($handle, (CURL OPTION), (CURL VALUE));
lines as you need to configure cURL the way you need it.
e.g.:
POST vals
Session settings
etc., etc.
Good luck!
It's javascript, not php.
<form id="post_form" method="post" target="post_frame">
<input type="hidden name="field1" value="value1>
.... other fields
</form>
<script type="text/javascript">
document.getElementById("post_form").submit();
</script>
<iframe name="post_frame" height="100" width="100"/>
right off the file_get_contents man page:
<?php
// Create a stream
$opts = array(
'http'=>array(
'method'=>"POST",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);
//put post content into cookie part
$context = stream_context_create($opts);
// Open the file using the HTTP headers set above
$file = file_get_contents('http://www.example.com/', false, $context);
?>
<div><?=$file?></div>
not rly an iframe but the same idea
I have a html form with action="script1.php"
In script1 I need write all data to the database and redirect to
script2.php, but I need all parameters posted to script1 to be sent to script2.
mod_rewrite is on
How I can redirect using PHP with all data come through POST ?
if i do like that this disgusting practice but
<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
<!--
function Search(){
wpc_form.submit();
}
// -->
</script>
</HEAD>
<BODY onload='Search()'>
<form name=wpc_form method="post" action="/script2/">
<?php
foreach($_REQUEST as $name => $value)
echo '<input type="hidden" name="'.$name.'" value="'.$value.'">'
?>
</form>
Impossible.
But you don't need it. Because you have all this data already. Just read it from the database in script2.php
A redirect doesn't allow you to do this unless you have custom client-side code running in the browser to extract state from the response message body in order to populate your form fields. This is advanced usage and probably not what you really want to do.
If you really do need to transmit state between your forms then you can use the session to do this. The form in the browser won't have access to the data, but your PHP script running on the server can store values between requests. Here's a link to a tutorial on sessions in PHP which might be of use to you. This approach is often used for maintaining application state between requests and redirects to third-party services such as OpenID providers etc.
You can use the cURL library (or similar) to send a separate POST request from your local script to the external service.
// assemble data from your post here:
$data = array('formfield' => 'data', 'otherfield' => 'otherdata');
// and then send it off somewhere else
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://somewhere.else');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_exec($ch);