5th Feb 2003 [SBWID-5973]
COMMAND
	Opera mutiple vulnerabilities
SYSTEMS AFFECTED
	Opera 7
PROBLEM
	Thanks to GreyMagic Software security advisories :
	
	 [GM#002-OP] http://security.greymagic.com/adv/gm002-op/
	 " Many thanks to Tom Gilder for his excellent help in researching this
	   vulnerability. "
	 - And -
	 [GM#003-OP] http://security.greymagic.com/adv/gm003-op/
	 [GM#004-OP] http://security.greymagic.com/adv/gm004-op/
	 [GM#005-OP] http://security.greymagic.com/adv/gm005-op/
	 [GM#006-OP] http://security.greymagic.com/adv/gm006-op/
	
	
	   Problem 1 [GM#002-OP]
	 =========================
	
	Version 7 brings many long-awaited features such as proper  DOM  support
	and  an  improved  rendering  engine.  However,  Opera  seems  to   have
	neglected one of the most important aspects in any  browser  today,  its
	default cross-domain security model.
	 Discussion: 
	 ===========
	All browsers with Javascript  support  deploy  a  cross-domain  security
	model, which, in essence, attempts to prevent documents from one  domain
	to access other documents in different domains.
	Opera 7 deployed a  fundamentally  different  approach  to  cross-domain
	security, a caller-based  model,  rather  than  the  origin-based  model
	deployed in other browsers. The  vulnerability  is  comprised  of  three
	different flaws in that model:
	
	* Functions in different domains can be accessed and executed. 
	* Functions are being executed under the caller's domain credentials and not
	in their originating domain. 
	* It is possible to override properties and methods (both native and user-defined) in other windows. 
	
	The first flaw means that a window in one  domain  is  able  to  execute
	functions in a window that's in a different domain. This flaw in  itself
	is not a big threat because of the second flaw, which  means  that  even
	if a function in the victim window is executed, it is executed with  the
	attacker's credentials, and therefore  unable  to  access  the  victim's
	document.
	The second flaw means that  if  the  attacker  can  get  the  victim  to
	execute a function, it will run  under  the  victim's  credentials.  And
	because of the first flaw, the victim will have no problems accessing  a
	malicious function created by the attacker.
	The third, and most devastating flaw means that the attacker is able  to
	trojanize native methods in the victim window  with  his  own  code  and
	simply wait for the victim to execute it.
	With these three flaws combined, it becomes extremely  easy  to  exploit
	any document that uses some scripting, including local resources in  the
	file:// protocol. Being able to access local resources  in  Opera  means
	that the attacker would be able to:
	
	* Read any file on the user's file system. 
	* Read the contents of directories on the user's file system. 
	* Read emails written or received by M2, Opera's mail program. 
	* And more... 
	
	 Exploit: 
	 ========
	A perfect candidate for exploitation is Opera's own Javascript  console,
	which  arrives  in  the  form  of  three  separate  files   in   Opera's
	installation directory.
	The file "console.html" makes a very early call  to  the  native  method
	"setInterval", which can be overridden  by  an  attacking  window.  This
	scenario does not require any user interaction.
	
	<script language="jscript">
	var oWin=open("file://localhost/console.html","","");
	oWin.setInterval=function () { 
	    alert("Access to local resource achieved: "+oWin.location.href);
	}
	</script>
	
	The "file://localhost/" URL appearing in this  sample  is  a  convenient
	method provided by Opera in  order  to  access  the  selected  directory
	(Opera's home by default).
	 Demonstration:
	 ==============
	We put together two proof-of-concept demonstrations:
	
	* Simple: Reads cookies from a few well-known sites and demonstrates access
	to a local resource. 
	* GreyMagic Opera Disk Explorer: Browse your entire file system using this
	explorer-like tool, which takes advantage of this vulnerability in order to
	access local resources. 
	
	They can both be found at http://security.greymagic.com/adv/gm002-op/.
	
	   Problem 2 [GM#003-OP]
	 =========================
	
	Version 7 brings many long-awaited features such as proper  DOM  support
	and an improved rendering engine. Among the useful  new  features  Opera
	added a shiny new Javascript console. The  console  is  mainly  used  by
	developers in order to efficiently  track  down  exceptions  in  running
	scripts.
	 Discussion: 
	 ===========
	Opera's Javascript  console  is  using  three  html  files  residing  in
	Opera's  installation  directory.  The  most  important   of   them   is
	"console.html", which contains all the logic behind the console.
	The console lists unhandled exceptions that are thrown during  the  life
	of a session. Javascript can throw custom exceptions using  the  "throw"
	statement and Opera also adds its own way to create debug messages  with
	the "opera.postError" method.
	In order to display clickable URLs properly, Opera does some  formatting
	on the thrown exception message to turn them into links:
	
	newmsg = msg.replace( /</g, "<" ).
	       replace( />/g, ">" ).
	       replace( /https?:\/\/\S+/g, create_link ).
	       replace( /file:\/\/(?:\S|(?:[ ](?=[^\n\r]*\.)))+/g, create_link );
	
	The first two lines supposedly handle the safety of this string,  so  it
	wouldn't contain HTML.  The  last  two  lines  are  meant  to  transform
	strings that appear like URLs into actual links. Unfortunately, each  of
	these last two lines contains an obvious way for an attacker  to  inject
	his own attributes to the link. By  doing  so,  the  attacker  can  gain
	access to the file:// protocol, which, among others, have the  following
	implications:
	
	* Read any file on the user's file system. 
	* Read the contents of directories on the user's file system. 
	* Read emails written or received by M2, Opera's mail program. 
	
	The first  vulnerable  regular  expression  is  /https?:\/\/\S+/g,  it's
	trying to match anything  starting  with  "http://"  or  "https://"  and
	keeps consuming characters as  long  as  they  aren't  whitespace.  This
	regular expression does not check for the  existence  of  quotes,  which
	are the delimiters of the "href" attribute in the  resulting  link,  and
	therefore opens up a way to add additional  attributes  (spaces  between
	attributes are not mandatory).
	The  second  vulnerable  regular  expression   is   /file:\/\/(?:\S|(?:[
	](?=[^\n\r]*\.)))+/g,  it's  trying  to  match  anything  starting  with
	"file://" followed by a non-whitespace character or a regular space,  as
	long as a dot appears and no line  breaks  appear  after  it.  The  same
	mistake is made again; quotes can be used to add  additional  attributes
	to the link.
	Being able to add arbitrary attributes to a link may seem innocent,  but
	with a little manipulation  it  leads  to  the  execution  of  arbitrary
	script code. The "style" attribute in most elements,  for  example,  may
	contain properties such as "background-image", which normally  point  to
	a URL. That URL can be "javascript:[code]", which will  be  executed  in
	the context of the console (file:// protocol).
	 Exploit: 
	 ========
	A simple exploit of the first regular expression:
	
	open("file://localhost/console.html","","");
	opera.postError("http://\"style=\"background-image:url('javascript:alert(location.href)')\"");
	
	A simple exploit of the second regular expression:
	
	open("file://localhost/console.html","","");
	opera.postError("file://\"style=\"background-image:url('javascript:alert(location.href)')\".");
	
	 Demonstration:
	 ==============
	We put together two proof-of-concept demonstrations:
	
	* Simple: Demonstrates how the poisonous debug message is being inserted. 
	* GreyMagic Opera Disk Explorer: Browse your entire file system using this
	explorer-like tool, which takes advantage of this vulnerability in order to
	access local resources. 
	
	They can both be found at http://security.greymagic.com/adv/gm003-op/.
	
	   Problem 3 [GM#004-OP]
	 =========================
	
	Opera 7, just like any other browser, supports a considerable amount  of
	image formats. Images are normally embedded in HTML documents  but  they
	can also be accessed directly via the browser.
	 Discussion: 
	 ===========
	By examining the HTML Opera produces when it displays  a  single  image,
	it becomes obvious that Opera doesn't bother to  do  any  formatting  on
	the provided URL.  Luckily  though,  Opera  automatically  encodes  most
	characters in the URL, so access to other domains via this flaw  becomes
	impossible.
	However, URLs to local files (file:// protocol) do not get  encoded  and
	therefore cannot evade the very basic form of XSS:
	
	 file://path/to/image.jpg?">Arbitrary HTML here. 
	
	And to make this even more comfortable for attackers, Opera provided  an
	easy   way   to   refer   to   its   own   installation   directory    -
	file://localhost/. So instead of searching for  default  images  in  the
	OS, an attacker can simply  refer  to  file://localhost/images/file.gif,
	one of the few images Opera ships by default, and  enjoy  the  following
	abilities:
	
	* Read any file on the user's file system. 
	* Read the contents of directories on the user's file system. 
	* Read emails written or received by M2, Opera's mail program. 
	* And more... 
	
	Note: the same applies to embeddable media, such as SWF.
	 Exploit: 
	 ========
	
	open("file://localhost/images/file.gif?\"><script>alert(location.href);</script>","",""); 
	
	 Demonstration:
	 ==============
	We put together two proof-of-concept demonstrations:
	
	* Simple: Demonstrates how a single local image can be exploited. 
	* GreyMagic Opera Disk Explorer: Browse your entire file system using this
	explorer-like tool, which takes advantage of this vulnerability in order to
	access local resources. 
	
	They can both be found at http://security.greymagic.com/adv/gm004-op/.
	
	   Problem 4 [GM#005-OP]
	 =========================
	
	Like any other browser,  Opera  supports  the  "history"  object,  which
	makes it possible to navigate through the browser  history  by  exposing
	the "back", "forward", and "go" methods.
	 Discussion: 
	 ===========
	Opera exposed a little more than a few methods on  the  history  object.
	It also exposes  two  properties,  "next"  and  "previous".  Unlike  the
	methods mentioned above, these properties contain actual URLs.
	This means that when a user  navigates  to  a  website,  the  owner  can
	easily check and log where the user had last been,  and  even  where  he
	went  right  afterwards  (in  case  the  user  goes  back  in  history),
	regardless of whether that previous URL  referred  to  the  owner's  web
	site or not.
	Notice that "history.previous" is not the  same  as  the  "HTTP_REFERER"
	header. It will return the last URL  even  if  it  was  not  the  direct
	referrer to the  current  URL,  which  makes  Opera's  "Enable  referrer
	logging" configuration option completely pointless.
	That's  a  serious  breach  of  privacy,  which  Opera  seemed  to  have
	implemented intentionally.
	 Exploit: 
	 ========
	The following code demonstrates how to retrieve these properties:
	
	alert("Last URL: "+history.previous+".\nNext URL: "+history.next+"."); 
	
	 Demonstration:
	 ==============
	A proof-of-concept demonstration of this issue is available at
	
	 http://security.greymagic.com/adv/gm005-op/.
	
	
	   Problem 5 [GM#006-OP]
	 =========================
	
	The new browser features a very useful Javascript console, which uses  a
	few methods Opera implemented in the "opera" object.
	 Discussion: 
	 ===========
	These methods appear in the  comments  of  the  "console.html"  file  as
	follows:
	
	* opera.errorIndex():
	
	Returns  the  index  of  the  last  error   message.   This   index   is
	monotonically increasing (which limits  us  to  about  2^53  errors  per
	Opera session).
	
	* opera.errorMessage(i):
	
	Returns the error message at index i. The value returned may be  #f,  if
	that message has been flushed from the cache.
	Opera hadn't bothered to restrict these methods to  certain  credentials
	and they are available for any web page to use.  At  first  glance  this
	doesn't appear to  be  a  big  deal,  but  a  short  inspection  of  the
	generated error messages reveals that each  of  them  contains  the  URL
	that threw the exception.
	In practice, this means that a web page can extract a list of  all  URLs
	the user had visited and that threw  any  exceptions.  And  since  Opera
	pretends to be Internet Explorer by default, it often encounters  errors
	in web pages. Harvesting visited URLs had never been this simple.
	 Exploit: 
	 ========
	The following code will generate a list of visited URLs:
	
	var sMsg,
	    sFinal="",
	    iLen=opera.errorIndex();
	for (var iErr=0;iErr<iLen;iErr++) {
	    sMsg=opera.errorMessage(iErr);
	    if (sMsg && /(https?:\/\/\S+)/i.test(sMsg)) sFinal+=RegExp.$1+"\n";
	}
	alert(sFinal);
	
	 Demonstration:
	 ==============
	A proof-of-concept demonstration of this issue is available at
	
	 http://security.greymagic.com/adv/gm006-op/.
	
SOLUTION
	
	   Solution 1 [GM#002-OP]
	 =========================
	
	Opera was notified of a variation of  this  issue  on  14-Nov-2002,  but
	appareantly failed to understand the core issues and  only  patched  one
	symptom of the problem (it was possible for foreign  windows  to  simply
	set event handlers in Beta 1).
	In the meantime, until a patch becomes available, disable Javascript  by
	going to: File -> Preferences -> Multimedia,  and  uncheck  the  "Enable
	JavaScript" item.
	
	   Solution 2 [GM#003-OP]
	 =========================
	
	Fortunately, this vulnerability can be solved manually:
	* Edit the file "console.html", which resides  in  Opera's  installation
	directory.
	* Line 52 should read: m.replace( /\\/g, "\\\\" ) +
	* Replace it with: m.replace( /\\/g, "\\\\" ).replace(/"/g,""") +
	
	   Solution 3 [GM#004-OP]
	 =========================
	
	Until a patch becomes available, disable Javascript by  going  to:  File
	-> Preferences -> Multimedia, and uncheck the "Enable JavaScript" item.
	
	   Solution 4 [GM#005-OP]
	 =========================
	
	Hopefully, Opera will reconsider these properties and remove  them  from
	the history object. Until then you may prefer to disable  Javascript  by
	going to: File -> Preferences -> Multimedia,  and  uncheck  the  "Enable
	JavaScript" item.
	
	   Solution 5 [GM#006-OP]
	 =========================
	
	Until a patch becomes available, disable Javascript by  going  to:  File
	-> Preferences -> Multimedia, and uncheck the "Enable JavaScript" item.
	 Update (06 February 2003)
	 ======
	Opera  7.01  is  out  already,  fixing  the  vulnerabilities   GreyMagic
	reported.