I have Linux operating system with Doc root(/var/www/html)in which I have an index.html file which has a form for asking user's name and then it puts that details into MYSQL Database(using php script called inside the index.html).
When I open the index.html in browser it presents me with the form to enter the user details and after clicking on submit, the php script is called(browser URL changes to /localhost/insert.php)and it inserts the data into database which is fine.
The issue is that the backend php script is directly available using /localhost/insert.php, so if I(or someone) bypasses the index.html and directly opens the /localhost/insert.php, it runs directly putting some vague data into MYSQL Database.
Any fixes to avoid running the backend(server side php script) directly from the browser.It should ONLY be allowed to run when called from the index.html.
It is better to check the request method than check if the $_POST variable is set, as there will be cases that a form will be correctly sent but the $_POST won't be sent.
You can do this by the following:
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
header('Location: index.html');
die();
}
Then you can do sanitisation to check the fields have been entered, then finally sanitise data. If you are inserting the data into a database be sure to use prepared statements (or at the very least sanitise your data inputs using a real escape string function). Also make sure you prevent XSS injections by using htmlspecialchars.
You need to bypass processing in insert.php by placing a check and executing only if the request is coming from a POST
if(!isset($_POST['formValue'])){
exit;
}
?>
formValue is the key being "Post" from your index.html
If you are handling things properly, using POST method, then things should work out good. It doesn't matter if the user is trying to access your php script directly. It all depends on your request method. Say for example your form tag goes like this.
<form action = "index.html" method = "post">
And your submit button goes like this,
<input type = "submit" id ="submit">
Then in your index.html php script their should be something like this.
if(isset($_POST['submit'])){
// redirect data to another php script. And in this script, data should be cleaned to prevent Sql injections !!
}
else
{echo "invalid request";}
Related
I have a basic file. The user can only view the file after a successfull form submission.
Now I know I have a variety of options I could use including placing it in a dir and modifying my .htaccess and then use a parameter which I pass through a routing script to let the user view the file as pointed out by numerous answers to somewhat similar questions. (which would probably be best option)
However Im just curious about something. "How Secure" would the following be.
Both files reside in a directory called xyz
Directory public_html/xyz
Form.php
<form method ="post" action="displayInfo.php" />
displayInfo.php
Now what I would like to know is IF i set the following code at the start of displayInfo.php would it stop with unauthorized access (i.e. prevent user from viewing the file IF he / she did not successfully submit the form)
if($_SERVER['REQUEST_METHOD'] !== 'POST'){
die("first submit the form")
}
No it wouldn't. I could defeat your security precaution with a simple cURL command:
curl -X POST https://example.com/displayInfo.php
The check for a POST request will pass, because it indeed a post request. However, it has absolutely none of the data you wanted.
Having some trouble. New to web development. I'm trying to make a simple application that receives data from a Particle Photon board - using a webhook, everytime a particular event occurs on the board's end, a JSON is sent via POST. I'm running an Apache webserver. I want to process the POST request with PHP, and then have that PHP update what the user sees somehow. Right now I have only index.php, with the following:
<html>
<head>
</head>
<body>
<div>
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
$data = json_decode(file_get_contents("php://input"));
// do something with $data
}
?>
</div>
</body>
</html>
I'm not worried about input validation, I just want the rudimentary functionality. My thought process is that the webhook sends this POST request (it sends it to index.php, and appears to be working), and then the index.php will be triggered and then display the POST request information. I can't seem to get the index.php to receive the POST request. I've tried var_dump, echo, but it all comes back either blank or NULL. Is there something inherently flawed with my understanding of this setup?
This is the JSON that is being sent:
The only file I have on the server is index.php.
From comments:
First of all, prepare a process file, eg.: process.php, in this file you need only php code that check for a post, process it and store relevant data in your database.
<?php
if(isset($_POST)){
// Process post, store relevant data on database
}
Then, with data properly stored on database, you can show html pages to your users, retrieving data from database and showing to them accordingly.
When a user submits any form, a $_GET['variable_name'] is sent by the webpage and will give a URL like the following: www.mywebsite.com/index.php?variable_name_here='yes'.
However people can just write the URL www.mywebsite.com/index.php?variable_name='yes' into the address bar of the website and gain access to this part of the script, without actually submitting the form!
This is a problem! It's breaking specific parts of the script linked to that form submission! This is because the part of the script relating to the $_GET['variable_name'] can't get the variables that should be sent by the form as it is never submitted!
How do I stop people getting to specific parts of a script when they manipulate the URL by sending them back to www.mywebsite.com/index.php?
P.S. : This is for user submitted data through a form which is then processed (no SQL or any alike software involved)
If you are worrying about people getting in to your site without logging in or not having correct params, you should first check to see if the correct $_GET variables exist using isset(). If all paramaters you are expecting exist allow them to pass, otherwise use header('Location: /index.php'); to force a redirect.
To redirect from www.mywebsite.com/index.php?variable_name='yes' to www.mywebsite.com/index.php you would need to include the following code below before you open a HTML header! This solution will work for any $_GET variables within your whole website if you place it within an includes("filename_here"), no need to change the code.
//if there are any $_GET variable(s) set (doesn't matter what the name of the variables are)
if (! empty($_GET))
{
//if there is no record of the previous page viewed on the server
if(! isset($_SERVER['HTTP_REFERER']))
{
//get requested URL by the user
$redir = $_SERVER['PHP_SELF'];
//split parts of the URL by the ?
$redir = explode('?', $redir);
//redirect to the URL before the first ? (this removes all $_GET variables)
header("Location: $redir[0]");
}
}
I need to create a landing page that's dynamic to information picked up by a form that executes a php script.
Person submits form > PHP Code sends me an email > PHP code that displays information
I have a hidden input in every form that identifies what form it is, and depending on what the value or "identification" of the form a specific code on the php is executed using a switch and I thought that maybe I could use that same identifier to execute another switch on the page after that. My problem is I don't know how to carry that value or identifier from one php to the other.
So just to reiterate, I want to know how to move or copy variables from one php to another, after mail() is executed.
Im using $request to get those variables
Keep this source form identifier and render it into your new form identifier field. It will deliver the response form with same identifier
after you do your Mail() thing, call a function that runs whatever you want.
If the classes or functions you want to run are not available you must include or require them.
I'm not 100% sure about what you are asking for, but due the comments I'll make a try to answer it.
When I create forms I usually have one page with the actual form and another page that handles the data. When the data is handled I simply redirect the user back to the form and then give them feedback.
The reasons I'm using two separate pages are the following:
I like to keep the code for the form and the handler separated.
Users can't accidently submit the form again by refreshing the page.
The same handler can be used by eventual Ajax and uphold progressive enhancement.
An extremely simplified example below.
form.php:
<?php
//Start session
session_start();
//If the session variable has been set
if($_SESSION['remember'])
{
## DISPLAY FEEDBACK ##
}
else
{
## DISPLAY FORM ##
}
//Delete the session variable
unset($_SESSION['remember']);
?>
req.form.php
<?php
//Start session
session_start();
//If a form has been submited
if(isset($_POST['submit']))
{
## HANDLE THE DATA ##
//Set a session variable
$_SESSION['remember'] = true;
//Redirect the user back to the form
header('Location: /form.php');
exit;
}
?>
I came up with a technique to prevent duplicate form submission by going back/forward or refreshing the page. And I thought about duscussing it here, I already tested a sample not in production environment, what is flaws that you can identify?
Please note that I am well aware of using Form Tokens, which will defend you against CSRF attacks, and wasn't added in the steps below.
-Generate Form ID for each form, and use it as hidden field in the form:
$formid = microtime(true)*10000;
-On form submit:
Validate from data
Calculate the hash of form fields data
$allvals = '';
foreach($_POST as $k=>$v){
$allvals .= $v;
}
$formHash = sha1($allvals);
Validate form hash by comparing with previously saved hashes. the session value is binded to each form by $formid variable.
$allowAction = true;
if(isset($_SESSION['formHash'][$_POST['formid']]) && ($_SESSION['formHash'][$_POST['formid']] == $formHash)){
$allowAction = false;
}
if form hash wasn't found, it means this is the first time form submitted or the form data is changed.
If data saved ( to database, for example), save form hash to session:
$_SESSION['formHash'][$_POST['formid']] = $formHash;
Full version of the code:
http://thebusy.me/2011/01/06/preventing-duplicate-form-submissions/
A simpler way to achieve what you want is to use redirect on submit. After you process a POST request you redirect, possibly even to the same page. This is a common pattern called "Redirect after POST" or POST/Redirect/GET.
For example:
<?php
if($_POST) {
// do something
// now redirect
header("Location: " . $_SERVER["REQUEST_URI"]);
exit;
}
?>
<html> ...
<form method="post" action=""> ... </form>
By setting the action to "" then it will submit to itself, at which point the if($_POST) code block will validate to true and process the form, then redirect back to itself.
Of course you probably want to redirect to a different page that shows a "your form has been submitted" response or put the form on a different page and have the HTML of this page be the response.
The benefit of this method is that when you hit the back button it does a GET request so the form is not re-submitted.
On Firefox, it will actually take the submission to itself out of the browser history so when users browse across the web and then hit back, instead of seeing the "thank you" page they see the form page.
It looks like you are getting overly complicated with this. My favorite way, because it also prevents some session jacking hacks at the same time, is described here:
http://www.spotlesswebdesign.com/blog.php?id=11
It's simple and easy to impliment on any form. It uses a randomly generated page instance id to verify that the form submission received is identical to the last page served to that particular user.
Both solutions above are good but a bit short.
how about stopping further insertions in the next few minutes from the same user with perhaps minor changes in data?
this can be done by putting an md5 hash in a cookie on the users machine and storing a copy in the database - this way any further attempt from the same machine over a specified time can be ignored and stopped from being inserted into the database.
perhaps someone can comment on the validity and effectiveness of my suggestion or am i barking up the wrong tree ???