1

My form saves user inputs (inputs+textarea) into a flat file database. I found lots of examples Googleing on how to create a flat file database, but no one is properly covering some good basics on how to properly secure form from XSS and other malicious attacks.

I know the best way is to have (Ex:) an SQL database... but that's not the case.

So far I know (this could be wrong! correct me if it is) :

  • Preferably use .php files to store data (inside <?php ...data... ?>) instead of .txt files
  • If possible drop an .htaccess with a deny from all inside the database folder
  • Validate via php your inputs and textarea before submission. (But how to do that exactly??? I mean... what's the best way?)
  • validate properly your fields (php) (How exactly... some practices are only for sql databases, not for ffdb...)
  • I'm looking something like mysql_real_escape_string but good enough for ffdb

What are your thoughts? I appreciate your help

Ginnani
  • 325
  • 1
  • 5
  • 19
  • The first one sounds peculiar. Where did you find that recommendation? – mario Nov 25 '11 at 12:08
  • 1
    Do you have any reason to want a flat-file database? If it's just because you can't have MySQL (or postgreSQL or ...), have you taken a loot at using [SQLite](http://php.net/sqlite)? It stores the data in files you can save in any folder you want, and it's enabled by default in PHP5 – Carlos Campderrós Nov 25 '11 at 12:47
  • Thanks @Carlos ... actually I heard a lot of SQLite but never had time to explore it... I was just interested on: having a small piece of code Ex: chat room or Leave a comment form to create a small FFDB... expecially in the case there was no access to the SQL db. In this case not many easy info are available 'out there' ... – Ginnani Nov 25 '11 at 19:12

2 Answers2

2

Dunno where did you get it, but by using

  • .php files to store data (inside ) instead of .txt files

you can be definitely sure that it will ALLOW anyone whatever attack they wish,

  • drop an .htaccess with a deny from all inside the database folder

makes absolutely no sense,

So, it seems the only issue is

  • how to properly secure form from XSS

and it is solved by using htmlspecialchars()

here is an example of such a script I wrote long time ago in a galaxy far, far away...
Feel free to ask if something looks unclear.

<?php
if ($_SERVER['REQUEST_METHOD']=='POST') { 
  // iterating over POST data
  foreach($_POST as $key => $value) { 
    //first we are doing non-destructive modifications
    //in case we will need to show the data back in the form on error
    $value = trim($value); 
    if (get_magic_quotes_gpc()) $value = stripslashes($value); 
    $value = htmlspecialchars($value,ENT_QUOTES); 
    $_POST[$key] = $value; 
    //here go "destructive" modifications, specific to the storage format
    $value = str_replace("\r","",$value);
    $value = str_replace("\n","<br>",$value);
    $value = str_replace("|","&brvbar;",$value);
    $msg[$key] = $value;
  } 
  //various validations
  $err=''; 
  if (!$msg['name']) $err.="You forgot to introduce yourself<br>"; 
  if (!$msg['notes']) $err.="You forgot to leave a comment!<br>"; 
  //and so on
  //...
  // if no errors - writing to the file
  if (!$err) { 
    $s  = $msg['name']."|".$msg['email']."|".$msg['notes']."|".time()."\n"; 
    $fp = fopen("gbook.txt","a"); 
    fwrite($fp,$s); 
    fclose($fp); 
    //and then redirect
    Header("Location: ".$_SERVER['PHP_SELF']); 
    exit; 
  } 
  //otherwise - show the filled form
} else { 
  //if it was not a POST request
  //we have to fill variables used in form
  $_POST['name'] = $_POST['email'] = $_POST['notes'] =''; 
} 
?> 
<html> 
<head></head> 
<body> 
<? if ($err): ?><font color=red><b><?=$err?></b></font><? endif ?> 
<form method="POST">
Name: <input type="text" name="name" value="<?=$_POST['name']?>"><br> 
Email: <input type="text" name="email" value="<?=$_POST['email']?>"><br> 
Notes: <textarea rows="3" cols="30" name="notes"><?=$_POST['notes']?></textarea><br> 
<input type="submit" name="submit"> 
</form> 
</body> 
</html>

it will produce a so-called pipe-delimited format like this

name1|email1|comment
name2|email2|comment

you can read it using file()+explode()

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
1

If your storing content in a text file then you don't need to worry about escaping the string.

You could filter it for malicious HTML, but it depends on what your doing with the contents.

Make sure the file is in a folder outside of the public directory or is protected with the deny from all htaccess trick, and ensure that you use file locking to prevent it being overwritten at the same time.

Also if your looking for a good flat file database check out Flintstone, its a key/value database store I wrote, might be useful for you.

fire
  • 21,383
  • 17
  • 79
  • 114