Upload
carlo-bonamico
View
644
Download
3
Tags:
Embed Size (px)
Citation preview
@carlobonamico#devoxxuk
Web Application Security Reloaded for the HTML5 era
Carlo Bonamico @carlobonamico [email protected]
http://www.nispro.it
Designing and implementing secure Single Page Applicationshttps://wall-simple.sli.do/#/event/cmnxxfl0/section/18289/questions
@carlobonamico#devoxxuk
About meSpeaker Bio
– passionate software developer since the C128 era– PhD and research at the University of Genova / CNIT National TLC
Research Consortium – exciting time at startup Eptamedia– now a Solution Architect and Senior Trainer at NIS s.r.l.
between Italy and new London office
Current projects & interests – training/mentoring teams on AngularJS, Web Security, Continuous
Integration & Delivery– creating component-based Angular applications– security reviews and assessments
@carlobonamico#devoxxuk
AbstractTen years after the first OWASP Top Ten list of Web Application Security risks has been published, the basics of protecting a typical JEE/Rails/PHP/.NET, webapp are becoming mainstream knowledge (although never enough, as the endless series of high profile vulerabilities demonstates).
But the industry-wide move towards HTML5 and Single Page Applications, motivated by the opportunity for more sophisticated interaction and UX, is again upsetting the balance between Hackers and Developers. A wave of new-generation front-end technologies such as Web Components, AngularJS and Ember is Developers are attracting Developers with their combination of productivity and innovative UX, but at the same time opens the door to new vulnerabilities and security challenges.
This talk will summarize the main principles of Secure Coding, and will discuss their application to HTML5 applications that interact with REST or WebSocket backends to prevent major risks (including OWASP Top Ten).
A concrete example will demonstrate the use of tools and libraries, from RBAC to JWT, from Spring Security to AngularJS modules for implementing secure HTML5/JS apps.
@carlobonamico#devoxxuk
Evolution of Application SecurityWhen I taught my first Web Application Security training
– most participants had never heard of SQL Injection and XSS
Thanks to many industry and community players (especially OWASP),– not to mention many high-profile incidents,
things have started to change... Application Security
Ensuring Application guarantees
•Confidentiality•Integrity•Availability•Accountability
of the Information it processes
@carlobonamico#devoxxuk
Are we doing better? It's 2015... we were promised flying cars... and what we got is...
See also– http://www.cvedetails.com/vulnerabilities-by-types.php – https://www.whitehatsec.com/resource/stats.html
@carlobonamico#devoxxuk
Enter HTML5After years of playing catch-up with Desktop, the Web is now often the default development target
– powerful APIs– interactivity– always up-to-date & cross-platform
the mobile web just adds more push to that
=> the rise of the Single Page Application
Somewhat ill-defined term, but you know what I mean– HTML templates, statically served– client retrieves data from REST services / websockets– views dynamically rendered on the client side
@carlobonamico#devoxxuk
HTML5 appsDefinitely more powerful that traditional request-response webapps
also more secure?
@carlobonamico#devoxxuk
First problemSpiderman's Uncle Ben version:With great power comes great responsibility...
The Web Application Security version:With great power come more holes and greater risks!
– increased Surface of Attack Websockets, storage, apis...
– https://html5sec.org/ – http://html5security.org/
– and once you penetrate the browser, you can do basically everything
and I mean it: calling APIs, install keyloggers, redirect user behaviour, capture private data
–http://xenotix.in/
“most attack were already possible... but they are more powerful now”
http://w3af.org/understanding-html5-security
@carlobonamico#devoxxuk
Second problemWe are undergoing a wide architectural shift from
To
So many security assumptions do not hold true anymore!
ServerPOST params
HTML
Browser
Form-based input
HTML rendering
HTML templating
Controllers,Interaction
LogicBusiness Logic
ServerPOST JSON
JSON
Browser
HTML rendering
HTML templating
Business Logic
Interaction Logic
REST endpoints
@carlobonamico#devoxxuk
The good sideThe typical modern HTML5 application architecture has a single/main advantage:
it forces at the very least a basic degree of separation between UI and business logic
– even more so with Angular, Ember, React
In our consulting/project/problem solving experience, the single biggest cause of
– quality – performance– security
problems is....
@carlobonamico#devoxxuk
The good sideThe typical modern HTML5 application architecture has a single/main advantage:
it forces at the very least a basic degree of separation between UI and business logic
– even more so with Angular, Ember, React
In our consulting/project/problem solving experience, the single biggest cause of
– quality – performance– security
problems is.... the mixing & coupling of UI and business logic
@carlobonamico#devoxxuk
There's hope...If we properly understand the new architectural paradigm, we can turn it into an advantage
Follow the principles of secure coding
– Do not trust inputs– Minimize attack surface area
(and window of opportunity)– Establish secure defaults– Principle of Least privilege– Principle of Defense in depth– Fail securely– Don’t trust services– Separation of duties (vs
configuration)– Avoid security by obscurity– Keep security simple– Fix security issues correctly
@carlobonamico#devoxxuk
Top Ten Web Application Risks
– A1-Injection– A2-Broken Authentication and Session Management– A3-Cross-Site Scripting (XSS)– A4-Insecure Direct Object References– A5-Security Misconfiguration– A6-Sensitive Data Exposure– A7-Missing Function Level Access Control– A8-Cross-Site Request Forgery (CSRF)– A9-Using Components with Known Vulnerabilities– A10-Unvalidated Redirects and Forwards
What's different between Request/Response apps and HTML5/SPAs?
@carlobonamico#devoxxuk
What changes with HTML5/SPAs? RED → more critical ORANGE → different solution GREEN → easier
– A1-Injection → same problem, same solution– A2-Broken Authentication and Session Management– A3-Cross-Site Scripting (XSS)– A4-Insecure Direct Object References– A5-Security Misconfiguration– A6-Sensitive Data Exposure– A7-Missing Function Level Access Control– A8-Cross-Site Request Forgery (CSRF)– A9-Using Components with Known Vulnerabilities – A10-Unvalidated Redirects and Forwards
We will focus on those!
@carlobonamico#devoxxuk
A3 - XSSCross-Site-Scripting means that attacker can insert custom js code which is then displayed in the user browser
– stored (input js in a field → DB → sent back to the page)– reflected (input js in the url, send the url to a user, js executed)– DOM-based (input triggers js logic that manipulates the DOM and
insert custom js)
Remember: any external input is UNTRUSTED! – so we must avoid mixing user input with js code
@carlobonamico#devoxxuk
A3 – Preventing XSSLooks easy: but HTML allows for multiple mixed execution contexts:
– JS within CSS within HTML within a frame of another HTML …
The proper solution is ESCAPING: encoding the data so that the browser properly interprets it as plain text (and not js)
– https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
In a well designed SPA, – clear inputs paths
REST service responses, user inputs, url bar, ...– HTML generation through the framework templating engine – so it is easier to intercept and escape outputs
@carlobonamico#devoxxuk
A3 – Preventing XSS with AngularSince 1.3, the HTML compiler will escape all {{}} & ngbind by default
– https://www.ng-book.com/p/Security – http://java.dzone.com/articles/angularjs-how-handle-xss
Be careful if you must include user-generated HTML (e.g. in rich text editors)– take advantage of the services and directives– ngbindhtml (from angular-sanitize)
print as is removing “script” tags (beware of img tags) fully customizable with
–$sceProvider & $SanitizeProvider– https://docs.angularjs.org/guide/security
Please note: – escaping in the REST services is not always feasible/useful– they can be consumed by mobile Apps and other clients
@carlobonamico#devoxxuk
More Angular-specific guidelinesFurther suggesions:
– prefer model-based logic– avoid mixing client side and server side templating– clear template / data separation– avoid dynamically generating templates from user input– do not run input in $eval
@carlobonamico#devoxxuk
A3 – XSS - ToolsStatic Code Analysis for DOM-based and reflected XSS
– Mozilla ScanJS https://github.com/mozilla/scanjs
– JSPRime https://github.com/dpnishant/jsprime
More references– https://blog.nvisium.com/2014/06/javascript-security-tools.html
@carlobonamico#devoxxuk
RememberMost vulnerabilities are not so serious by themselves
– but became terrible if mixed think Pepsi + Mentos
XSS is an enabler for – phishing– browser-based MITM– session / auth token stealing– sensitive data extraction
– img courtesy of http://www.delawaretoday.com/
@carlobonamico#devoxxuk
Securing cookiesIf your cookie is stolen
– via Cross-Site-Scripting, interception, ...attacker is granted access to the session
At the very least– always use HTTPS / TLS– set secure flag– set HTTPOnly flag
Also, do not store sensitive data in clear in localStorage / sessionStorage indexDB
@carlobonamico#devoxxuk
A5 – Security misconfigurationA single MITM (Man in the Middle) and your “done”
– as the attacker can put arbitrary code in your browser– so,
https://www.eff.org/Https-everywhere
Be careful with CORS– Avoid AllowOrigin “*” unless you have very strong authentication
and authorization
Remember to tell the browser to enable stronger protection– typically through headers such as CSP– https://www.owasp.org/index.php/List_of_useful_HTTP_headers
@carlobonamico#devoxxuk
Securing HeadersNode
– https://www.npmjs.com/package/helmet
Java (Spring Security)– http://docs.spring.io/autorepo/docs/spring-security/current/reference/html/headers.
html
Test tools– security headers online
https://securityheaders.com/
– OWASP ZAP https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project
@carlobonamico#devoxxuk
What is AuthenticationVerifying the user identity
– independently from his profile / authorizations
Several elements: – where valid users are listed (Realm)
internal, file, DB, LDAP, Active Directory, SSO Server– what info is used to establish user identity
one or more “factors”: username, password, OTP, certificate...– how identity is checked the first time
login → credentials validation– how identity is checked on subsequent requests
validation
@carlobonamico#devoxxuk
Traditional Request-Response Applications
e.g. JSP / ASP / PHP– login page– successful login creates a session– protected pages accessed within the session– data and access control filtered on the server side
often within views or controllers
Browser
Server
POST Login Data
GET secured page
SESSIONID = 5
SESSIONID = 5 auth =
true?
credentials valid?
Realm
filteredHTMLpage
SID AUTH DATA
5 true carlo,admin
@carlobonamico#devoxxuk
Issues with Cookie + Session Authentication
Authentication requires – checking credentials against a realm– keeping auth in session state on the server– sessionid sent in a cookie
Issues– state replication in clustered servers vs sticky sessions
Single-Sign-On across servers?– More complex scenarios are possible
e.g. SSO Server, like CAS– typically cookie based →
all server must be in same domain
Remember:
Cookies are sent with ANY request
to the same domain(including images)
@carlobonamico#devoxxuk
Cookie-based authentication in Single Page Applications
Can't SPA just do the same?– login form POSTs to login service– successful login creates a session and sets a cookie– protected Pages & REST services accessed within the session
data and access control filtered … where ?
Browser
Server
POST Login Data
GET secured JSON
SESSIONID = 5
SID AUTH DATA
5 true carlo,adminSESSIONID = 5 auth
= true? {
...}
credentials valid?
Realm
@carlobonamico#devoxxuk
Authentication vs Session Management
Pros– simple to implement
Cons– not suited to stateless nature of REST services
Authentication vs Sessions– They are two different things, although often used together– REST services
tend to be stateless
Unauthenticated Authenticated
Stateless Plain HTTPe.g. Wikipedia
REST e.g. Google APIs
With Session Session cookiese.g. Amazon
JSP/ASP/PHPe.g. Intranet Apps
@carlobonamico#devoxxuk
Token-based Authentication Login establishes a valid token
– each request must be presented with the token– the server can check token validity at each request– https://auth0.com/blog/2014/01/07/angularjs-authentication-with-
cookies-vs-token/
Browser
Server
POST Login Data
GET secured JSON
TOKEN = 5
TOKEN = 5 token valid?
credentials valid?
Realm
no session!
@carlobonamico#devoxxuk
IssuesGiven a token
– how do you know which is the current user?
On the server– how expensive it is to check the token at each request?
Can you share a token across services? – can you validate it without connecting to a DB / SSO Server?
@carlobonamico#devoxxuk
Creating and Validating TokensSimplest way: checking them against a list of valid tokens
– in memory → similar to session-based auth replication problems
– on a DB easier clustering, must consider performance
– on an external server SSO for free, must evaluate performance & complexity
@carlobonamico#devoxxuk
JWT - http://jwt.io JWT = encoded & signed Json object containing
– Access token– Claims (custom: session, domain, username...)– Expiration– and Digital Signature! → verifiable with just the public key
Returned by login REST serviceSent as header at each request
–Authentication: bearer eyJhbGciO .eyJzdWIiOWV9.eoaDV
Checked by REST backed at each request– can also be used with websockets
{“user”:”carlo”,“domain”:”NIS”,“expiry”: ..}
@carlobonamico#devoxxuk
JWT in angularAngular Library
– https://github.com/auth0/angular-jwt
Extensible hooks for – storing and retrieving tokens on the client
Interceptors for– retrieving tokens from server Response Headers– optionally refresh tokens– automatically sending tokens at each request
Robust and simple to userbower install angularjwt
@carlobonamico#devoxxuk
Token-based Auth in AngularJsIngredientsREST endpoints
– /auth/login Input parameters: credentials Response: token
– /auth/logout Input parameters: token
$http or $resource based Client Service AuthenticationService
– login() logout() methods wrapping the above– plus isAuthenticated() and possibly currentUser()
@carlobonamico#devoxxuk
Token-based Auth in AngularJsIngredients
– Controller(s)– LoginController
bound to Login form, calls service– LogoutController– AuthenticationController
IsAuthenticated, currentUser
Possibly, Directives <authenticateduser> showWhenAuthenticated<menu showWhenAuthenticated=”true”>
@carlobonamico#devoxxuk
Authentication ClientPerform the request – Form based POST $http({ url: '/oauth2/token', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, transformRequest: function (obj) { var str = []; for (var p in obj) str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); return str.join("&"); }, data: { username: credentials.username, password: credentials.password, } })
@carlobonamico#devoxxuk
Authentication Client REST POST $http({ url: '/rest/auth/token', method: 'POST', data: { username: credentials.username, password: credentials.password, } })
@carlobonamico#devoxxuk
Saving the token In both cases, register a then() on the promise$http(...).then(function(response) { currentToken.jwt = response.data.access_token; }Store it locallyIf you need, parse ittokenPayload = jwtHelper.decodeToken(currentToken.jwt);date = jwtHelper.getTokenExpirationDate(currentToken.jwt);bool = jwtHelper.isTokenExpired(currentToken.jwt);
@carlobonamico#devoxxuk
Integrating with angular-jwt
Specify Token retrieval functionangular.module('myApp') .config(function Config($httpProvider, jwtInterceptorProvider) { jwtInterceptorProvider.tokenGetter = ['currentToken', function(currentToken) {return currentToken.jwt; //or return localStorage.getItem('id_token');}];Register interceptor $httpProvider.interceptors.push('jwtInterceptor');});
@carlobonamico#devoxxuk
Back-endLogin endpoint
– validates credentials– generates JWT
REST Service endpoints (or better interceptor)– extract Token from Authentication: header– validate it– proceed with request processing
or return error 401
Full example– http://thejackalofjavascript.com/architecting-a-restful-node-js-app/
@carlobonamico#devoxxuk
JWT in...Plain Node: Auth0 library
– https://github.com/auth0/node-jsonwebtokenExpress: Express JWT
– https://github.com/auth0/express-jwtPassport - Modular Auth Framework for node.js
– http://passportjs.org/.NET - OWIN.Identity
– http://bitoftech.net/2014/10/27/json-web-token-asp-net-web-api-2-jwt-owin-authorization-server/
Java - Spring Security – https://spring.io/guides/tutorials/spring-security-and-angular-
js/Integrating OAUTH with JWT
@carlobonamico#devoxxuk
Token Storage vs Session DurationIn memory or sessionStorage
– works only on current tab– automatically closed
In localStorage– persistent– work across multiple tabs– requires explicit expiration
https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/
@carlobonamico#devoxxuk
Sending Tokens - Cookies vs Headers
CookiesPros
– sent automatically– no code required on the client
Cons– sent automatically– even when do not want
e.g. <IMG src= in email– less control on validity– stored on client disk
HeadersPros
– sent only explicitely– not stored on disk– unless you want to– more control– also prevents CSRF
Cons
– require code on the client side– but this is normal in SPAs
https://auth0.com/blog/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies/
@carlobonamico#devoxxuk
What else would we need?what happens when the user is not logged in?
how to improve usability?
@carlobonamico#devoxxuk
Routing support for Authentication & Authorization
Need to configure Routing for– redirect to login if not authenticated– redirect to login if token expired– optionally, redirect back to original URL– redirect to error page if route not authorized in the current profile
Difficult to do in the default ngRoute– Possible in ui-router
Way easier in angular-new-router– https://medium.com/angularjs-meetup-south-london/angular-ng-
conf-2015-media-25dbe6250154
@carlobonamico#devoxxuk
CSRFSee section “Security Considerations” on
– https://docs.angularjs.org/api/ng/service/$http
Angular automatically manages CSRF-prevention tokens if you use cookies
The server needs to set a token – JavaScript readable session cookie called XSRF-TOKEN on the first HTTP GET request
On subsequent XHR requests – the server can verify that the cookie matches X-XSRF-TOKEN HTTP header– the token must be unique for each user and must be verifiable by the server
e.g. a digest of your site's authentication cookie with a salt for added security
Also, – Angular automatically supports JSONP-prevention characters
http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/
@carlobonamico#devoxxuk
Typical Server side application Authorization is verified
– in controllersif (user.hasRole(“admin”) == true)
– through filters / interceptors– in views
<hasRole role=”admin”> or <if (...)>confidential info
</hasRole>
Client Browser only receives content it has rights to– (roughly) works even if security checks are “spaghetti code” in the
JSP/ASP/PHP templates
@carlobonamico#devoxxuk
And in a SPA?Would this be secure?In users-view.html
<button ngif=”authCtrl.isAdmin” ngclick=”userCtrl.deleteUser()”>
or this?
<section ngif=”authCtrl.isAdmin” >{{userCtrl.user.confidentialData}}</section>
@carlobonamico#devoxxuk
No!
Just press F12
and modify the HTML / JS
or even the DOM in the developer tools
@carlobonamico#devoxxuk
Security is up to the serverEven in SPAs, Authorization is still up to the server:
Security controls– checking authentication state– checking profile and inferring permissions– enabling privileged actions– filtering confidential data
MUST be performed on the server– in the REST / websocket endpoints– locally in each service, or via filters/interceptors
Also, the same rule applies to input validation
@carlobonamico#devoxxuk
Usability is up to the clientBut letting the user click on the button, invoking the service, and only then displaying an error is not user friendly
UX is up to the client– Front-End should have enough info to disable/hide the button
if the user is not authorized to click it retrieve the permissions list from a REST service at logon
E.g. Permission check directives for Angular<button ngclick=”postCtrl.delete()” haspermission=”deletePost”>
permissions for Role-Based Access Control
@carlobonamico#devoxxuk
Checking the user profileSo, in each server endpoint, you should check
– valid authentication– valid authorization profile which includes privileges for the
currently requested action / dataExample Blog application
if (subject.hasRole(“admin”))//enable delete postif (subject.hasRole(“editor”))//enable modification of postelse//only read data
What are the problems
with this code?
@carlobonamico#devoxxuk
What if the rules change?
What if an auditor asks about what an “editor” can do?
Real-world cases tend to be more complex!
@carlobonamico#devoxxuk
Role Based Access ControlSeparating Role definition from Permission check
– In each service / action, code checks that the user has the relevant permission
if (subject.hasPermission(“deletePost”))– Role Definition lists all the permissions
e.g. –Admin detelePost, updatePost→–anonymous readPost→
Authorization system maps user/groups to list of roles– and computes the “merged” set of permissions active for the valid user
user is both Admin & Editor Permissions are
–changeSettings, deleteUser, addUser, deletePost, modifyPost
@carlobonamico#devoxxuk
Hierarchical permission system 2-level: User → Role → Permissions3-level: User → Groups → Roles → Permissions
Wildcard Permissions– blog:deletePost– blog:readPost– blog:* means both
blog:readPost:12 → entity level permission blog:readPost:* on all entities
see Apache Shiro
@carlobonamico#devoxxuk
AdvantagesPermission check is
– focused, readable – easy to implement– easy to test– rarely changes
Role definition is – centralized– easy to review– easy to change– as it tends to change often
Secure Design Principle
all parts of the system need to perform security
checks
but
security check implementation
should be centralized and not “spread” in the system
@carlobonamico#devoxxuk
RBAC in a Single Page Application Server-side Ingredients:
– Profile definition mapping Roles to Permissions static file db table possibly cached Identity server (e.g. OpenAM)
– API for checking permissions
Normally, some of this information is cached to ensure minimal performance penalty
@carlobonamico#devoxxuk
Usable Secure UI in AngularJSIngredients:
– /authorization/profile/current REST endpoint returns a Json current user roles merged list of all active permissions
On the Client– Client Service wrapping the above– Authorization/ProfileService storing the permission list
hasPermission(p) methodCall the service from
– Controller methods– Routing callbacks
@carlobonamico#devoxxuk
Component SecurityThe code we write
The code which actually runs in our application – libraries and components
@carlobonamico#devoxxuk
Checking dependecies for vulnsOn the client side
– http://retirejs.github.io/retire.js/npm install g retire ; retire –path src
– also available as ZAP & mvn pluginmvn com.h3xstream.retirejs:retirejsmavenplugin:scan
On the server side– OWASP Dependency Check
https://github.com/jeremylong/DependencyCheck dependencycheck.sh app Testing out . scan [path to jar files to be scanned]mvn org.owasp:dependencycheckmaven
@YourTwitterHandle#DVXFR14{session hashtag} @carlobonamico#devoxxuk
A fna
l
wor
d...
But isn't all that unnecessary complexityslowing down development of my critical project?
@carlobonamico#devoxxuk
A final wordPeople tend to view Security as “overhead”, not adding value to the project
The reality: – if you know what to pay attention to, minimal additional costs– also, in most cases, adding security just means following good design principles
if you separate well concerns, adding security is easy – favor clarity of intent and code readability– favor composition over inheritance– test, test, test!
incorporate security checks in your tests
This lets software adapt more easily to both requirements & security changes – easier to evolve incrementally & validating each step → see Continuous
Delivery
@carlobonamico#devoxxuk
ReferencesOwasp Secure Coding Principles
– https://www.owasp.org/index.php/Secure_Coding_Principles
OWASP Testing Guide– https://www.owasp.org/index.php/OWASP_Testing_Guide_v4_Table_
of_Contents
SOLID Design Principles– http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
@carlobonamico#devoxxuk
HTML5 SecurityAttack Vectors & Vulnerabilities
– https://media.blackhat.com/bh-eu-12/shah/bh-eu-12-Shah_HTML5_Top_10-WP.pdf
OWASP Guidelines– https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet
JS Frameworks Security– http://www.slideshare.net/x00mario/jsmvcomfg-to-sternly-look-at-
javascript-mvc-and-templating-frameworks
@carlobonamico#devoxxuk
Thank You for your attention Interested?
– attend our Web Application Security trainings– engage us for Design/Code Reviews, Vulnerability Assessments &
team mentoring
Read more on – http://www.nispro.it– http://www.slideshare.net/carlo.bonamico
Follow us on twitter– @nis_srl @carlobonamico
updates on Security, AngularJS, Continuous DeliveryContact me