I have a website, on one page it reads a cookie from the users computer and uses that as a variable in the php code, for example in echo statments.
I am not currently cleaning the cooking any way.
2 questions:
can someone hack their cookie to put stuff into my php code?
if yes, how can i prevent this? HOW can I clean it?
Thanks!
Yes, it's very very easy to edit the cookies on the client.You should handle the values of the cookies as any other user generated input: don't trust it and validate it.
Yes, one could very easily exploit this depending on how it's used in the code. One could for instance, forge the entire request and provide any desired value for the cookie.
The question of how to prevent this depends on what values you are expecting the cookie to contain. All you need to do is make sure that the value of the cookie fits within your specification. Without knowing what this specification is or how the value is being used, there is not much more to say.
If you are only echoing the cookie, then the vulnerability that the user can explode is called "XSS" that stands for Cross Site Scripting. Basically he would insert <script> tags in the website to execute javascript.
You can prevent this by using the function strip_tags in php to clean tags from the cookie.
If you use the cookie in some other way, there could be new security issues, please specify if that is the case.
Strip_tags does not protect you from being hacked nor does it strip XSS. It only strips the HTML and you don't need HTML to XSS a site.
The problem is not in the input per se, it's in how you output it. If you echo it directly into an HTML page then you need to HTML-encode it; that's true of all strings you include in an HTML page, not just cookies. If you are as a habit outputting unescaped strings into HTML then you probably have much easier to exploit XSS bugs than this(*).
The way to handle variable text properly for output into HTML is to wrap every variable in htmlspecialchars() at the point you echo it into HTML (not as an input handling step). Do not use strip_tags()—it is not designed as a security measure and it fails in a variety of circumstances. If you need to accept limited user-input markup use an HTML purifier library.
(*: how exploitable an HTML-injection-from-cookie is depends largely on how that cookie gets set. If there is any way an attacker can persuade your application to set another user's cookie to a specific value, it'll be easily exploitable; otherwise, in order to exploit the HTML injection they would have to find a cookie-fixation bug. That could be a header-injection bug in your app, or it could be any vulnerable application in a ‘neighbour domain’—an application at a.example.com can set a cookie that will be read by an application at b.example.com.)
As people have posted a cookie is super easy to manipulate on the client side. It's basicly just a text file. If you only echo and don't depend on the data in the cookie for db calls, function calls or file includes you pribably don't need to care becasue the user would only affect what's displayd on his local machine. On public computers this could ofcourse be a problem though.
If you want more controll handle the data using serverside sessions. Or if you really need the data in the cookie, store a hash of the cookue values serverside so you can determine if it has bern tampered with
Related
Do I always need to validate user input, even if I'm not actually saving them to a db, file, or using them to include files etc..
Say I just wanted to echo out a request variable or I was using it to send email, is there any need to validate or sanitise it? I've always heard people say that all user input should be checked before doing anything with it, but does it actually pose any threat, if I'm not doing any of the above?
I wouldn't recommend it.
my rule is - NEVER TRUST USER'S INPUT.
lets say that your'e working on a team.
as you wrote, you build a simple form that submit the data to php file and than mail it.
after 3 weeks another team mate wants to use that form.
he's assuming that the data in the php file is clean . he dont know that you dont filtered it.
this is a crack for troubles.
Do I always need to validate user input, even if I'm not actually saving them to a db, file, or using them to include files etc..
Everything you are going to do with user supplied data depends on the context in which you are going to use it. In your single sentence you are already talking about 3 different contexts (db, file, include). Which all will need a different strategy to prevent things for that specific context.
Say I just wanted to echo out a request variable or I was using it to send email, is there any need to validate or sanitise it?
There are more things you can do besides validating and sanitizing. And yes you should handle this case (which is another context btw). Basically you should handle all user data as if it is malicious. Even if you are "just echoing it". There are numerous things I could do when you are "just echoing".
Considering we are in the context of a HTML page I could for example (but not limited to) do:
<script>location.href='http://example.com/my-malicious-page'</script>
Which can be for example an exact copy of you website with a login form.
<script>var cookies = document.cookie; // send cookieinfo to my domain</script>
Which can be used to get all your cookies for the current domain (possibly including your session cookie). (Note that this can and imho should be mitigated by setting the http only flag on the cookies).
<script>document.querySelector('body')[0].appendChild('my maliscious payload containing all kinds of nasty stuff');</script>
Which makes it possible to sideload a virus or something else nasty.
<!--
Fuck up your layout / website. There are several ways to do this.
I've always heard people say that all user input should be checked before doing anything with it
This is mostly wrong. You only need to decide how you are going to handle a piece of data once you know what you are going to do with it. This is because you want to prevent different things in different situations. Some examples are (but not limited to): directory traversal, code injection, sql injection, xss, csrf.
All above attack vectors need different strategies to prevent them.
but does it actually pose any threat, if I'm not doing any of the above
yes totally as explained above. All data that is coming from a 3rd pary (this means user input as well as external services as well as data coming out of the database) should be treated as an infectious disease.
im relatively new to php and was hoping you could help me understand why you should sanitize html when 'echo'ing , specially if data is from cookie..
i.e instead of
<h3>Hello, <?php echo $_COOKIE['user']; ?>!</h3>
you should do
<h3>Hello, <?php echo htmlspecialchars($_COOKIE['user']); ?>!</h3>
this is what i understand.
cookies are stored on client side, hence are a security risk since the data in them can be manipulated/changed by evil users (lol # evil) .
but since the cookie is stored on client side, it means a client can only change his own cookie, which means if he adds some kind of malicious code to $_COOKIE['user'] , when the cookie does run, the malicious code will only be shown to one user (who changed the cookie in the first place) and no one else!? so whats the problem?
You're assuming that the user changed his own cookie. Cookies can be changed by a third-party (Edit: Using additional software. Third-party websites cannot change the cookie directly). This would enable someone to inject malicious code into the user's browser, changing their user experience and potentially posing an additional security risk for your code.
Instead of just looking security aspect, there is a user experience aspect. The code you present is not really useful for security because risk are very poors in this case BUT if username can contains quote or < > signs, the user will not understand why its login is not displayed correctly.
Using such a code garanties that you will display correctly the username (and add extra security), no matter what kind of characters you allow during the registering process.
It's not really a risk in that situation - but this is rarely the actual situation. You should do it anyway.
Consistency - don't put it in now, and when you change it to something else, you might open up a security hole.
User experience - just because a cookie contains HTML doesn't mean it was an XSS injection attempt. What if somebody's name were &? I've been thinking of changing my name to &.
A user could inject a script into your page by changing the cookie. That fact alone should be enough to make you pause for thought.
Imagine you are creating a really by website where many data is stored in the user cookies.
Maybe some of the data in the cookie is used by your website to build an SQL statement, which could result in errors if the user or another website modifies your cookie in a bad way.
If you don't check the cookie data for injections, and even if, something could be written in the cookie that could harm your data consistence, e.g. a String in a varchar column where only hexadecimal numbers should be inserted.
The best way to deal with that problem is to either use Sessions where possible and only store the minimum amount of required data in the cookie as possible.
but since the cookie is stored on client side, it means a client can only change his own cookie, which means if he adds some kind of malicious code to $_COOKIE['user'] , when the cookie does run, the malicious code will only be shown to one user (who changed the cookie in the first place) and no one else!? so whats the problem?
Well, it depends on your implementation and what you use cookie's data for. An evil user could inject SQL through your cookies, change his permisions, impersonate another user, etc.
That's why you should always code thinking about the worst scenario
I have built a small app using javascript. I am using javascript for form validation and i am wondering if by using the "no script" tag if this will protect me against people passing non-clean data into my mysql db? I will deny access to the application to anyone who has it turned off. Is this a secure method or do i have to also do php form validation on top of the js validation?
If not, can someone advise me on what is the best way to ensure that the data submitted to my db is not harmful and clean. Id like to do this using javascipt if possible and not layer it with php but if i have to i will as long as my app is secure.
I know i must do some php cleaning such as htmlentities but want to avoid doing form validation with php.
Thanks.
No, you can never trust the client-side to validate. You must always validate server-side. Client-side validation can improve the user experience, but it gives no security benefit.
As a general rule, you never want to rely on client-side code (javascript in this case) to validate data. The client has full control over anything you would put in javascript, and so it would be pretty easy to bypass. Always validate on the server where you have full control of what is happening.
No, you always need to do serverside validation. You can alter JS even when it's turned on (in Chrome for example, you can just pause script loading, edit the JS then run it), therefore it wouldn't even matter if it's on or not.
This is a good starting point: http://net.tutsplus.com/tutorials/html-css-techniques/build-a-neat-html5-powered-contact-form/ (towards the bottom is the validation examples)
Javascript protection is just "visual". Anyone can bypass it and insert any data he/she wants.
You should always validate user-submitted data server-side.
Basically you can start with mysql_real_escape_string() for preventing mysql injection, and do some tag stripping if you are going to display the inputted data back.
I'm wanting to pass data from one php page to another on click, and use that data in populating the linked page. At first I was going to use ajax to do this, but ran into trouble, and then realized it was as easy as placing the data in the href of the link.
My question is, is it safe to place the data directly in the href in this manner? I know that passing the data via the URL (which this ends up doing) is safe, but I heard somewhere (that I can't recall), that placing the data directly in the href of a link can cause problems with web-crawlers and the like.
Is this true? Is there anything else I should worry about in using this method? Or is this the best way for me to send data, unique to each link, to another page on click?
The PHP:
while($row = mysql_fetch_assoc($result_pag_data)) {
echo "<a target='_blank' href='secondary_imgs.php?imgId=".$row['imgId']."'></a>";
}
There should be no problems with web crawlers as they just follow the links.
There is however a potential security problem in that malicious users can address arbitrary rows in your table by altering the URL string. This may or may not be a problems depending on what the links point to.
If you need to restrict your data to particular users then this is not a good idea, otherwise, its simple and straightforward if it works for you then do it.
I think it's safe enough if you want to display some data, but never use get method to insert data, especially careful when it comes to sql. NEVER use get method to modify sql, if had to, validify the arguments first.
Be careful with post method too. In a word, never trust users, you never know.
It looks like it's safe since you're "only" querying an image with a specific id (that's all you're doing, right?). Just ask yourself if
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
9.1.1 Safe Methods
Implementors should be aware that the software represents the user in their interactions over the Internet, and should be careful to allow the user to be aware of any actions they might take which may have an unexpected significance to themselves or others.In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe".
applies.
Neither passing data through URL, nor embedding it into href is safe.
That data can be seen by user, so you are not protecting your data from user.
That data can be modified by user, so you are not protecting your data from modification and your script from getting evil or misformed parameters.
So, if you are designing the system which is going to be run under strict protection in a friendly environment - it's OK to pass params through the URL (hovewer, note that URL string is limited to 4096 characters). If not - it depends on protection level you want.
The simpliest way is to use POST requests instead of GET. THis way you'll not protect your data from evildoers, but ordinary users will not have the ability neither see nor modify it. Anyway, it's a good idea to validate the input on the server always.
Define "safe".
Without knowing the the threat model is nor how the data is used it's impossible to answer.
Certainly there are very important differences between a GET and POST (but note that a POSTed for can still send GET variables via the action URL).
It's no less dangerous using a POST rather than GET to send data. Nor using a cookie. All can be modified at the client end.
If you're talking about CSRF, then there's lots of methods to prevent this - try Google for starters.
Is the XSS attack made by user input?
I have recived attacks like this:
'"--></style></script><script>alert(0x002357)</script>
when scanning a php page without any html content with acunetix or netsparker.
Thanks in advance
Remember that even if you had just a static collection of HTML files without any server-side or or client-side scripting whatsoever, you may still store you logs in an SQL database or watch them as HTML using some log analyzer which may be vulnerable to this kind of URIs. I have seen URIs in logs that were using escape sequences to run malicious command in command line terminals – google for escape sequence injection and you may be surprised how popular they are. Attacking web-based log analyzing tools is even more common – google for log injection. I am not saying that this particular attack was targeted at your logs but I'm just saying that not displaying any user input on your web pages doesn't mean that you are safe from malicious payloads in your URIs.
I'm not 100% sure I understand your question. If I understood you correctly, you used a security scanner to check your web application for XSS vulnerabilities and it did show a problem about which you aren't sure if it really is a problem.
XSS is pretty simple: whenever there is a way to force an application to display unfiltered code a user provided, there is a vulnerability.
The attack code you show above seems to target a style tag that add certain user provided data (eg. a template variable or something similar). You should check if there's such a thing in your app and make sure it's properly filtered.
Blackbox scanners will try this attack even when your html doesn't expect any parameter because there is no easy way for them to know what's going on in your source code), if you don't echo anything or use stuff like PHP_SELF you are fine.
Also take a look at DOM Based XSS to understand how XSS might happen without any server-side flaw.
If the scanner reports a vulnerability take a look at the description and source code, generally it will hilight the vulnerable part of the source code so you can see.
Secondly you can manually test and if executes JS then you can investigate whether it's about your framework, or a vulnerability in the javascript code or in URL Rewrite (maybe you echo your current path in the page) or something like that.
Where did you find this XSS? As far as I am aware if a page does not take any user-input (a process/display it) it cannot be vulnerable to XSS.
Edit:
I think I misunderstood your question - did you mean can XSS occur by entering Javascript in the address bar in the browser? Or by appending Javascript to the URI? If the latter - then the page is susceptible to XSS and you should use a whitelist for any variables passed to your URI. If the former, then no, any client-side changes in the address bar will only be visible to that single user.