0

A colleague and I found a PHP book at work and since we currently got the time we started learning by building a small webapp we aim to use in our daily work some day. At the base our app is simple CRUD-style apps where data is called from a database, put into HTML-code, and echoed to the client who then can edit the data and send it back to save it.

We took the approach you are going to see in the following code-snippets because we ran into problems writing JavaScript-accessible HTML-code with PHP. Often times JavaScript had difficulties accessing values we directly put into the HTML-code with a PHP-variable. Other times we were not able to successfully echo the code we needed. For example:

echo '<input type="text" onfocusout="send_to_server("string", "another_string")">';

..would "break" the resulting HTML-code at all "

In order to enable the client to post/save data to the database/back-end we use an asynchronous JavaScript function that calls a php-script which saves the data in a mariadb database. This is our function that passes updated data:

async function send_to_server(id, value, column, table){
    const querypath = "/php/update_database.php?row="+id+"&value="+value+"&column="+column+"&table="+table;

    const fetchRespone = await fetch(querypath);
    if(fetchRespone.status != 200){
        return console.log('Fetch error, status code: ' + fetchRespone.status);
    }
}

This is our Script that saves the passed data in the mariadb-table. Update_database.php:

$row = $_GET["row"];
$value = $_GET["value"];
$column = $_GET["column"];
$table = $_GET["table"];


$dbhost = 'localhost';
$dbuser = '#######';
$dbpass = '#######';
$dbname = '#######';

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
$sql_stmt = mysqli_prepare($conn, "UPDATE $table SET $column=? WHERE id=$row");    
mysqli_stmt_bind_param($sql_stmt, “s”, $value);
mysqli_stmt_execute($sql_stmt);
mysqli_stmt_close($sql_stmt);
mysqli_close($conn);

(we decided for a general purpose update-script)

In order to send the data with JavaScript to the back-end we are currently writing all the data that is supposed to be saved in the classname and data-attributes that are then accessed by the JavaScript function. The to be echoed HTML-Code is built by calling PHP functions like this one:

function create_input_text($id, $value, $column, $table){
    return '<input type="text" class="'.$column.'" id="id_input_'.$column.'_'.$id.'" name="input_'.$column.'" value="'.$value.'" data-row="'.$id.'" data-relation="'.$table.'" onfocusout="send_to_server(this.dataset.row, this.value, this.className, this.dataset.relation);">';   
}

($id is the id in the table, $column refers to the column of the table. This way we use one script to save data at the exact location in the relation)

As you can see we are saving, displaying, and sending highly sensitive data visibly. Since we are currently only testing things with dummy data there is no problem. But using this – even in an internal network – is undoubtedly very very risky. We would be grateful if you can give us alternative ideas for our data-attribute-centric-approach on passing data / our way of writing JavaScript-code with PHP.

There is probably a framework that would solve this easily but we are currently trying to keep it as vanilla as possible since we are just starting out.

alxl86
  • 9
  • 4
  • I don't really understand what you mean by _JavaScript accessible HTML_ anything in the DOM is accessible. If you do mean the values of PHP variables, you have to pass these values somehow, keep in mind that the PHP is running on one machine, the server, while the JavaScript is running on the client. You can do that a lot of different ways, echoing the values as data attributes, requesting them as JSON... look into that. You should send the `update` request as a `PATCH` request, and the data as body parameters, not query parameters, and use HTTPS. – Raul Sauco Jun 15 '21 at 09:14
  • **Warning:** You are wide open to [SQL Injections](https://php.net/manual/en/security.database.sql-injection.php) and should use parameterized **prepared statements** instead of manually building your queries. They are provided by [PDO](https://php.net/manual/pdo.prepared-statements.php) or by [MySQLi](https://php.net/manual/mysqli.quickstart.prepared-statements.php). Never trust any kind of input! Even when your queries are executed only by trusted users, [you are still in risk of corrupting your data](http://bobby-tables.com/). [Escaping is not enough!](https://stackoverflow.com/q/5741187) – Dharman Jun 15 '21 at 09:23
  • 1
    If you echo the data as html without checking, keep in mind that you could easily get a XSS vulnerability. For instance if you echo the username `$name` which equals to `">` – A_A Jun 15 '21 at 09:24
  • If you are only starting to learn PHP then you should learn PDO instead of mysqli. PDO is much easier and more suitable for beginners. Start here https://phpdelusions.net/pdo & https://websitebeaver.com/php-pdo-prepared-statements-to-prevent-sql-injection – Dharman Jun 15 '21 at 09:24
  • Thank you all for the comments! Raul_Sauco: i will edit my question to clarify. Dharman: thanks for shining the light on the issue and all the links you provided. The bobby tables link is hilarious :D. A_A: thank you for bringing that to our attention! – alxl86 Jun 15 '21 at 09:51

0 Answers0