What is the best way to stop Cross-Site Scripting for ColdFusion?
Is there a setting to set in the CF Admin or is their code in you can put in Application.cfc?
Example Code:
http://test.com/file.cfm?center=fisCenter')" onmouseover="alert('Insert Hax Here.')" style="display:block;position:absolute;top:0;left:0;width:10000px;height:10000px;z-index:100">
First things first: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet. OWASP has tons of resources to help devs better understand the problem. XSS isn't a CF problem, but a webdev problem.
That said, which version of CF are you working with? It's more difficult to deal with in CF9 or lower. Those versions have limited built-in functionality and may require falling back into Java methods, if able. But CF10 added a bunch of functionality.
HTTPOnly Cookies - while "available" well before CF10, CF10 added it as a setting in CF Administrator or by using this.sessioncookie.httponly=true in Application.cfc. You can still accomplish this in older versions through JVM settings or content headers. (https://www.petefreitag.com/item/764.cfm)
Content Secruity Policy - (https://content-security-policy.com/) I will admit that I'm not as familiar with CSP as I should be. It's not really CF, but it's still something to know about. It lets you establish the approved origin of the content in your site, which should hopefully prevent someone from injecting content that redirects a user's action to somewhere else. But be warned that it is browser-dependent.
scriptProtect is a CF Admin or Application.cfc setting. (http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d69.html) will help with a lot of XSS, but not all. It's a simple pattern-matching blacklist method instead of a whitelist (it pretty much looks only for object, embed, script, applet, and meta), so there are many ways to get around it. It should be used but not relied upon or expected to be 100% safe.
encodeFor*() - (https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-e-g/encodeforhtml.html). These have been much improved since the HTMLEditFormat() days. Make sure you use the appropriate encoding method.
Canonicalize() - (https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-c-d/Canonicalize.html) This function is great, but I believe there was a minor change between 10 and 11 that adds a little better handling. With the additional CF11 throwOnError flag, when you check for both multi- and mixed encoding, you can throw/catch an error if either are detected and log/block that user. There is pretty much no reason any legitimate user would ever hit those flags, so logging/blocking isn't a bad idea.
Also see Dave Epler's excellent writeup in http://learncfinaweek.com/week1/Cross_Site_Scripting__XSS_/. That will give you some good info on XSS in ColdFusion.
And finally, as you can see from some of my earlier links, Pete Freitag has some the best security resources I've found (https://www.petefreitag.com), and he tends to be the expert I trust for information about ColdFusion application security. Pete's Bank of Insecurity app (https://github.com/foundeo/cfml-security-training) will give you some great examples of how CF can be exploited.
The moral of my story is one of basic Defense In Depth, even for a single type of exploit. Some of my examples above involve code you write, some are page headers (not quite the same kind of code) and some are Server Administrator functions or settings. You can never be 100% safe, but it's a good idea to throw multiple roadblocks up in the way of a malicious user.
This seems to be the answer I was looking for so far.
<!--- In Application.cfc --->
<cfscript>
this.scriptprotect = "all";
</cfscript>
<!--- In OnRequestStart in Application.cfc --->
<cfscript>
sanitizeScope(url);
</cfscript>
<!--- CF10 Canonicalize --->
<cfscript>
/* This function decodes any particular scope values */
public void function sanitizeScope( struct scope )
{
for( var key in scope )
{
scope[key] = canonicalize(scope[key], false, false);
}
}
</cfscript>
Related
Let's say I want to display all the records a particular SELECT statement returned. So I do something as simple as this:
<?php
$listings=ProductListings::find(array());//ProductListings is my model
foreach($listings as $listing)
{
echo '<pre>'.print_r($listing,true).'</pre>';
}
?>
But, instead of seeing a clean-looking output, like one unsavvy with Phalcon would expect, I see a massive screen splashing properties via di:protected including my config and the disturbing:
[db] => Phalcon\Db\Adapter\Pdo\Mysql Object
(
[_eventsManager:protected] =>
[_descriptor:protected] => Array
(
[host] => localhost
[username] => **myUsername**
[password] => **myPassword**
[dbname] => **myDatabaseName**
[charset] => utf8
)
I know somewhere down the line, I'm gonna find myself doing a print_r and the database information is gonna go public; or worse, a search engine will cache the page with my sensitive data in tact. Whether someone can make use of such information or not, that's not the point. I don't want such information displayed in the first place when I do a print_r. Security concerns aside, I don't wanna have to search pages and pages worth of clutter to find the data I'm interested in.
My question to you is, coming from a design point of view, what options do we have as Phalcon developers to add another layer of security to our applications, so these protected properties are less likely to expose our sensitive data with one wrong slip of a print_r when we're debugging? The same problem is evident with all Phalcon-related objects which store references to the di. I imagine I could do something with output buffering to scan the output every time for possible slips, but that would just be silly. Being considerate of Phalcon's architecture, what kind of countermeasures can we take in an effort to keep our applications secure?
Short answer: There is no way to get around this, I'm afraid.
Somewhat longer (but probably equally unsatisfying) answer:
Bear these two facts in mind:
print_r is, as you rightly said, a means of debugging. It will print out all the contents of a variable, regardless of how sensitive the information contained might be to you.
The concept of dependency injection does not work without a DI container. This container is designed to hold all relevant parts of your application like the database interface, the view engine etc., therefore making it the sacred core of your entire app.
Understand that what you're doing is exposing the inner sanctum of your app by using print_r($di) or on any component therein (because they also hold a reference to the DI). It's probably the worst thing you can do, because - as you correctly pointed out - if you forget to remove one of these debugging calls, it would be a worst case scenario in terms of security.
Conclusion:
You have to use another way of doing safer debug outputs. Never output your DI container in its entirety, never output more data than you really need for debugging.
I would recommend limiting that output to stuff like the current route, active controller and action, variables present in your view and possibly other less sensitive data.
If you would like to safely debug your SQL statements, I would recommend reading this part of the Phalcon documentation.
Try this
<?php
$listings=ProductListings::find(array());
foreach($listings as $listing)
{
echo '<pre>'.print_r($listing->toArray(), true).'</pre>';
}
?>
Hey guys! Working on a new Cake app and wondering if there is anyway for me to remove the ID-in-URL routing from Cake. Perhaps by passing the ID in POST somehow? Having the ID passed in as a URL param just seems really shoddy and unsafe. Thanks!
"Shoddy"? It's standard practice and a perfectly fine solution to have ids in the URL. Look at the URL of your question:
http://stackoverflow.com/questions/4638262/removing-id-from-cakephp-url
^^^^^^^
id
Also, there's absolutely nothing unsafe about showing an id in a URL. It's just a number that doesn't mean anything. If a user can do something "bad" only by knowing this id, your app is broken and insecure, not the id-passing mechanism.
Trying to work around this scheme means working around the fundamental principle of the HTML protocol and opens up a whole new can of worms.
Some people prefer using slugs instead of primary key ids. This is the removing-id-from-cakephp-url part of the URL from this page. Take a look at the SluggableBehavior.
However, slugs can change. Hence, having the primary key in your URL is useful if you want to have a permalink. StackOverflow does both so that it can support both permalinking from other sites, as well as for SEO reasons. :)
Regarding security issues, I guess the other answers have already pointed out that there are other ways to make your application secure.
Why do you care? URL-s are optimized for SEO reasons, an ID won't matter if it's ain't too long. If the latter, consider using a shorter one with numbers and letters in them instead, it will be as difficult to guess as a long one with just numbers.
If you are not using GET and you do not supply the params in the URL, your users won't be able to copy-paste the location.
I would like to know if there is a way to prevent the use of userscripts on my browser game site?
Many use Greasemonkey to have advantages over other players, and I would like a way to disable these scripts.
I found this old article, "How To Disable Greasemonkey On Your Web Site", but it's from 2005 and doesn't seem to work.
Combating a smart scripter is tough. They have the upper hand since their script can touch the page before your server does, and can block or replace just about anything. See this answer to a very similar question.
Your smartest, and most cost-effective countermeasure is to sanction the users who are "gaming" the game. Attack the burglar, not the lock-pick.
If you insist in a tech war with your users, nothing you do will block everybody, but you can make them work for it.
Here are some things you can do make life harder for scripters:
Frequently change the structure of the page, especially element ID's and CSS class names. If you can, periodically insert or remove elements, so that the key <div> is not always the 3rd one in the second <table>, for example.
Every time you make a change, monitor your logs for users who get a sudden decrease in performance or usage -- for however many hours or days it takes them to adapt their scripts.
Likewise, frequently change your javascript filenames, and change the names of any variables or functions that the scripter may use.
Write your click and keyboard event-handlers to only work for trusted events, for browsers that support it.
You can put key text, including countdown timers, in images with unpredictable names. Making it hard for the script to detect key events. Needing to do OCR ramps up the skill-level required by a Greasemonkey scriptwriter, considerably. (At least for now.)
If you move the key game action into Flash, it becomes an order of magnitude harder to script for. They may even have to reverse engineer your flash and replace it with one that has scriptable hooks. Switching to Flash will annoy and drive off users (like me), though.
See that answer for more but, again, the best and most cost-effective approach is to sanction the offending user(s). Be sure that your Terms of Service specifically forbids what they are doing, though.
As addition to Brock Adams' own answer, here's couple methods for finding a possible scripter.
Timed function that checks DOM tree and search for added elements that are not your code's creation, or look for missing elements.
Primarily finds scripter who alters UI, yet haven't read/understood the game's js-source.
Client-side.
"Missing element"-search may get false positives from people who use something like AdBlock Plus. Not really false positive, if aim is to rank them out, too.
Inspect cookie content and look for hints of user added content.
If scripter has to transfer information from page/session to another, and has/knows no other method, he may attempt to use cookies for this.
Inspect query/hash in URL for content not added by your code.
It's possible to try to transfer information to other pages by altering links.
Hash-content (# in URL) is accessible only client-side.
Inspect session/localStorage.
Client-side.
Disable access thru anonymizing services, like anonym.to.
Circumventable, but makes life harder for people using unwanted online-tools.
Allow access to game-page only if referer is correct, otherwise redirect to login-page.
Another method to limit access to game-pages from outside sources.
If you want to be a pain, kill active session when redirecting.
NOTE: All client-side functions can be circumvented by scripter who understands the code.
NOTE: Usage of these requires some wisdom and good planning. If doing things wrong, then with client-side stuff you risk of kicking users' browsers on knees or DDoSing your own server. Or you may end up banning least half of the userbase after an update on your own code, if you use too much automation.
Here's one of my scripts. It could definitely still use some work, but the framework is there (though you may need to wrap everything in a big function to make variables private)
var secureElements,secureTags,secureTagLoop,secureLoop,var secureReporter = secureAnalyzationFunction = 0;
function analyze(secureAnalyzation){
if(secureAnalyzation.indexOf("function ")!=-1){
secureAnalyzationFunction = secureAnalyzation.substring(secureAnalyzation.indexOf("function ")+9,secureAnalyzation.indexOf("()"));
secureAnalyzationFunction = secureAnalyzationFunction+"=undefined;";
eval(secureAnalyzationFunction);
}
}
function secure(){
var secureTags = ["script","link","meta","canvas"];
for(secureTagLoop=0;secureTagLoop!=secureTags.length;secureTagLoop++){
secureElements = document.getElementsByTagName(secureTags[secureTagLoop]);
for(secureLoop=0;secureLoop!=secureElements.length;secureLoop++){
if(secureElements[secureLoop].outerHTML.indexOf("verified")==-1){
analyze(secureElements[secureLoop].outerHTML);
secureElements[secureLoop].parentElement.removeChild(secureElements[secureLoop]);
secureLoop--;
secureReporter++;
console.log("Deleted "+secureReporter+" foreign elements.")
}
}
}
}
window.onload = function() {
secure();
setInterval(secure,1500);
};
I am working on a site that have an international aim; I.o.w., logged in users can add text in their own language. I am hoping for international page names and content.
An URL example, like the Japanese Wikipedia: http://ja.wikipedia.org/wiki/メインページ (Both pagename and content text).
I know by using UTF-8, I can do this, but how should I control it?
UTF-8 contains way to many languages/letters to control in a script, I guess, so how safe/unsafe is it to allow people to add UTF-8 text?
I can see that someone could add harmful code this way, but how to prevent it?
All information regarding safety/control when using UTF-8 is appreciated!
EDIT: PS! I use PHP and MySQL.
Warning: perhaps a slightly rusty response:
Note: not discussing host name (IDNS) issues.
The only completely safe thing here is to use %-escaped UTF-8. Some browsers will display this as what you want, and some will display the %-escapes. (e.g. http://foo.bar/%ee%cc%cf.html)
If you put 'real UTF-8' in the URLs, many things will work, but there may be unpleasant surprises lurking for some people in some browsers. I'm reading your question as dealing with 100% static content. If you are trying to do this with code behind the site, you have additional issues to work on.
The 'unpleasant surprises' would be (a) people finding the %xx's in the URL unreadable, (b) a browser that melts, (c) some data scraping or aggregating application that melts.
I wish I were more up to date on this, but I'm not, so my recommendation is to deploy a test site and then try to access it with everything you can put your hands on, including mobile phones. Persuade Google to index it, and see what happens there.
For domain names, this is called IDN. For page names, you may want to think of the possibility of IDN spoofs.
It's safe as long as you don't interpret it literally as SQL (SQL injection) or HTML (XSS) or any other language. Just escape any user-controlled input (request URL, request headers, request parameters, request body, etc..etc..) at the point it's going to be used in SQL or HTML.
It's unclear what server side programming language you're using, so I can't go further in detail.
I wish to block ALL my content from any users using an ad-blocking browser extension (ie. Adblock Plus for Firefox, Adthwart for Chrome).
How can I acheive this? Is there a server-side solution? Client-side?
Edit 1
This question regards the detection of ad-blocking browser extensions:
Detecting AdBlocking software?
I'm concerned with post-detection action.
Edit 2
A duplicate question was asked after mine, so I thought I'd link to it here:
Prevent Adblock Users from Accessing Website?
To detect if the user is blocking ads, all you have to do is find a function in the ad javascript and try testing for it. It doesn't matter what method they're using to block the ad. Here's what it looks like for Google Adsense ads:
if(typeof(window.google_render_ad)=="undefined")
{
//They're blocking ads, do something else.
}
This method is outlined here: http://www.metamorphosite.com/detect-web-popup-blocker-software-adblock-spam
It's like trying to block users from reading your contents while standing rather then while sitting. It's silly, and it's likely to drive visitors off your site. The last time i saw a "you're using adblock, that hurt web developing bla bla" i jst blocked that div with the element hiding helper. It was fun i admit. Most sites are almost unreadable as now, with flashing ads and pale contents. A good quantity of ads are, also, malevolent, disguised as part of the site they're in takes the user to bad places.
That's why you should not. If you still want to, bad news, you can't. As long as i can write $('.ad').hide() in my console, nobody can stop me from adblocking something. I sometimes give up when ads divs have a very generic class, id, or they haven't any, so that it's difficult to target them with the adblock element hiding helper (of course if they are not in the lists, in that case i dont even know they exists). So the best you can do probably is give to ads a class of .content or something you use also in other parts of the site. It's not much, but it' all you can do. And just because you can, it does not mean you should. The web marketing model have to change, and it will.
That I know of this is not directly possible. Most add blockers work by locking at the URLs that are being "requested" and either blocking directly, or looking at the content/mime-type and blocking based on that.
You might be able to do something by looking for signs of the adblocker, but this will be difficult at best.
Although I love my adblocker, it's about answering questions. You could check if an url that would normally be blocked by an adblocker is reachable, and continue only if that image/bla in question is loaded. otherwise, you just don't.