tag 528938 patch thanks Hi,
Taking a look at this long standing security and RC bug, attached is my proposed patch for the sid issue. A 255^255 session id should be good enough. Cc'ing the stable security team as I would some input from them. As mentioned by Florian on IRC there's a bug on some browsers that could let other websites predict the sequence of Math.random(). On unstable the cryptojs library from stanford could be packaged and used to generate a session id with the Fortuna-based PRNG (which is of course not shared between websites, therefore safe from the Math.random() attacks), but that can't be done on neither stable nor oldstable. And FWIW, I think that a larger and more random sid is better than the week and poor currently being generated. The patch needs some testing (mostly on the per-user sessions limit part), though. Cheers, -- Raphael Geissert - Debian Developer www.debian.org - get.debian.net
diff -urpN ajaxterm-0.10-4.orig/ajaxterm.js ajaxterm-0.10-4/ajaxterm.js --- ajaxterm-0.10-4.orig/ajaxterm.js 2006-10-28 21:52:39.000000000 -0500 +++ ajaxterm-0.10-4/ajaxterm.js 2009-10-09 11:42:33.000000000 -0500 @@ -3,7 +3,23 @@ ajaxterm.Terminal_ctor=function(id,width var ie=0; if(window.ActiveXObject) ie=1; - var sid=""+Math.round(Math.random()*1000000000); + var sid=""; + + for (var i=0; i < 255; i++) { + var r = 0; + // now get a random number between 0 and 255 + // numbers not in the range are intentionally discarded + // as it reduces the chance of predicting the seed, by not + // using all of the numbers generated by the PRNG + do { + r = Math.round(Math.random()*1000); + } while(r >= 255); + r = r.toString(16); + if (r.length == 1) + r = "0"+r; + sid += "%" + r; + } + var query0="s="+sid+"&w="+width+"&h="+height; var query1=query0+"&c=1&k="; var buf=""; diff -urpN ajaxterm-0.10-4.orig/ajaxterm.py ajaxterm-0.10-4/ajaxterm.py --- ajaxterm-0.10-4.orig/ajaxterm.py 2006-10-28 21:52:39.000000000 -0500 +++ ajaxterm-0.10-4/ajaxterm.py 2009-10-09 14:34:35.000000000 -0500 @@ -483,6 +483,9 @@ class AjaxTerm: self.mime['.html']= 'text/html; charset=UTF-8' self.multi = Multiplex(cmd) self.session = {} + self.session_ip = {} + self.sessions_limit = 20 + self.sessions_user_limit = 2 def __call__(self, environ, start_response): req = qweb.QWebRequest(environ, start_response,session=None) if req.PATH_INFO.endswith('/u'): @@ -491,12 +494,23 @@ class AjaxTerm: c=req.REQUEST["c"] w=req.REQUEST.int("w") h=req.REQUEST.int("h") + ip="unknown" + if environ.has_key("REMOTE_ADDR"): + ip=environ["REMOTE_ADDR"] if s in self.session: term=self.session[s] else: if not (w>2 and w<256 and h>2 and h<100): w,h=80,25 - term=self.session[s]=self.multi.create(w,h) + # check if there aren't too many open sessions + if len(self.session) < self.sessions_limit: + count=0 + for i in self.session_ip.keys(): + if self.session_ip[i] == ip: + count+=1 + if count <= self.sessions_user_limit: + term=self.session[s]=self.multi.create(w,h) + self.session_ip[s]=ip if k: self.multi.proc_write(term,k) time.sleep(0.002) @@ -507,6 +521,7 @@ class AjaxTerm: req.response_gzencode=1 else: del self.session[s] + del self.session_ip[s] req.write('<?xml version="1.0"?><idem></idem>') # print "sessions %r"%self.session else: