Private browsing in Opera is not so private actually

I've always been using Opera's private browsing when didn't want any history and other stuff to be saved locally. Always until I decided to take a look at how private it really is.
After some private browsing I navigated to ~/.opera/temporary_downloads and noticed that Opera stores some necessary files there. There were:
  • crossdomain.xml (which may reveal domain you browsed in many cases)
  • various swf files (which may reveal sensitive information when decompiled)
  • strange video_related.htm file, which contained a lot of info
That's fine, but the actual problem is that Opera doesn't delete the files when closed. It only do this when opened in next time. It works so regardless private or usual navigation. And I doubt anyone opens Opera again just to clear files after private browsing.
So, Opera's private browsing is not so private actually.


Drupal and cookies domain caching

From time to time anyone experience some problems with non-fresh Drupal installations (e.g. some project from SCM). The major one for me was some strange cookie setting and handling - when I tried to login Drupal replied with correct Set-Cookie header, but cookies were not saved within browser, i.e. after login the page was just reloaded with login prompt. No message or anything to help me. So I just started commenting and editing related code by random. Finally, I got it. The problem is that Drupal was installed first with hostname A and I tried to work with it on hostname B. Don't know why sometimes it's okay and sometimes it's not. However, you just need to uncomment $cookie_domain and set it to your hostname in settings.php. Just like this:

$cookie_domain = 'your.domain';


Using Hudson variables in Python

While moving my continuous integration build script to Python (using Python Plugin for Hudson), I faced a problem of using Hudson environment variables. I am new to Python and get used just to place variables in shell script like $WORKSPACE or ${WORKSPACE}. Still, it didn't work in case of Python. So, if you met such a problem, you should use os.eviron() method. For example:


import os

workspace = os.environ['WORKSPACE']
print workspace


Getting Fun from Responsible Disclosures

I've recently released two proof-of-concepts for jCart application and Simpli Easy Newsletter (formerly AFC Simple Newsletter) script. Both of these disclosures were pretty exciting actually.
As a responsible security researcher, I first contacted both vendors.
Guy from Simpli Easy Newsletter quickly replied. He said: Thanks, I'll let my friend know so he can fix.
Funny, isn't it? Three weeks have passed, but his friend did nothing and further emails from me were ignored. So, my disclosure was responsible in effect.
Absolutely different situation happened to jCart. I sent an email to its vendor, but didn't receive any reply and in a couple of days released vulnerabilities. Some time later I received annoyed email from Doug Whitney (jCart guy), where he explained that I was wrong not contacting him first. Of course, I forwarded him my previous email and, what's funny, everything was correct, but it got into Spam box. So, was it responsible disclosure or not? Anyhow, it was pretty funny.


PunBB v1.3 Extension Scanner

While pentesting one project, I've faced PunBB v1.3 forum running there. As long as it would take a bit of time to check for installed extensions (even though there are not so much for it), I've written a pretty simple Python script to enumerate them. Maybe I It gets the list of available extensions from PunBB site and searches for them at provided website. Its code is really dirty, but I needed quick solution. Maybe it will be useful for someone. Or maybe I just failed googling for a one. Anyway, here it is. Usage (note no trailing slash):

$  python3 scanner.py http://www.example.com/forum


import urllib.request, re, sys

host = sys.argv[1]

  l = urllib.request.urlopen('http://punbb.informer.com/svn/additions/punbb-1.3/extensions/')
except urllib.error.HTTPError:
  print('Cannot enumerate available extensions from http://punbb.informer.com/')

e = l.read().decode()
e = re.sub('<.*?>', '', e)
e = re.findall('(pun_.*/)', e)

for i in e:
    urllib.request.urlopen(host + '/extensions/' + i)
    print('YES - ' + i)
  except urllib.error.HTTPError:
    print('NO  - ' + i) 


Opera and access to file:// iframes

It's just a quick thought about getting content of iframes with file:// sources. While Firefox and Chrome don't alllow access to contentWindow and contentDocument properties of iframes with file:// sources, Opera and Internet Explorer don't have such security policies.
It's possible to get access to it in case when original file with iframe is saved locally. This way, Opera and Internet Explorer render file iframe and, as long as protocols match, which is required for contentWindow and contentDocument properties, allow reading it (actually, Firefox lets this too, but it also compares path to file - if they differ, it throws security exception).
So, we force user to save webpage locally (as HTML file) and to open it. In case of IE, however, it won't execute Javascript by default. Still, Opera lets us do it.
Here is a proof-of-concept just for fun:

<body />
  iframe = document.createElement('iframe');
  iframe.src = 'file://localhost/etc/passwd';
  info = iframe.contentWindow.document.body.innerHTML;

P.S. Wow, I don't really know what does it mean, but Safari runs Windows Explorer with the path of such iframes.


Exploiting IE MIME-sniffer vulnerability in Drupal

IE always loved to create vulnerabilities where they would never be. Not many people know, but there is an old bug in IE MIME-sniffer, which can be easily exploited. The essence of the bug is that when IE renders file, which was sent along with Content-type: text/plain header, it tries to identify its MIME type. So, if file contains HTML code inside, IE will think its text/html and render it. Simple example of exploit in Drupal:
1. There is a Drupal site with enabled Upload module.
2. Attacker uploads *.txt file with HTML code inside. By default Drupal allows *.txt files.
3. Attacker sends a link to that file to victim.
4. Victim opens it in IE and HTML code is rendered.

It's pretty bad that Drupal core, which is tough by default, can be exploited in such a simple manner. I understand that it's not Drupal issue, but Microsoft isn't going to fix it. Instead, they suggest to send X-Content-Type-Options: nosniff HTTP response header. But, it's not possible to do this in Drupal and Drupal Security Team didn't fix it for 2 years and won't do this in future. So, if you are aware of your users' safety, remove .txt from allowed tags. You can do this in Administer -> Site configuration -> File uploads.


SafeClick - protect your Drupal site from Clickjacking

SafeClick is released. It is a module for Drupal CMS, which you gotta have to defense your website from Clickjacking. It implements several techniques of such defenses.

Opportunity of setting X-Frame-Options HTTP header. You may set it up to SameOrigin to allow framing of website within its domain or to DENY to prevent framing at all. Or you may disable it. This header is currently supported by Mozilla Firefox + NoScript extension, Apple Safari, Google Chrome and Microsoft Internet Explorer 8, so it's the safest way for your website.  

JavaScript + CSS + <noscript> framebusting. It's the hardest defense for your website, however it can break down some of your modules which use iframes. The disadvantage of usual framebusters is that they can be disabled particularly using IE8 or Safari XSS filter  This framebuster, pointed to me by sirdarckcat, excludes such kind of attack. If user disables framebuster script selectively - he sees blank screen. If user has generally disabled JavaScript - he sees message like "Enable JavaScript". However, I've decided to make <noscript> tag as a separate option, because such option may be useful without framebuster itself. 

Opportunity of decreasing the risk of Clickjacking on your site via overridden styles of <iframe>, <frame>, <object> and <embed> tags. This option should only be enabled if you allow your users to post content with stated tags. Special CSS overrides opacity level and z-index for them, preventing transparent frames and hidden via z-index frames. Also, z-index is useful for prevention of "last loaded - first focused" behavior (when last loaded frame is being focused regardless its z-index). The reverse is that in theory it may break website layout.
    Module is released and I hope it will be useful for Drupal users. Thanks to all slackers for helping me with Clickjacking prevention techniques.
    You may download module there.


    SafeClick Testing & Review

    After long discussion about methods of Clickjacking prevention, I've released for testing and reviewing SafeClick. It is a module for Drupal CMS which implements several of such techniques.
    The first is an implementation of  X-Frame-Options HTTP header.
    The second is JavaScript + CSS + <NoScript> hack, pointed to me by sirdarckcat - thanks to him!
    The third is special CSS, which can be useful if a website allows users to post frames within their content. It overrides opacity and z-index of HTML elements, used for Clickjacking attacks.
    Module is currently being reviewed by Drupal community. Everyone is welcomed for testing and hacking!