-1

Probably I am missing some point here. I always assumed, that sequence

mysqli -> real_escape_string($var);
insert into database
.....
select from database
$var = stripslashes

is the correct one for storing and retrieving string inputs from users. I just found, that this approach work fine except one case - it strips all slashes input by a user. It only works, when I use

$var = str_replace("\\","\\\\",$var);

before real_escape_string. Is this exactly correct approach assuming I cannot use prepared statements for some reason?

user3523426
  • 836
  • 3
  • 11
  • 26
  • 6
    Use prepared statements and forget about escaping strings. – Jay Blanchard Feb 12 '18 at 16:29
  • 3
    Don't, don't, just **do not** use `stripslashes`. That function is intended to deal with the damage that "magic quotes" introduces, but that feature has been removed from PHP for the betterment of all. – tadman Feb 12 '18 at 16:30
  • 1
    *"Is this exactly correct approach assuming I cannot use prepared statements for some reason?"* - why not? – Funk Forty Niner Feb 12 '18 at 16:30
  • `real_escape_string()` does *not* remove slashes. It escapes them. Something else must be doing that. – Barmar Feb 12 '18 at 16:31
  • 2
    Possible duplicate of [How can I prevent SQL injection in PHP?](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) – Stephen R Feb 12 '18 at 16:31

1 Answers1

0

The answer here is to use prepared statements with placeholder values in an extremely disciplined manner. Any and all user data, be it directly from form inputs, query parameters, session data, or other database records, must be treated as possibly hostile and, as such, needs escaping. The most reliable way to escape that when dealing with the database is to use placeholder values, maintaining strict separation between query and data.

For example:

INSERT INTO users (name, shoes) VALUES (?, ?)

Where those ? values represent arbitrary user data. With bind_param you can bind against these:

$stmt->bind_param('si', $_POST['name'], $_POST['shoes']);

Where that properly encodes that as a string and integer, respectively.

When displaying content you'll need to be aware that it's also important to escape that for the context you're rendering it in, be that HTML, JavaScript/JSON, or a URI, each of which have different requirements and formats.

Always store your data in the most neutral format. Never pre-escape HTML or strip characters arbitrarily. Non-destructive cleaning, such as trimming leading and trailing spaces, is fine, but any aggressive formatting not related to normalization to an ideal form should be discouraged.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • `$_POST['shoes']` that should probably read as `$_POST['shoe_size']` - The name implies wearing a pair of Gucci shoes ;-) – Funk Forty Niner Feb 12 '18 at 16:35
  • @FunkFortyNiner It's just a count of how many shoes you have. Shoe sizes aren't purely numerical. – tadman Feb 12 '18 at 16:35
  • Thanks for the detailed info, but the question clearly stated: "I cannot use prepared statements" - there is solid reason for it. – user3523426 Feb 12 '18 at 16:49
  • @FunkFortyNiner People are unusually cranky in this last year and I don't know why. – tadman Feb 12 '18 at 16:49
  • @user3523426 Unless you can specifically state why, then I cannot comment on what you should do. This stuff is deadly serious. There is no safe way besides prepared statements, so you'll have to explain in more detail what obstacles you have. – tadman Feb 12 '18 at 16:50
  • Is it important "why"? The question was "how without prepared statement" .... OK, why - because I am forced by my customer to use database library created years ago, which accepts string queries only. – user3523426 Feb 12 '18 at 16:53
  • The answer is, unfortunately, to fix their library. There is no magic bullet here, and no amount of `stripslashes` or manual escaping can help you. This is a problem that must be addressed on a fundamental level. Their code is vulnerable, and the cost of those vulnerabilities might be severe. I'd advise the client that unless that library is patched to work with prepared statements and placeholder values you can make absolutely no guarantees about the security or integrity of their application. – tadman Feb 12 '18 at 16:55
  • If they understand the risks and elect to proceed without fixing these problems then I'd be sure to get this acknowledgement in writing. Your professional reputation is at stake here. The person who touched the code last is often the first to blame regardless of the nature of the problem. Attackers don't care that your client can't or won't deal. Attackers will gleefully exploit their inadequate code. This is just the harsh reality we have to live with. – tadman Feb 12 '18 at 16:56