Do I need to completely filter all input data
You must not trust any data received from outside. For example, $ _GET, $ _POST (by default, the two are $ _REQUEST, according to the php.ini settings, request_order and variables_order can also include cookies, $ _SERVER and environment variables), $ _COOKIE, $ _FILES, data downloaded from third-party systems ( for example, by API). The general point is that you should not look for an abstract filter from dangerous data, but understand what data you expect to find in this place and what happens next with this data. Output to CSV, HTML, or writing to a DBMS - each requires its own special processing.
The better to use filter_var (), filter_input (), etc., or use regular expressions.
Anything that will allow you to verify the correctness of the data. It is necessary to begin with the white list. Often you know in advance that, for example, $ _GET ['index'] you can only have foo or only bar . Check these two valid values.
For example, for an email user there is a regular regular filter_var , hidden in filter_var . This is a good starting point and will usually work well. “Usually” - because email is a really funny thing. If you read the relevant RFC, it turns out that it is easier to check for the content of the @ symbol and send the same letter than to understand all the variety of acceptable options. Almost everything is permissible there.
For example, login, you may wish to restrict input to only Latin letters and some special characters. This is most easily done by a regular program.
The broadest interpretation, usually for free text input. For example, here for this very message. As a rule, any UTF8 characters are allowed.
By the way, once I started talking about this: please do not validate the password in any way, except perhaps for the minimum length. And only if that is definitely required by the subject area, then by minimal complexity. But in any case, do not limit the maximum. You still have to hash it, and not to store, let the user enter what he likes and the length that he likes.
What method of authorization on the site can be considered safe?
Depending on security requirements. EDS is quite difficult to get around (figuratively, banking). It is difficult to get around if authorization is allowed only from one specific IP of one specific VPN (corporate data). For a site that is not as sensitive to security - HTTPS (if the server side is configured correctly! Over the past years, it has become rather easy to configure HTTPS incorrectly) to adequately cover MitM and encrypt the data.
You can hash the initial password on the client and transfer the hash to the server so that the initial password is not transmitted over the network at all.
Without HTTPS? Make HTTPS, the times of expensive certificates are already in the past.
Using PDO, can I not be afraid to bind variables right away
There is no SQL injection in this case. And immediately an important caveat: only if you have the connection encoding correctly configured or the emulation of the prepared expressions is disabled. https://stackoverflow.com/questions/134099/are-pdo-prepared-statements-sufficient-to-prevent-sql-injection
But you still have to check logical errors. For example, do you think using (int) $ _POST ['amount'] is safe as: amount?
UPDATE users SET balance = balance - :amount WHERE id=:user
(example, in reality there will be a double accounting entry in such a place, which check is additionally validated elementarily at the record level in subd (especially if the same mysql could check at all), but as one DBA says, people understand money faster).
And if you pass -100? Get a charge of money instead of writing off?
If I have an HTML (wysiwyg) editor, then I need to use functions before saving to the database
Very interesting question and behavior depends on the degree of trust. Do you trust the one who uses this editor? Those. should the output be real HTML and need to be output as HTML? This is a common thing for admin some CMS. Then you should not validate this field at all. htmlspecialchars($var, ENT_QUOTES, 'UTF-8') should be called for this text when inserted into the textarea, otherwise a random text will break everything.
If you do not trust, but there will be HTML - then you are obliged to thoroughly parse into tokens and check all transferred HTML on the white list. I will not tell you about specific tools, I only know that there are such. The problem is that, for example, you want to give the opportunity to insert <img src> , and you will slip some <img src='...' onload="alert(document.cookie)"> and that's it. Instead of an innocuous alert, there may be something more interesting. And htmlspecialchars is impossible, otherwise the picture will not be either.
If HTML should not be in general, then htmlspecialchars. It is possible to apply before writing to the database, but logically it is more appropriate to apply directly when outputting to HTML. But not strip_tags. Why are you deleting what the user entered? You must keep it right and show it right, not delete it.
If there is one, then the password is checked using the password_hash function ($ password, PASSWORD_DEFAULT);
Is this a bug in the question? password_hash does not check anything. Checks password_verify.
Why are you saying something, oh, how far CSPRNG is not writing, apparently, in a cookie, and how you plan to use it later - I also do not imagine.
CSPRNG is a cryptographically secure pseudo-random number generator.
For session session authorization and use. Let me remind you only about one obvious pitfall, which does not always pay attention: the session does not have a lifetime. Absolutely not. There is only the amount of time from the last access to this session, after which this session can be deleted by the garbage collector. And when the garbage collector starts up, who knows? And all this time, the session is still valid. Therefore, if for your task it is necessary to invalidate the authorization an hour after authorization or after the last user access, you should do this logic yourself.
For long-term authorization, in my opinion, this answer is already huge. Better a separate issue.
Data Filtering:
See the beginning of the answer. You need to know what you want to find in this data and where this data will go next. The rest does not belong to safety, only crutches and illusions of safety. There is no “do me correctly and safely” magic function.
And, of course, you cannot be sure that such information has come to you at all. First check for isset or, if valid for values, empty. Or filter_input, it will also correctly respond to missing keys.
And once again it was reminded about CSRF: remember that everything that changes the state of the system should be done through POST, PUT, PATCH or DELETE requests (if it is not about the API, then only POST is usually used) and be covered with a unique token. Unique in general or unique to the user or for the session - the question is already debatable. GET requests should be read only. Two identical GET requests must return an identical result. Sometimes it is necessary to deviate from this rule, for example, for a “unsubscribe” link in letters (changes subscription data), but this is an exception. Do not delete anything via a GET request.