Can you set $_POST values outside the script?
Moderator: General Moderators
- social_experiment
- DevNet Master
- Posts: 2793
- Joined: Sun Feb 15, 2009 11:08 am
- Location: .za
Can you set $_POST values outside the script?
This post stems from another thread (post forms security - tampering) but is (to me) related to this: Is there a way to fake (spoof) $_POST values?
“Don’t worry if it doesn’t work right. If everything did, you’d be out of a job.” - Mosher’s Law of Software Engineering
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Can you set $_POST values outside the script?
If you mean craft a post that appears to be coming from the site, but is not -- then yes. That's why there is only the concept of untrusted data. It doesn't matter where the post comes from, you can't trust the data and have to validate and filter.
(#10850)
Re: Can you set $_POST values outside the script?
Easiest way, Firebug. You can change anything on the currently displayed site (even the "generated" code made via Javascript).
I worked on a shopping cart once, where to save on doing AJAX calls back to the server for each time you changed an attribute to get that combinations price, they had them all just as "hidden" inputs, and the JS called the price to display from that one. Well because the site had a pain in the rump advanced joins across like 4 tables to get the price, the person who coded the "Add to cart" code, just grabbed the price from the submitted "Hidden" values. I could go to the page, have a $250 item, firebug it, change it to $5.00 do add to cart, and go through checkout and pay $5.00 (plus shipping) for a $250 item. And even worse, this particular company the site was for, had people fulfilling the orders who didn't care what price was on them, they just saw "Qty 3 of SKU 435345" and put that many in a box and shipped, and wouldn't have noticed.
That is why you never trust anything that can be altered by the user, $_POST / $_GET / $_COOKIE / $_SERVER['PHP_SELF'] / $_SERVER['HTTP_USER_AGENT'] / $_SERVER['HTTP_REFERRER'] are the main used ones.
-Greg
I worked on a shopping cart once, where to save on doing AJAX calls back to the server for each time you changed an attribute to get that combinations price, they had them all just as "hidden" inputs, and the JS called the price to display from that one. Well because the site had a pain in the rump advanced joins across like 4 tables to get the price, the person who coded the "Add to cart" code, just grabbed the price from the submitted "Hidden" values. I could go to the page, have a $250 item, firebug it, change it to $5.00 do add to cart, and go through checkout and pay $5.00 (plus shipping) for a $250 item. And even worse, this particular company the site was for, had people fulfilling the orders who didn't care what price was on them, they just saw "Qty 3 of SKU 435345" and put that many in a box and shipped, and wouldn't have noticed.
That is why you never trust anything that can be altered by the user, $_POST / $_GET / $_COOKIE / $_SERVER['PHP_SELF'] / $_SERVER['HTTP_USER_AGENT'] / $_SERVER['HTTP_REFERRER'] are the main used ones.
-Greg
- social_experiment
- DevNet Master
- Posts: 2793
- Joined: Sun Feb 15, 2009 11:08 am
- Location: .za
Re: Can you set $_POST values outside the script?
Thanks for the replies; i assume that you're both refering to values such as hidden input's, text input, checkboxes, dropdown boxes, radio buttons or does this include every single $_POST item? The example below:
Can you spoof $_POST['submitButton'] and so that the script will start processing?
Code: Select all
<?php
if isset($_POST['submitButton'])) {
// do processing
}
?>“Don’t worry if it doesn’t work right. If everything did, you’d be out of a job.” - Mosher’s Law of Software Engineering
Re: Can you set $_POST values outside the script?
Yes, you have to remember that on the server it gets all the post values the same way, all it knows is "here is a name and here is the value", it doesn't know that it came from a button, input, select, textarea, etc. That is strictly for the browser so it knows how to collect the value.
I can put a script on my server that will use curl to send requests to your site, that say the referring site is your site, that it is a firefox browser and contain post data.
So if you have, say for simplicity sake, a simple guestbook. I go to it, I see that I fill out a little form hit submit, and "wow! there is my message and link to my site live immediately". So I look at the form, see what the fields are. I write a script and set it to run once a day, and cool, my site is advertised every day on your site!
Heck even an up to date word press install can have this happen. Had the owner of company get several hundred e-mails to his iPhone PER HOUR one night because someone targeted his blog to auto submit spam comments. Now while they didn't auto display, it did e-mail him every post that a comment needed reviewed. Now being in the position he was in as owner of the company and wanting to be available 24/7 if a customer had a site issue, shutting his phone off at night when he goes to bed isn't an option.
By the time it came to my attention, there was several THOUSANDS of comments to clean out of the database. We locked it down pretty good, you have to submit the form withing 30 minutes from when the page with the form is loaded. The form has a hash of the timestamp on it (do a search for "int2key" on here to find the post where I put the code to code/decode) The forms on the sites have this form field:
That value is the current time stamp. If you can guess how to change that value to be a current time stamp so it is always current, then you are awesome and I'll accept the spam lol (see my post i said to search for on how it gets generated) Now you will notice, the field name is "comment_author_hash". If someone is gonna look at the code to see why their "bot" is failing, why give them something obvious like "form_timestamp" ;-) I'm all about deception when it comes to that (I usually name honeypot fields URL or txtURL to encourage a bot to fill it out in case it is automated or the person writing it isn't paying attention.)
All worked very nicely, and no need for fugly captcha, or the server overhead of having to fully load up the site to process a plugin to determine the comment was spam. The actual wordpress code never even fired if it was a comment submitted without the hidden field, or the hidden field was more than 30 minutes old.
You ever want to test an actual script, PM the info, I love a challenge like that!
-Greg
I can put a script on my server that will use curl to send requests to your site, that say the referring site is your site, that it is a firefox browser and contain post data.
So if you have, say for simplicity sake, a simple guestbook. I go to it, I see that I fill out a little form hit submit, and "wow! there is my message and link to my site live immediately". So I look at the form, see what the fields are. I write a script and set it to run once a day, and cool, my site is advertised every day on your site!
Heck even an up to date word press install can have this happen. Had the owner of company get several hundred e-mails to his iPhone PER HOUR one night because someone targeted his blog to auto submit spam comments. Now while they didn't auto display, it did e-mail him every post that a comment needed reviewed. Now being in the position he was in as owner of the company and wanting to be available 24/7 if a customer had a site issue, shutting his phone off at night when he goes to bed isn't an option.
By the time it came to my attention, there was several THOUSANDS of comments to clean out of the database. We locked it down pretty good, you have to submit the form withing 30 minutes from when the page with the form is loaded. The form has a hash of the timestamp on it (do a search for "int2key" on here to find the post where I put the code to code/decode) The forms on the sites have this form field:
Code: Select all
<input type="hidden" class="hidden" name="comment_author_hash" value="85cQjZyUDM1YTM" />All worked very nicely, and no need for fugly captcha, or the server overhead of having to fully load up the site to process a plugin to determine the comment was spam. The actual wordpress code never even fired if it was a comment submitted without the hidden field, or the hidden field was more than 30 minutes old.
You ever want to test an actual script, PM the info, I love a challenge like that!
-Greg
- social_experiment
- DevNet Master
- Posts: 2793
- Joined: Sun Feb 15, 2009 11:08 am
- Location: .za
Re: Can you set $_POST values outside the script?
Thanks for the info (and explanation); I was not sure of the possibility of the submit button being spoofed but i see that it is. To me it seems that the solution to this is not to try and stop the form being processed because that seems to be impossible, rather it's to see if the submission was made from the 'correct' form
“Don’t worry if it doesn’t work right. If everything did, you’d be out of a job.” - Mosher’s Law of Software Engineering
- flying_circus
- Forum Regular
- Posts: 732
- Joined: Wed Mar 05, 2008 10:23 pm
- Location: Sunriver, OR
Re: Can you set $_POST values outside the script?
It's not so much spoofing as it is crafting. Of course you can craft an http post, and you dont need a browser to do it. You can insert any data that you want. By viewing the page source of the form you wish to craft, you will have an idea of what pieces of data the server expects. Once you know the fields the server expects, you can insert any arbitrary data.social_experiment wrote:This post stems from another thread (post forms security - tampering) but is (to me) related to this: Is there a way to fake (spoof) $_POST values?
Consider the following running telnet from a shell.
Code: Select all
$ telnet example.org 80
> POST /test/forms/login.php HTTP/1.1
> Host: example.org
> User-Agent: myTelnetScript
> Content-Length: 86
> Content-Type: application/x-www-form-urlencoded
> Cookie: PHPSESSID=1234
>
> username=Tony&password=password&persistent=on&hiddenInput=someData&=submitButton=Login
>
> Code: Select all
print_r($_POST);
//Array ( [username] => Tony [password] => password [persistent] => on [hiddenInput] => someData [submitButton] => Login )