How to get around people changing form submit methods - php

I've got the following HTML
<form action="/home" method="post">
<input type="hidden" name="_method" value="POST">
<input type="text" name="var">
<button type="submit">Submit</button>
</form>
on the server side, I trigger different actions based on the type of request I get. The _method hidden field governs that action. Can users not simply change the value to, say DELETE and cause mayhem? I tried it on my local Apache server, and it does in fact trigger the delete route, which could potentially be disastrous.
I also know that I'm not the only one using this practice, as I've seen it on official documentations for various frameworks, so what am I missing?

You can check the method name on the server side with:
<?php
if ($_SERVER["REQUEST_METHOD"] == "GET") {
// collect value of input field
}
else{
// Do nothing
}
?>
Note: Change "GET" as you see fit.
Note2: $_SERVER["REQUEST_METHOD"] is generated by the server. User can not edit it. So, you can check with this variable what kind of request you have (GET, POST, PUT,...).
Hope it helps you!

Related

PHP Get snd Post both set

loaded page from javascript. tested for GET & POST. Only GET set as expected;
window.location.href = "medications_edit_revised.html?recordId="+id ;
Retrieved and used the data from the GET[]
Reloaded page from SUBMIT as shown below.
<form method="post" action="">
<table id="detailsDivTable">
<?php
$editClass->selectTheRecord();
?>
</table>
<fieldset name="Group1">
<legend>Group box</legend>
<input name="saveButton" type="submit" value="Save" />
<input name="deleteButton" type="submit" value="Delete" />
<input name="cancelButton" type="submit" value="Cancel" />
</fieldset>
</form>`
Tested GET[] & SET[]
if (isset($_GET['recordId']) ) {
$recordId = $_GET['recordId'];
require_once "medications_edit_revised.class.php";
$editClass = new editRevisedClass($DBH, $recordId);
}
if(isset($_POST['saveButton'])) {
Both tested TRUE. Is this normal behavior. I expected the GET[] would have been cleared when the form was POSTed
If yes is there a way to clear the GET before sending the SUBMIT
Thanks
When you set the URL like this:
window.location.href = "medications_edit_revised.html?recordId="+id ;
You have set URL params. Then when you do this:
Reloaded page from SUBMIT as shown below.
<form method="post" action="">
Because the action is empty it'll retain the URL parameters, because that's what empty and (eg) $_SERVER['PHP_SELF'] do - they send to the current URL, params and all.
You already know the URL so just set it as needed:
action="medications_edit_revised.html"
You seem to be confusing POST/GET requests and the PHP $_POST and $_GET superglobal variables.
PHP will populate $_GET with data in the query string of the URL the request was made to.
PHP will populate $_POST with data in the request body of a POST request if that data is encoded using a supported encoding.
It doesn't matter if the request was caused by JavaScript, a form submission, or something else.
Is this normal behavior.
Yes
If yes is there a way to clear the GET before sending the SUBMIT
Submit the form to a URL which does not have a query string.
The URL the form is submitted to will be specified by the action attribute.
If you don't have an action attribute, it will be submitted to the URL of the current page. If that URL has a query string, then so will be the URL that the form is submitted to (and thus $_GET will be populated).
If you want to avoid that, then specify the action explicitly.
Can you please past some of your code?
If you use GET to revice your variable, it gets it from the URL: example.com?name=jesper&lastname=kaae
The differences is:
GET requests a representation of the specified resource. Note that GET should not be used for operations that cause side-effects, such as using it for taking actions in web applications. One reason for this is that GET may be used arbitrarily by robots or crawlers, which should not need to consider the side effects that a request should cause.
And
POST submits data to be processed (e.g., from an HTML form) to the identified resource. The data is included in the body of the request. This may result in the creation of a new resource or the updates of existing resources or both.
You can read more about them here

Url and Form security in Laravel 5.1

What's the Problem?
Primary Key is present in Url so the data for other records can be seen easily by easily changing the Url.
Rendered html has hidden field present. Anybody can easily change other records based upon this Hidden Field.
When I edit the page. My Url looks like below.
http://localhost/Category/3
and Below is the rendered Html
<form method="POST" action="http://localhost/UpdateCategory" accept-charset="UTF-8">
<input name="_token" type="hidden" value="AmAXKmqtct6VOFbAVJhKLswEtds4VwHWjgu3w5Q8">
<input name="CategoryID" type="hidden" value="3">
<input required="required" name="Category" type="text">
<input class="btn btn-success" type="submit" value="Update">
</form>
Please suggest some Url and Form security in Laravel 5.1
There are many worksaround which shall by handled by us to avoid such incidents.
Fix 1 :
If you don't want to reach the user's by just changing the url
(i.e., Directly passing the id in url )
You shall filter the requests by
if($_SERVER['HTTP_REFERER']!='')
{
}
else
{
exit;
}
You shall have this in your Middleware or even in your view if you wish
Fix 2 : Never worry about the _token that is visible when you see form source
It is just the token that is generated by laravel app which is to identify whether the request is from authenticated source or not.
If you edit the token and pass the form you will surely get CSRF Token Mismatch Exception
Infact this is one of the great feature of Laravel.
Interesting Point : You can also find something in the headers of the browser ;)
Happy using Laravel ;)

GET method appeared in $_SERVER before submit

<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" onsubmit="return checkValid(this)" method="GET">
<input type="text" name="Symbol">
<input type="submit" name="submit" value="Search">
</form>
<?php
if($_SERVER["REQUEST_METHOD"] == "GET"){
echo "test";
$CSymbol = $_GET["Symbol"];}
?>
when the page was first load and did not press submit button, the php was executed and "test" was print on the screen, also with error:
Notice: Undefined index: Symbol in test.php on line 179
but if i change everything to POST, problem solved. Why is that, what's different btn GET and POST?
GET values are sent in the URL, POST in the HTTP Body. So "GETting" values can alsways be done but may be empty. POST has to be manually created. If you want to use GET in this case however. Guard it:
<?php
if($_SERVER["REQUEST_METHOD"] == "GET" && isset($_GET["Symbol"]){
echo "test";
$CSymbol = $_GET["Symbol"];}
?>
Reference Link
GET and POST are two different types of HTTP requests.
According to WikiPedia:
GET requests a representation of the specified resource. Note that GET should
not be used for operations that cause side-effects, such as using it for taking
actions in web applications. One reason for this is that GET may be used
arbitrarily by robots or crawlers, which should not need to consider the side
effects that a request should cause.
and
POST submits data to be processed (e.g., from an HTML form) to the identified
resource. The data is included in the body of the request. This may result in
the creation of a new resource or the updates of existing resources or both.
So essentially GET is used to retrieve remote data, and POST is used to insert/update remote data.
Authors of services which use the HTTP protocol SHOULD NOT use GET based forms
for the submission of sensitive data, because this will cause this data to be
encoded in the Request-URI. Many existing servers, proxies, and user agents will
log the request URI in some place where it might be visible to third parties.
Servers can use POST-based form submission instead
Finally, an important consideration when using GET for AJAX requests is that some browsers - IE in particular - will cache the results of a GET request. So if you, for example, poll using the same GET request you will always get back the same results, even if the data you are querying is being updated server-side. One way to alleviate this problem is to make the URL unique for each request by appending a timestamp.
For your above code..
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" onsubmit="return checkValid(this)" method="GET">
<input type="text" name="Symbol">
<input type="submit" name="submit" value="Search">
</form>
<?php
if($_SERVER["REQUEST_METHOD"] == "GET" && !empty($_GET['Symbol'])){
echo "test";
$CSymbol = $_GET["Symbol"];}
?>
Every http request that is not a POST counts as a GET request, and so every page that loads up has an empty GET request, php will create a super global $_GET array with every non post request.
Hope this helps you understand what is going on.

How can I only allow request from my form

I have a form on a server and the php to process it, on an other server, this configuration cannot be changed.
I receive a lot of SPAM, and tried to fix it. SESSION couldn't works due to cross-domain, so no token and no captcha, $_SERVER["HTTP_REFERER"] is not reliable. I'm thinking to implement an encrypted key which change once a day, but i think it's limited. Any better idea?
exemple of encrypted key:
$key = "string".date("d");
A lot of bots doesn't run javascript, so you could just inject an arbitrary field into your form:
<form id="douchebag" action="http://yourotherserver.com/process.php" method="post">
<input type="text" name="name" />
.. bunch of other inputs
</form>
Then your js:
var bugSpray = document.createElement('input');
bugSpray.setAttribute('type', 'hidden');
bugSpray.setAttribute('name', 'aa');
bugSpray.value = 'bb';
document.getElementById('douchebag').appendChild(bugSpray);
then in your process.php
if(empty($_POST['aa']) || $_POST['aa'] != 'bb') // bot
You don't need a session to use CAPTCHA.
Many kinds of CAPTCHA exist.
Even the following will probably keep 99% of spambots out:
<form action="...">
<input type="hidden" name="thequestion1" value="23">
<input type="hidden" name="thequestion2" value="-">
<input type="hidden" name="thequestion3" value="5">
How much is 23-5?
<input type="text" name="theanswer">
<input type="submit">
</form>
Most spambots don't look any futher than input fields and submitbuttons.
I bet this kind of CAPTCHA will keep most spam out.
PS: Be sure to safely evaluate the values of thequestion1, thequestion2, thequestion3 on the server.
One technique I've used before is similar to what #SiGanteng suggested but rather than adding a new field you can change the name attributes on exiting ones, to either remove or add a prefix.
<script>
var inputs = document.getElementById('myform').getElementsByTagname('input');
for(i=0; i<inputs.length; i++) {
inputs[i].name = "antispam_" + inputs[i].name;
}
</script>
You could for example add a new resource on the server which generates a key and stores it in a database. When the web page is loaded you request a new key from the server and insert it into a hidden form field.
Then, when a request has been made, you check the value of this field and see that there is a corresponding key in your database. If not, discard the request.
Of course, it is still possible for bots to circumvent it (by also requesting a key), but it will be harder.
Another way you could do it is using a simple check,
take two text inputs and concatenate them,
make an md5 of them and send this through POST.
On the other server check this and Voila.

Using POST method to hide URL parameters

I understand that I am able to use the POST method for URL parameters to display data according to a specific variable, I know how to make use of the GET method - but I am told that the POST method can be used to hide the part of the URL that is like this.
/data.php?parameter=1234
What is the actual difference of the two methods in terms of URL parameters?
Below is some code that fetches data from a database according to the id of a specific link
<?php
//This includes the variables, adjusted within the 'config.php file' and the functions from the 'functions.php' - the config variables are adjusted prior to anything else.
require('configs/config.php');
require('configs/functions.php');
//This is the actual interaction with the database, according to the id.
$query = mysql_query("SELECT * FROM table WHERE id=" .$_GET['id'] . ";") or die("An error has occurred");
//This re-directs to an error page the user preventing them from viewing the page if there are no rows with data equal to the query.
if( mysql_num_rows($query) < 1 )
{
header('Location: 404.php');
exit;
}
//Here each cell in the database is fetched and assigned a variable.
while($row = mysql_fetch_array($query))
{
$id = $row['id'];
$title = $row['title'];
$month = $row['month'];
$day = $row['day'];
$photo = $row['photo'];
$text = $row['text'];
}
?>
On a separate page I generate links to the data.php file according to the ID like so:
<?php echo $content['title']; ?>
Forgetting that there are potential SQL injections that can occur through the above code, how would I go about making use of the POST method in order to hide the URL parameters, or at least not display them like this:
http://example.com/data.php?id=1
In order to use POST, you will need to use a <form> tag, and depending on how you are pulling up these URLs, it could be easier to use javascript to help out. Here's a basic example:
<form method="post" action="data.php">
<input type="hidden" name="parameter" value="1234" />
<input type="submit" value="Go" />
</form>
The Go button would POST the form data, and now in data.php you will be able to retrieve the value from $_POST['parameter']. Note that when using POST, you will probably want to redirect (HTTP 302) back to a page so that when a user hits the back button, the browser doesn't prompt to resubmit the form.
Using javascript, you could set the parameter input to a different value before posting the form.
Use method "POST" for your form. I had the same issue, just adding POST to the form removed the parameters from the URL
<form id="abc" name="abc" action="someaction.php" method="post">
<input type="text" id="username" name="username"/>
<input type="password" id="password" name="password"/>
<input type="submit" id="submit" name="submit" value="submit"/>
</form>
To POST values, a browser would have to use a form with method="post", or javascript simulating a form. Various developer tools (fireug, etc) can convert GET forms to POST forms, but generally, a form is what is required.
In theory GET requests should not have any side effects, and "should" be consistent from request to request. That is, the server should return the same content. In todays world of just about everything being dynamic, this might be of little practical design significance.
Whether you use GET or POST, the parameters will appear in $_REQUEST. The critical difference is that using POST allows the variables NOT to appear in URL history. This decreases the visibility of data such as passwords which you do not want to show up in URL history. To use POST instead of GET, simply produce <form method="POST" ...> in the document.
Even better is to store sensitive values (like user ids) in cookies, so that they don't appear in $_REQUEST at all. Since the contents of cookies are provided in extra HTTP request headers, not in the content, they are generally not stored as part of the history.
In order to use POST instead of GET, you would need to use an HTML form tag in your html, like so:
<form method="POST" action="/data.php">
<input type="hidden" name="parameter" value="1234" />
<button type="submit">Submit</button>
</form>
When submitted, your URL will just be /data.php and parameter=1234 will be in your (hidden) post buffer.
Make sense?
To do a POST, you have to use a form, or some javascript/ajax trickery. An <a> will only ever cause a GET request.
Note that POST requests can still have query parameters in the URL. It's not "normal" to have them, but they are allowed. The main difference being that with a GET request (ignoring cookies), the URL is the ONLY way to send parameters/data to the server. With POST, you can use both the URL, and the body of the POST request, which is where POSTed form data is normally placed.

Categories