Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have a very limited understanding of PHP, as well as the internet for that matter. I'm wondering if someone could simply send a POST request to my PHP script (assuming its public). Wouldn't that have the potential to mess up my entire script?
Answer: YES.
The end.
I think this question comes from some security concerns that are not being worded.
First off, know you can check the request method (a.k.a HTTP verb) with $_SERVER['REQUEST_METHOD'].
Second, you can send HTTP request from the browser, or from other software with whatever request method, to whatever public server (read: reachable on the network). And yes, you can handle other things aside from GET and POST in PHP.
I have found the browser extension "Requestly" useful for testing.
You might be interested in Cross-Site Request Forgery and Cross-Site Scripting.
Let us talk mitigation...
It should be evident... but: validate all input. Do not trust that the input comes from a well intended user of your own site.
After validation, it could be necesary to have a sanitation step. For example, if you are going to display the values you got from a request to your users, sanitize the input so it does not contain HTML code. By doing so, you are preventing the attacker to inject potentially dangerous code in your page (being the classic example, injecting javascript).
You probably know this already also, however: Use prepared statements. If you are sending the data you got from a request to the database, using prepared statements will protect you from SQL injection.
Yes, I know the question is not about javascript or SQL injection. However Injection reminds the most common vulnerability according to OWASP TOP 10 and people who wonder if third party can make requests to their page is the kind of people who needs to be told this.
Alright, next up, you need to know if the request comes from an authenticated user. Again, you are probably doing this already, use sessions. What you might not know is that PHP session cookie is not HTTP only by default, meaning that it could be stolen on the client (see Session Hijacking). To fix that use ini_set('session.cookie_httponly', 1);.
Now, of course, the cookie could be stolen from a Man In the Middle attack, which brings me to: use HTTPS. You can get an free SSL certificate to set up HTTPS in your hosting from Let's Encrypt, if you are new to this, I suggest using ZeroSSL which will make it easy to get a certificate and uses Let's Encrypt behind the scenes.
Finally, there are scenarios where you need to make sure the request does not come from a malicius party and you cannot depend on a session being open. In this situation you need to issue a token associated with an specific action, and only allow the action to proceed if the token is presented... for example, if the user wants to recover access (forgot password) you can send a link with a token to their email account, and if the email is presented (and optionally if a captcha is resolved) you allow the user to set a new password.
I hope I do not need to tell you How NOT to Store Passwords!.
For more information see OWASP Cross-Site Request Forgery Prevention Cheat Sheet.
I'm wondering if someone could simply send a POST request to my PHP script (assuming its public).
Yes, though not via XHR/fetch from a modern browser if you haven't allowed CORS. (This doesn't stop a regular form on another web page posting to your script.)
Wouldn't that have the potential to mess up my entire script?
How so? You're responsible for properly handling anything posted to you.
Related
I have a public form that publish POST data to a PHP script.
This form is not located on the same domain, and doesn't use PHP either so the protection cannot be built around PHP session.
The goal is to allow only this form to post on that PHP script.
How do I provide more security for checking source of the request tells how to implement CSRF protection using PHP session but I wonder how I could do to protect mine without it? Is it possible?
POST requests are harder to fake compared to GET requests, so you have that going for you, which is nice. Just make sure you're not using $_REQUEST in your script.
You cannot use sessions here, but the principles are the same - you gotta implement some kind of a "handshake" between a form and your PHP script. There are a few different approaches if sessions are not an option.
The simplest thing to do would be to check http referrers. This will not work if the form is on http and script is under https, and also can be overcome using open redirect vulnerability.
Another way to go would be captchas. I know, not user friendly or fashionable these days, but that would make request forgery much harder, as hacker could not make his exploit work behind the scenes without any user input. You should look into reCAPTCHA (google's "I am not a robot" checkbox): https://www.google.com/recaptcha/intro/index.html
This is a tricky situation, because form on one host and script on another is basically CSRF in itself, so you want to allow it but only for one host. Complete security without any user interaction might be impossible here, so just try to make it as hard as possible for a would-be hacker to mess with your script, or suffer on the UX side. Personally i would go with reCAPTCHA.
On my current website i use Jquery and POST requests between different PHP files to get and update information. Currently om not using either SSL or home grown encryption to hide the plain-text in the headers, that will come later.
I'm wondering how to prevent client side POST modification besides sanitizing and validating the inputs before using them. Some of the information passed between the PHP documents are hard to predict, therefore hard to validate.
Got any tricks up your sleeves?
I was thinking i could use session stored data in PHP to validate that it was the actual server that sent the request. But i guess that session data can be "tapped" in many ways?
Choose one:
You can store data in session between requests (more server memory)
You can sign the data sent to the client using an HMAC (more server cpu), then check it on the next request on the server
There's no excuse not to use HTTPS these days. 3 free vendors now.
Two important things about HTTP - It is, by nature, stateless, therefore every request is independent of any previous requests and secondly and more importantly - it is based on trust. Once data hits the server (specifically the php script), it is impossible to know where that request originated and if the data can be trusted. This means the only way to ensure data is clean and secure is if it is sanitized and validated.
Because of the inherent trust with HTTP, any client can forge a request with malicious intent. There are ways to make this harder, and depending on what you are trying to protect you can spend more time and resources to do so. These steps are different depending on what you are trying to accomplish. Are you trying to stop a malicious user from stealing others users information? Are you trying to stop them from accessing data on your server that they should not (sql injection, directory traversal)? Are you trying to prevent the user from impersonating another user (session hijacking)? Are you trying to prevent the user from injecting malicious javascript (xss)? Depending on your goal and your risk, you would invest time and energy to try and prevent one or all of these things.
Lastly, HTTPS only mitigates a man in the middle attack (maybe session hijacking) and not any of the above mentioned scenarios, so you still need to clean and scrub all data that your php receives.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I start to write php web application (static php) , I made every thing.
But,how should I check for common security vulnerabilities: SQL injection, XSS, CSRF etc in my web application ?
First of all, automated vulnerability scanners can not give a guarantee. So you can not trust their results. I will shortly explain what yo have to do in order to secure your PHP application.
1. Use PDO instead of Native MySQL Library.
In order to secure your application agains SQL Injection vulnerability which is one of most critical web application vulnerability, you have to use PDO. For instance,
Do NOT do this.
<?php
$cal = $_GET["calories"];
mysql_query('SELECT name, colour, calories
FROM fruit
WHERE calories < '.$cal);
?>
Do this.
<?php
$calories = $_GET['calcalories'];
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->execute();
?>
2. Encode each variable that you will print on client browser
This is the key of XSS prevention. You should use encoding method before echo/print variables to the browser! There is 3 kind of XSS vulnerability. First one is Reflected XSS, second one is Stored XSS and last one is Dom Based XSS. Please read following link to understand what is XSS and how can your secure your application agains XSS vulnerability. https://www.owasp.org/index.php/Cross-site_Scripting_(XSS) .Try to explain three of them will take two or three pages! So i will skip this part.
3. Insecure Direct Object Reference
Depends on the web application, this vulnerability can be most dangerous one. Because this is not about the PHP or code syntax. This vulnerability appear because of application desing failure and code anatomy. For example;
www.gsmfirm.com/invoice/1337 -> It's your invoice for January!
www.gsmfirm.com/invoice/1338 -> It belongs to someone else!
Please read the following link. I'm sure you will understand what is the IDOR and what can it cause. http://avsecurity.in/2013/06/nokia-insecure-direct-object-reference/
4. PHP Object Injection Vulnerability
Short explanation, do not use serialize() function. Use json_encode instead of that. If you will have a look following link. You can understand clearly what is Object Injection vulnerabilities. https :// www.owasp.org/index.php/PHP_Object_Injection
5. CSRF
Cross Site Request Forgery is can be dangerous too. Basically you have to be sure about "Does this request was sent deliberately by the user?" In order to be sure that, you must generate unique key and store it in session for each user and you have to use it as hidden html input inside of html tags. Than you will check that value for each form request. "is it same with stored ?" if not, the request was not send by client with deliberately.
6. Broken Authentication and Session Management
Basically, there is two type of vulnerability. Session Fixation and Session Prediction .
In order to be secure against Session Fixation, you have to regenerate session key after successfully logged in. Also you have to use HTTP Header Cookie parameter to carry session key instead of GET parameter.
Session Prediction is weakness about session key generation algorithms. Use complex key generation method to generate unpredictable key. And please do not try to develop your own generation or encryption algorithms.
PS: I couldnt post more than 2 links because of reputation point. Sorry about that.
You can use Arachni Scanner. It's an open source tool having both web & cli interface.
I found a company that does it, but I haven't tried them:
http://lp.checkmarx.com/php-code-security
Here are some tips:
http://code.tutsplus.com/tutorials/5-helpful-tips-for-creating-secure-php-applications--net-2260
If there is user authentication then you should check that, current logged in user is not able to access any other data that is not related to him. Means current user has 3 entry from customers table then he should able to access only those 3 entries.
If you are using framework then they have implemented many security features. For example in Zend Framework Form Elements is able to add csrf in form. So, within given time form should be submitted and csrf key will be verified in back end automatically.
Most framework gives htmlescapers. So, by using that you can avoid xss at some good level. For static/core php code you should use htmlentities for avoiding extra unwanted characters.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am building a website and I have a questions with forms on login/registration page. I have a few standard javascript validations on the login page. My questions is should I just disable the login button if javascript is disabled or should I keep PHP validations on the server side code?
Which is a better approach in terms of security? I am planning to keep login/registration button disabled and only enable it by javascript. That way I can avoid writing PHP side validation of the same JavaScript that is already there. Is it a secure way of doing it?
Thanks
Overall, use PHP. Javascript can be easily fooled and/or turned off entirely. At that point your server gets supplied with whatever Mr Malicious End User wants you to have, and you won't be stopping them.
Use PHP for validation, and if you want it to look fancy, put javascript on top. But ALWAYS server-side validate.
As a general rule of thumb, anything relating to security or prevention of particular user behaviors, don't rely on javascript or CSS to stop something from happening on a page. Since scripts and css can be overridden or disabled in the browser, you'll have no protection against that behavior if they do so.
Server side is the correct place for implementing preventative security precautions.
Also, note that doing both is very nice for user experience, but server side is the only definitive place for preventing unwanted data making it through.
Every client-side validation MUST be replicated server-side to ensure security. Your client side scripts can be easily replaced by a malicious user in order to bypass your validation completely and buttons can be re-enabled fairly easily with web debugging tools.
However, it is sometimes wanted for user convenience to also include client-side validation. In which case, you have to validate both server-side (PHP) and client-side (Javascript).
PHP side validation is better .
Client side validation is NOT secure because it can easily be hacked. It is for user convenience only. For example, in response to client-side validation, the user can fix mistakes before the form is submitted. That saves the user time, and they appreciate your site.
Security validation must take place on the server
You must validate your data on the server and parse the answers of it with Javascript. Only use Javascript to add/remove HTML content and create better user interfaces.
Always take this into account: What happens if the user disables Javascript in his/her browser?
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm putting together read and write methods to my database and exposing them via URL (I'm using CodeIgniter framework and using URL segments to pass parameters to these methods). The original idea was to have my Ajax script call these methods. However, now I am thinking I could potentially expose these methods to any developer.
What should I do to make sure only authorized developers use my API? I'm thinking they should pass an API key and possibly password to each method call. If I were to provide them with such details, would that be secure enough?
Also, I'm thinking that I should support POST instead of GET as some of the required parameters may not fit in nicely with URL segments. Thoughts?
Implementing OAuth http://oauth.net/documentation/getting-started/ would work for what you're trying to do. I'm not certain of what type of data you're securing, but I agree with TradyBlix this probably best. I've implemented it before, it's not too hard to figure out, it's well documented with many APIs that handle user-data utilizing it.
Another thing you should think about is limiting API Keys to domains, so a developer can only use their API key from their own domain-essentially preventing an unauthorized developer from gaining access, at least without gaining access to an authorized domain and corresponding key.
First: require HTTPS.
HTTPS ensures that a secure channel is established before any request data is sent. Yes, before any request data is sent: URL, headers, cookies, GET or POST parameters... anything. This means that you can use simple methods such as HTTP Basic authentication over HTTPS without putting the user's credentials at risk.
This is really not negotiable, unless the data you are passing over the API is truly public. If you aren't using HTTPS, then any communication with your API (including HTTP Basic credentials) can be sniffed in plain text.
The only reason major sites (like Facebook) don't use HTTPS is because it gets expensive at massive scale.
If you absolutely can't run HTTPS, then you should look into OAuth, which is making strides in API authentication in exactly this situation. With OAuth you can authenticate users while keeping credentials secret over unencrypted channels.
Second: authentication is not authorization.
Don't blindly trust data from authenticated API users. Make sure that the methods and actions they are accessing are appropriate, otherwise you may give your users a backdoor into other users' data or administrative functions.
There's a lot more to it than this, but if you follow these two principles you're on your way.
Maybe you should check out OAuth. It's An open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.
I haven't tried it myself to be honest but it's the first thing I thought of when you mentioned authorized developers use my API. Just an idea.