Validating inputted strings as URLs - worth it for security? - security

In a web application I'm writing, I give logged-in visitors the opportunity to enter a URL to go with their uploaded picture, as a link back to their site.
I was going to validate the string entered to make sure it was a URL, but after mulling the complexity of the solutions out there, I thought maybe it's not necessary.
However, are there any security implications that I might be missing by not doing so? (I'm thinking of situations where a valid URL might include some malicious scripting, or similar.)

The security issue with URLs is less to do with their validity (though it's good to have basic checks in order to catch mistakes, and naturally you need to use the same input validation and output escaping code as you use for data in general); it's more to do with dangerous URL schemes.
Most notably javascript: URLs aren't really locations at all, but script content to inject into the page that links them, resulting in cross-site scripting vulnerabilities. There are other schemes with similar issues. Best is to allow only known-good schemes, for example by checking that the string begins with http:// or https://.

This feature seems to be a perfect example for a Cross-Site Request Forgery (CSRF) attack where the uploader links to a web page that triggers the CSRF attack.
To mitigate the risk of CSRF attacks, make sure that actions with site effects cannot be predicted by the attacking site. This is generally done by a so called token, a random value that is only known to your site and the logged-in visitors.

Correctly validating a URL is not trivial. You can get close, but it still won't necessarily cover everything allowed by the RFCs. As long as you aren't evaluating the URLs as input, running html_escape() or your framework's equivalent should be a sufficient precaution to protect your site from casual string mischief.
You may need to research your framework to understand what precautions, if any, you need to make against cross-site scripting, SQL injection, and other related issues. Most things that can go wrong will relate to unsanitized input, but your mileage may vary quite a bit.
Protecting the user is probably not a reasonable design goal if you expect 100% safety. The web is not a protected sandbox, after all.

Related

are precautions against CSRF needed for view-only pages?

All the examples of CSRF exploits tend to be against pages which process the incoming request.
If the page doesn't have a form processing aspect do I need to worry about CSRF ?
The situation I'm looking # :
the page in question contains sensitive data
as such users need to establish a session to view the page
... my understanding is that a malicious page will be able to redirect a client to this page by embedding a link to it, however since there's no action on the target to perform there's no harm that can result, right ?
There's no way for said malicious site can view the sensitive page, correct ?
Why I ask: I want the url to the page with sensitive data to have a 'simple' URL which allows people to email the link to other people (who will in turn need a session to view the page). The token-based solution I've seen for most CSRF solutions remove this possibility, and so I'd like to avoid them if possible.
There's no way for said malicious site can view the sensitive page, correct ?
Correct in terms of CSRF.
The blog you linked is talking about Cross-Origin Script Inclusion, which is a different animal. To be vulnerable to XOSI your sensitive page would have to be interpretable as JavaScript, and you'd have to be either serving it without a proper HTML MIME type, or the browser would have to be an old one that didn't enforce type checking on scripts.
You might also potentially worry about clickjacking, where another site includes yours in a frame and overlays misleading UI elements. There are some sneaky ways that has been used to extract sensitive data (see the next generation clickjacking paper and this amusing info leak in Firefox) so you may wish to disallow framing with the X-Frame-Options header.
Why I ask: I want the url to the page with sensitive data to have a 'simple' URL which allows people to email the link to other people (who will in turn need a session to view the page). The token-based solution I've seen for most CSRF solutions remove this possibility
You definitely shouldn't be putting a CSRF token in a GET URL. Apart from the ugliness, and breakage of navigation, URLs are easy to leak from the browser or other infrastructure, potentially compromising the confidentiality of the token.
Normal practice is not to put CSRF protection on side-effect-free actions.
In general, CSRF is independent from whether the request causes any side effects or not. The CWE describes CSRF (CWE-352) as follows:
The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
So CSRF is a general request intention authenticity problem.
However, although CSRF is not really feasible without any effects other than data retrieval as the same-origin policy restricts the attacker from accessing the response, the attacker could exploit another vulnerability to profit from retrieval-only requests as well and gain access to sensitive data.

Is not displaying output enough to prevent link injection cross-site scripting?

I'm new to dealing with cross-site scripting problems. We have some 404 pages that output the not found URL where, from what I learned, javascript can be maliciously substituted. To prevent an XSS attack, is it enough to simply remove the outputting of the bad URL? Or do I still need to somehow filter the input against a whitelist, for which I was looking at the OWASP library: https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API
any input from user is potentially dangerous. you receive it - it can take your whole memory :) you display it - you can be hurt by cross site scripting. you tries to interpret it anyhow - you have sql/ldap/js/xxx injection. and there are probably a few more attacks that i'm not even aware of. so if you don't display it then yes, you are secure against xss. however you still should be careful with user's data. OWASP advices are good - whitelist filtering is easiest way to get higher level of security

Voting system hack proof

I'm implementing a voting system like Stackoverflow's. How can I implement this so it is hack proof?
I've got some PHP that does database work according to the ajax request sent after the javascript parses it. Would doing a query to check the current vote state of a user be enough to avoid unauthorised votes?
It is definitely possible to implement pretty reliable solution. But this must be done server-side.
Basic rule of security: you don't trust client data.
Move all your checks to PHP and make your javascript as dumb as
$(".vote").click(function(e) {
$.post('/vote.php', vote_data, function(result) {
// update UI according to returned result
}
}
It's a common thing, however, to still do checks on the client, but as a way to improve usability (mark required form fields that weren't filled) or reduce server load (by not sending obviously incomplete data). These client checks are for user's comfort, not for your security.
Answering to your updated question:
If you store full log of when which user voted for which question, then yes, it's pretty easy to prevent multiple voting (when user can vote for the same thing several times). Assuming, of course, that anonymous votes are not allowed.
But if you have a popular site, this log can get pretty big and be a problem. Some systems try to get away by disabling voting on old articles (and removing corresponding log entries).
What if someone intentionally tries to hack me?
There are different types of attacks a malicious user can perform.
CSRF (cross-site request forgery)
The article lists some methods for preventing the attack. Modern Ruby on Rails has built-in protection, enabled by default. Don't know how it is in PHP world.
Clickjacking
This attack tricks users into clicking on something what isn't what they think. For example, they may click "Play video", but the site will intercept this click and post on user's wall instead.
There are some articles on the Web as well.
Wiki on clickjacking
5 ways to prevent clickjacking
Javascript to prevent clickjacking
NOTE: THIS IS AN ANSWER TO THE ORIGINAL QUESTIONDon't downvote it just because the OP radically changed his question.
It's a huge error even just thinking of relying on browser-side components to enforce application logic. Javascript should be used, in untrusted environments, exclusively for presentation purposes.
All application logic should be implemented, validated and enforced server-side.

Security by obscurity: what about URLs?

first of all, the question from a naive point of view:
I've got a WebApplication with a URL to a product like Products?id=123. Let's say I've got an administration page reachable from Products?id=123&editable=true.
If I consider that no one will ever try to enable the editable parameter, and thus don't need any further security mechanism to protect this page, that's security by obscurity, and that's not a good idea, right?
-
In my real case problem, it's slightly more subtle: is there any danger in allowing anyone to know my administration URLS? for instance, while working with XSL, I would like to write:
<xsl:if test="/webAlbums/mode/#admin">
(compute edit link)
</xsl:if>
but wouldn't it be easier for a potential attacker to find a weakness in 'important' pages?
Security through obscurity is barely security at all. Don't count on it.
You should make an authentication system that prevents people from using the admin page through actual security.
As for people knowing your admin URLs, it should be fine as long as your admin page is protected and there is no sensitive data being shown in the URL (such as the internal representation of a data type, the internal ID of some data, etc).
Daniel Miessler gives another element of response in his blog, the one I had in mind when I wrote the question but couldn't formulate:
Obscurity as a Layer makes a system with already good defenses more difficult to target, which improves its overall security posture.
Security Through Obscurity means that, once targeted, the system will be defenseless, i.e. all its security comes from secrecy.
Hiding configuration URLs from unauthenticated clients adds a layer of security, on top of standard authentication mechanisms.
If crackers don't know where the door is, they will be less likely to try to force it!
That's what he does by changing its SSHd port to 24, port scanner will locate the SSH server, but automatic brute-force scripts will only try the default one.
Results? after a weekend, 18,000 attacks on port 22 and 5 on port 24 (he let both ports open to permit the comparison).
You are actually in luck, as what you are proposing is actually not security by obscurity, but actually a perfectly sound security technique called Obscure URL.
To make it work, you need to make sure a part of the URL is as hard to guess as a strong password. It doesn't really matter where you include it, as long as the page cannot be edited unless that part is correct.
Insecure example:
Products?id=123&editable=true
Secure examples:
Products?id=123&editable=true&edit-token=GgSkJSb6pvNT
Products?id=123&edit=GgSkJSb6pvNT
edit/GgSkJSb6pvNT/Products?id=123
GgSkJSb6pvNT/Products?id=123
I don't do web programming, so I may be a bit off-base here, but I think there are a few things to consider:
Just like any other authentication system, if you access the admin page without HTTPS, the page request (which contains the effective "password") is being sent in the clear.
Unless configured to do otherwise, browsers will retain history and cache for the the admin page. This makes the secret URL more available to attackers or even anyone who uses your machine.
As with all passwords, if the secret URL is simple enough, there is a reasonable possibility that it could be brute forced. Something like &editable=true doesn't strike me as secure.
But if handled properly, this should be just as secure as a conventional authentication system.

Checklist for Web Site Programming Vulnerabilities

Watching SO come online has been quite an education for me. I'd like to make a checklist of various vunerabilities and exploits used against web sites, and what programming techniques can be used to defend against them.
What categories of vunerabilities?
crashing site
breaking into server
breaking into other people's logins
spam
sockpuppeting, meatpuppeting
etc...
What kind of defensive programming techniques?
etc...
From the Open Web Application Security Project:
The OWASP Top Ten vulnerabilities (pdf)
For a more painfully exhaustive list: Category:Vulnerability
The top ten are:
Cross-site scripting (XSS)
Injection flaws (SQL injection, script injection)
Malicious file execution
Insecure direct object reference
Cross-site request forgery (XSRF)
Information leakage and improper error handling
Broken authentication and session management
Insecure cryptographic storage
Insecure communications
Failure to restrict URL access
I second the OWASP info as being a valuable resource. The following may be of interest as well, notably the attack patterns:
CERT Top 10 Secure Coding Practices
Common Attack Pattern Enumeration and Classification
Attack Patterns
Secure Programming for Linux and Unix
A Taxonomy of Coding Errors that Affect Security
Secure Programming with Static Analysis Presentation
Obviously test every field for vulnerabilities:
SQL - escape strings (e.g. mysql_real_escape_string)
XSS
HTML being printed from input fields (a good sign of XSS usually)
Anything else thatis not the specific purpose that field was created for
Search for infinite loops (the only indirect thing (if a lot of people found it accidentally) that could kill a server really).
Some prevention techniques:
XSS
If you take any parameters/input from the user and ever plan on outputting it, whether in a log or a web page, sanitize it (strip/escape anything resembling HTML, quotes, javascript...) If you print the current URI of a page within itself, sanitize! Even printing PHP_SELF, for example, is unsafe. Sanitize! Reflective XSS comes mostly from unsanitized page parameters.
If you take any input from the user and save it or print it, warn them if anything dangerous/invalid is detected and have them re-input. an IDS is good for detection (such as PHPIDS.) Then sanitize before storage/printing. Then when you print something from storage/database, sanitize again!
Input -> IDS/sanitize -> store -> sanitize -> output
use a code scanner during development to help spot potentially vulnerable code.
XSRF
Never use GET request for
destructive functionality, i.e.
deleting a post. Instead, only
accept POST requests. GET makes it extra easy for hackery.
Checking the
referrer to make sure the request
came from your site does not
work. It's not hard to spoof the
referrer.
Use a random hash as a token that must be present and valid in every request, and that will expire after a while. Print the token in a hidden form field and check it on the server side when the form is posted. Bad guys would have to supply the correct token in order to forge a request, and if they managed to get the real token, it would need to be before it expired.
SQL injection
your ORM or db abstraction class should have sanitizing methods - use them, always. If you're not using an ORM or db abstraction class... you should be.
SQL injection
XSS (Cross Site Scripting) Attacks
Easy to oversee and easy to fix: the sanitizing of data received from the client side. Checking for things such as ';' can help in preventing malicious code being injected into your application.
G'day,
A good static analysis tool for security is FlawFinder written by David Wheeler. It does a good job looking for various security exploits,
However, it doesn't replace having a knowledgable someone read through your code. As David says on his web page, "A fool with a tool is still a fool!"
HTH.
cheers,
Rob
You can get good firefox addons to test multiple flaws and vulnerabilities like xss and sql injections from Security Compass. Too bad they doesn't work on firefox 3.0. I hope that those will be updated soon.

Resources