Wondering how I would go around adding a reviews section to a HTML website. I am relatively new to dynamic sites, if this counts as that, so don’t really know where to start. Any ideas?
I have a small bit of experience with PHP, but no knowledge of securing forms and how to avoid injections etc.
How would I go around adding a place for a person to leave a name, review, and stars on a site, and then it to publish them?
I have looked at:
Google My Business integration, but apparently they have deprecated the ability to add it to sites.
PHP, but I have little experience with this, and I would be worried about securing it. We wouldn’t be collecting personal info, maybe only location, but obviously it needs to be secure.
JavaScript, something like this: https://codepen.io/jamesbarnett/pen/vlpkh but more advanced. Not sure how to store the data however, I guess I would use an SQL table?
Well, you definitely would need some sort of a backend with some kind of a database. Since you’re asking, I’m guessing that that means that you haven’t done that much backend.
You’d need a backend language. PHP is an option. As are Node, Java, Ruby, Go, etc. There are ways to secure data in any of those languages.
I’d suggest Python with Flask for backend, it’s pretty simple and seems enough for your needs.
For security there are libraries (or maybe it’s even already integrated, i don’t remember) which will filter user input for you, to prevent injections.
There are some good lectures from harvard’s CS50 course on youtube, you can find them both on the freecodecamp channel or the cs50 channel. Lecture 5 is html-css-http, lecture 6 is python, lecture 7 Flask, lecture 8 SQL databases
Firebase, now owned by Google, is pretty straightforward. It is both a data store and an API, built-in. You use their library in your HTML (by including it via a script tag), and then simply interact with the datastore itself. It stores JSON directly, so you would be able to use it directly with javascript objects – so setting up a “review” object would be pretty feasible. Personally, I’d suggest looking through the documentation on google’s own site, it’s pretty user-friendly
<?php
//Connecting to sql db.
$connect = mysqli_connect("server","user","pass","db");
//Sending form data to sql db.
mysqli_query($connect,"INSERT INTO reviewlist (name, location, review)
VALUES ('$_POST[name]', '$_POST[location]', '$_POST[contents]')");
This is my table:
However, it isn’t adding anything to it. Anyone know why? I fill in the table, hit submit and it just shows me the blank .php page, and nothing has been added to the table.
It is connected correctly as I can make changes to the table etc. I am using DataGrip for the table management, and PHPStorm for the PHP side of things.
What if I my name is “O’Sullivan”? Or if I type '); DELETE FROM reviewlist; into the name field? I strongly suggest rather than creating SQL by hand and opening up apps to what’s known as “SQL Injection Attacks”, that you use something like PDO and forget that the mysqli_* functions even exist. It may take a bit longer to learn, but as far as I know, it’s the only proper way to access a SQL database in PHP.
Other tutorials will suggest you “sanitize” data first, but if you use parameterized queries such as what PDO gives you, you’ll never have to worry about doing that.
@chuckadams I have looked into this but can’t figure out. Also, for some reason PHPStorm is highlighting the $pdo variable as non existent.
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Dotenv\Dotenv;
$dotenv = new Dotenv();
$dotenv->load(__DIR__.'/.env');
// Constants. USE .ENV
$servername = getenv('SERVER');
$username = getenv('USER');
$password = getenv('PASS');
$dbname = getenv('DBNAME');
// Get values from form
$name=$_POST['name']; // set name from form to the variable 'name'
$location=$_POST['location']; // set location from form to the variable 'location'
$email=$_POST['email']; // set the email from the form to the variable form
$rating=$_POST['rating'];
$review=$_POST['review']; // review from form to variable form
$userinfo = date('Y-m-d H:i:s') . " - $_SERVER[REMOTE_ADDR]"; // collect info about the user
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "INSERT INTO reviewlist (name, location, review, userinfo, email)
VALUES('$name', '$location', '$review', '$userinfo', '$email')";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
That is what I have so far, and I’ve tried using pdo but really can’t figure it out. I know about SQL injection, but have no idea what to stop it.
It looks like you can get away with using mysqli after all, as long as you stick to the prepared statement API and not the all-in-one ->query method . What you’re doing wrong is right here:
$sql = "INSERT INTO reviewlist (name, location, review, userinfo, email)
VALUES('$name', '$location', '$review', '$userinfo', '$email')";
if ($conn->query($sql) === TRUE) {
What you need to be doing is using parameters, not interpolating strings into the query. It should look more like:
That ‘sssss’ parameter is providing the types of each argument (an API pretty much unique to PHP), which is explained in the first section at that w3schools link.
Not particularly, other than running Penetration Testing on your app, which will usually include some kind of attempt at SQL injection if your app is connected to a DB. You could try a SQL injection on the old system then see if it works on the new one, but you’ll probably need to tweak the string somewhat to make it work. In other words, it pretty much has to be a hand-crafted attack, there’s no out of the box script to exploit sql injections automatically.
Incidentally this applies to more than SQL: if you run any kind of command, such as with system() or exec() and it uses any kind of user input, then the same idea applies. Imagine system($_POST['command']) and all the mischief that could go with it… The moral of the story is: never trust input you get from the outside.
One can’t say the form is 100% secure, but it does at least lack SQL injection capability. The other main potential security hole I can think of would be Cross Site Request Forgery, aka CSRF, which is a little more involved to solve (and usually solved for you by a framework like Laravel). Basically, it’s nearly impossible to prove something is 100% secure, only that you’ve closed the security holes you know about. Welcome to the scary world of information security
Cross Site Scripting, or XSS, is only a problem if you’re taking input from the outside and interpolating it directly into a page. You prevent this problem by escaping the output. For example (and I’m making up some functions here) instead of:
<?php
$name = load_user_name_from_db_somehow();
?>
User name: <?= $name ?>
You’d want something like this:
<?php
$name = load_user_name_from_db_somehow();
?>
User name: <?= htmlentities($name) ?>
And htmlentities will escape all html special characters (like < and >) and cause it to be printed as the string that was input, not as html to be interpreted. Do note you should only render entities with escaping, not store them in the db escaped (as I’ve seen many do). The video will explain it in a lot more detail, but the basic ideas are:
Never trust user input. Use something other than “sanitizing” if at all possible, such as parameterized queries or the array form of system().
Always escape output going into an HTML page if you don’t want it interpreted as arbitrary HTML. If you do want it interpreted as HTML, take heed of item #1 and don’t trust arbitrary input from the outside world. Most modern template systems (wordpress being a glaring exception) will escape things for you by default, which is all the more reason to use them rather than raw PHP.