1

Lets say you get a string from user input and store in into a database. Later you retrieve that string and populate a new form input's value with that string. Is there any XSS danger without any sanitization, if so, what is the best way with minimal disruption to the original input.

$str = $_POST['string'];
// INSERT $str INTO MYSQL

// LATER
$string = // database fetched string
<input type="text" name="data" value="<?= $string ?>" /> // << XSS vulnerable?
  • This is a relatively common thing for web developers, most will either use built in data validation or write their own using Javascript or have server side validation but JS is prefered in my opinion. Good that you are thinking about all of this as well, – Bryan Bergo Jan 28 '21 at 15:16
  • 2
    @BryanBergo You should definitely not write your own validation/escaping/encoding function. When it comes to security you should absolutely leverage battle-tested tools. And you should definitely not rely on client-side validation only. People can disable JS yet still submit your form or completely bypass your client and use tools like `curl` to post directly to your server-side script. – customcommander Jan 28 '21 at 15:25
  • @customcommander good point about curl, although can't you assign certian http headers to only allow requests from authorized domains, which would protect you from curl-based attacks? – Bryan Bergo Jan 28 '21 at 16:45
  • 1
    @BryanBergo Perhaps but I'd imagine these could be faked too. My point is that security isn't a server vs client responsibility: you should do client side validation for convenience (saves you a round trip to the server) and _maybe_ as a first line security gate _but_ it cannot be the end of the story. Data must be validated _again_ on the server. Similarly what comes back from your server doesn't mean it can be trusted; your client must not assume safety by default. – customcommander Jan 28 '21 at 19:20

1 Answers1

2

What if the $string is:

foo"/><script type="javascript">...something malicious...</script>

That's an XSS vulnerability.

Fix it by the usual method of protecting against XSS: htmlspecialchars()

See also How to prevent XSS with HTML/PHP?

Bill Karwin
  • 538,548
  • 86
  • 673
  • 828
  • So should I htmlspecialchars_decode() upon getting the inputs back before updating mysql data. Many sites I have looked at recommend storing raw user input. I am having problems with email not displaying the encoded characters correctly, they show the code rather than the represented character. – Daniel Krenn Jan 29 '21 at 16:57
  • Don't encode html special characters unless you're outputting to html. If the email is a rich html-formatted email, do encode those characters. If the email is plain text, don't do that. Some emails are multipart, so they include both plain text and html-formatted. So you would encode htmlspecialchars in one part of the email but not the plain part. – Bill Karwin Jan 29 '21 at 19:00
  • And do store raw user input in the database. Don't store html-encoded entities, just the original text. Do the encoding as the last step when you display it. The reason is that this gives you flexibility -- sometimes the text from the database will be presented in html output, sometimes it'll be plain. – Bill Karwin Jan 29 '21 at 19:01
  • So if I pre-populate an input value that has been encoded I should decode it before putting an edit back into the database then, correct? – Daniel Krenn Jan 29 '21 at 19:45
  • Why would an input be encoded? No, just don't encode inputs. Take inputs as plain text, store them in the database as plain text, fetch them from the database as plain text. ONLY if that content is going to be presented in html output, THEN encode it as you output it. – Bill Karwin Jan 29 '21 at 19:57
  • Ok I just realized that if you use htmlspecialchars() to encode an input value to something like [ Mike's ], it will came back as a POST variable unencoded as Mike's. I figured it would come back still encoded. That is cool. Thanks for your help! – Daniel Krenn Jan 30 '21 at 00:32