Upload
nguyenxuyen
View
220
Download
0
Embed Size (px)
Citation preview
bull 1835 - Kick off Introduction
bull 1845 - Lithium REST API Context Objects
bull 1915 - Common Initialization
bull 1930 - BREAK
bull 1940 - Endpoints External API integration
bull 2020 - Customizations security aspects
bull 2030 - Updates from Lithium Developer Network - QampA
bull 2100 Wrap Up
Lithium Dev Meetup - Agenda
Please interrupt if there are questions or doubts
Complex questions will be answered in the dedicated QampA session at the end or during the break
Format
Lithium implementations showcase
Paolo Tagliaferri (Technical Consultant)
Lithium Customization framework
LITHIUM STUDIO - A rich tool to implement a personalized community experience
bull Unique Look and Feel
bull Tailored custom functionality amp features
KPNampCo Custom Blog
bull httpforumkpncomt54G-in-de-praktijkbg-pkpnco-4g
bull
bull Horizontal navigation with labels
bull Featured image and teaser
bull Client side loading for more articles
KPNampCo Custom Blog
bull Custom Article with hero
bull Highlighting author information and comments
bull Custom social sharing features
Sony Europe Landing Page
bull httpcommunitysonycouk
bull Custom Headers Footers
bull Featured articles
bull Customized board navigation
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Virgin Atlantic Destinations blog
bull httpblogvirgin-atlanticcom
bull Category based collections of blogs
bull Hero article
bull Tiled structure for featured articles
bull Metrics showcase (comments kudos shares)
Virgin Atlantic Destinations blog
bull Related articles
bull Author information and avatar
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Please interrupt if there are questions or doubts
Complex questions will be answered in the dedicated QampA session at the end or during the break
Format
Lithium implementations showcase
Paolo Tagliaferri (Technical Consultant)
Lithium Customization framework
LITHIUM STUDIO - A rich tool to implement a personalized community experience
bull Unique Look and Feel
bull Tailored custom functionality amp features
KPNampCo Custom Blog
bull httpforumkpncomt54G-in-de-praktijkbg-pkpnco-4g
bull
bull Horizontal navigation with labels
bull Featured image and teaser
bull Client side loading for more articles
KPNampCo Custom Blog
bull Custom Article with hero
bull Highlighting author information and comments
bull Custom social sharing features
Sony Europe Landing Page
bull httpcommunitysonycouk
bull Custom Headers Footers
bull Featured articles
bull Customized board navigation
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Virgin Atlantic Destinations blog
bull httpblogvirgin-atlanticcom
bull Category based collections of blogs
bull Hero article
bull Tiled structure for featured articles
bull Metrics showcase (comments kudos shares)
Virgin Atlantic Destinations blog
bull Related articles
bull Author information and avatar
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Lithium implementations showcase
Paolo Tagliaferri (Technical Consultant)
Lithium Customization framework
LITHIUM STUDIO - A rich tool to implement a personalized community experience
bull Unique Look and Feel
bull Tailored custom functionality amp features
KPNampCo Custom Blog
bull httpforumkpncomt54G-in-de-praktijkbg-pkpnco-4g
bull
bull Horizontal navigation with labels
bull Featured image and teaser
bull Client side loading for more articles
KPNampCo Custom Blog
bull Custom Article with hero
bull Highlighting author information and comments
bull Custom social sharing features
Sony Europe Landing Page
bull httpcommunitysonycouk
bull Custom Headers Footers
bull Featured articles
bull Customized board navigation
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Virgin Atlantic Destinations blog
bull httpblogvirgin-atlanticcom
bull Category based collections of blogs
bull Hero article
bull Tiled structure for featured articles
bull Metrics showcase (comments kudos shares)
Virgin Atlantic Destinations blog
bull Related articles
bull Author information and avatar
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Lithium Customization framework
LITHIUM STUDIO - A rich tool to implement a personalized community experience
bull Unique Look and Feel
bull Tailored custom functionality amp features
KPNampCo Custom Blog
bull httpforumkpncomt54G-in-de-praktijkbg-pkpnco-4g
bull
bull Horizontal navigation with labels
bull Featured image and teaser
bull Client side loading for more articles
KPNampCo Custom Blog
bull Custom Article with hero
bull Highlighting author information and comments
bull Custom social sharing features
Sony Europe Landing Page
bull httpcommunitysonycouk
bull Custom Headers Footers
bull Featured articles
bull Customized board navigation
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Virgin Atlantic Destinations blog
bull httpblogvirgin-atlanticcom
bull Category based collections of blogs
bull Hero article
bull Tiled structure for featured articles
bull Metrics showcase (comments kudos shares)
Virgin Atlantic Destinations blog
bull Related articles
bull Author information and avatar
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
KPNampCo Custom Blog
bull httpforumkpncomt54G-in-de-praktijkbg-pkpnco-4g
bull
bull Horizontal navigation with labels
bull Featured image and teaser
bull Client side loading for more articles
KPNampCo Custom Blog
bull Custom Article with hero
bull Highlighting author information and comments
bull Custom social sharing features
Sony Europe Landing Page
bull httpcommunitysonycouk
bull Custom Headers Footers
bull Featured articles
bull Customized board navigation
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Virgin Atlantic Destinations blog
bull httpblogvirgin-atlanticcom
bull Category based collections of blogs
bull Hero article
bull Tiled structure for featured articles
bull Metrics showcase (comments kudos shares)
Virgin Atlantic Destinations blog
bull Related articles
bull Author information and avatar
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
KPNampCo Custom Blog
bull Custom Article with hero
bull Highlighting author information and comments
bull Custom social sharing features
Sony Europe Landing Page
bull httpcommunitysonycouk
bull Custom Headers Footers
bull Featured articles
bull Customized board navigation
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Virgin Atlantic Destinations blog
bull httpblogvirgin-atlanticcom
bull Category based collections of blogs
bull Hero article
bull Tiled structure for featured articles
bull Metrics showcase (comments kudos shares)
Virgin Atlantic Destinations blog
bull Related articles
bull Author information and avatar
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Sony Europe Landing Page
bull httpcommunitysonycouk
bull Custom Headers Footers
bull Featured articles
bull Customized board navigation
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Virgin Atlantic Destinations blog
bull httpblogvirgin-atlanticcom
bull Category based collections of blogs
bull Hero article
bull Tiled structure for featured articles
bull Metrics showcase (comments kudos shares)
Virgin Atlantic Destinations blog
bull Related articles
bull Author information and avatar
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Virgin Atlantic Destinations blog
bull httpblogvirgin-atlanticcom
bull Category based collections of blogs
bull Hero article
bull Tiled structure for featured articles
bull Metrics showcase (comments kudos shares)
Virgin Atlantic Destinations blog
bull Related articles
bull Author information and avatar
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Virgin Atlantic Destinations blog
bull httpblogvirgin-atlanticcom
bull Category based collections of blogs
bull Hero article
bull Tiled structure for featured articles
bull Metrics showcase (comments kudos shares)
Virgin Atlantic Destinations blog
bull Related articles
bull Author information and avatar
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Sony Europe Photo Galleries
bull Gallery showcase in the homepage
bull Photo entry and photo navigation by label
bull Full screen slideshow
Virgin Atlantic Destinations blog
bull httpblogvirgin-atlanticcom
bull Category based collections of blogs
bull Hero article
bull Tiled structure for featured articles
bull Metrics showcase (comments kudos shares)
Virgin Atlantic Destinations blog
bull Related articles
bull Author information and avatar
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Virgin Atlantic Destinations blog
bull httpblogvirgin-atlanticcom
bull Category based collections of blogs
bull Hero article
bull Tiled structure for featured articles
bull Metrics showcase (comments kudos shares)
Virgin Atlantic Destinations blog
bull Related articles
bull Author information and avatar
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Virgin Atlantic Destinations blog
bull Related articles
bull Author information and avatar
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
bull Rest API
bull Lithium Context Objects
bull Common Initialization
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
FreeMarker REST and Other Context Object
A look at the powerful tools you can access through FreeMarker
Chiara Sannitz and Filip Klisic
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Querying the Community
How to get community data into your components
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Use when dealing with pages that represent lower level nodes in the community structure bull Category page
bull Forum page
bull etc
Note Most pages in the application are community level
Examples
CoreNode Context Object
$coreNodeid
ltassign nodeId = coreNodeidgt
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
CoreNode Context Object
ltassign nodetype = coreNodenodeType gt
ltif nodetype = communitygt
ltassign node = gt
ltelseif nodetype = categorygt
ltassign node = categoriesid + coreNodeid + gt
ltelseif nodetype = boardgt
ltassign node = blogsid + coreNodeid + gt
ltelsegt
ltassign node = gt
ltifgt
Lithosphere CoreNode Context Object
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Use on a page that represents either a message a user or a thread bull If a page represents a user you can get details about the user
bull My Profile Page bull User Profile Page
bull If a page represents a message you can get details about the message bull Message Page
bull If a page represents a thread you can get details about the thread bull Thread Page
Examples bull Verify the context object exists using if
bull ltif pagecontextthreadgtltifgt
bull $pagecontextthreadtopicMessageuniqueId
bull $pagecontextmessageuniq ueId
bull $pagecontextuserid
Lithosphere Page Context Object
Page Context Object
ltif pagecontextthreadgthellipltifgt
$pagecontextthreadtopicMessageuniqueId
$pagecontextmessageuniqueId
$pagecontextuserid
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
When you are on a page with a list of messages (such as the topic page) the env object can help to get the id of each message in the list bull Forum Message bull Idea Message bull Etc
Examples bull $envcontextmessageuniqueId
bull ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Lithosphere Env Context Object
Env Context Object
$envcontextmessageuniqueId
ltif envcontextmessageparentgt$envcontextmessageparentuniqueIdltifgt
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Used to render localized text strings
Examples bull $textformat(ldquogeneralKudosrdquo)
bull $textformat(ldquotextkeywithargumentsrdquo
ldquoarg1rdquoldquoarg2rdquo)
Lithosphere Localizable Text
Localizable Text
$textformat(ldquogeneralKudosrdquo)
$textformat(ldquotextkeywithargumentsrdquo ldquoarg1rdquoldquoarg2rdquo)
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Useful FreeMarker Directives
A look at useful directives that can be used in components and endpoints
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
ltmacrogt
A macro is a template fragment associated with a variable
You can use that variable in your template as a user-defined directive
Examples bull Definition
bull Usage
ltmacro greetgt
ltfont size=+2gtHello Joeltfontgt
ltmacrogt
ltgreetgt
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
ltfunctiongt
Creates a method variable and works like the macro but bull Must have a parameter that specifies the return value of the
method
bull Attempts to write to the output will be ignored
Examples bull Definition
bull Usage
ltfunction sum x ygt
ltreturn (x + y) gt
ltfunctiongt
$sum(10 20)
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
ltincludegt
Use it to insert another FreeMarker template file bull The output from the included template is inserted at the point
where the include tag occurs
bull The included file shares the variables with the including template similarly like if it was copy-pasted into it
bull Examples
ltinclude common_varftl gt
ltinclude macrosftl gt
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
ltimportgt
Imports a library and creates a new empty namespace
The template is executed to populate the namespace with variables (macros functions etc) and not to write to the output
Examples
ltimport user-macrosftl as userDisplay gt
ltuserDisplaydisplayUserAvatar userId=authorid gt
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Lithium FreeMarker Directives
A look at special directives that can be used in components and endpoints
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
The component directive allows you to insert components into other components bull You can pass parameters to a component using named parameters
bull
bull You can add parameters to your custom components
Examples
component
ltcomponent id=ldquoforumswidgetboard-browserrdquo gt
ltcomponent id=ldquomy_own_componentrdquo gt
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Modal directive is used to render a component inside of a modal window bull You will need to specify the following parameters
bull Id the id of the component you want to render inside the modal
bull Label The text to display on the link or button used to open the component
bull These are the only two parameters required but there are others you can use to further customize the modal
Example bull ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lithosphere Creating Modal Dialogs
modal
ltmodal id=ldquomy_component_idrdquo label=ldquomycomponentlabelrdquogt
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Lets you specify a block of JavaScript code in a component bull The JavaScript will be added to any page containing the component
bull The JavaScript will be added after all core JavaScript has run
bull For jQuery use LITHIUMjQuery
bull You can assign $ to LITHIUMjQuery as in the example
Example
liaAddScript
ltliaAddScriptgt
(function($)
your code here
)(LITHIUMjQuery)
ltliaAddScriptgt
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
REST
How to make and use REST calls in FreeMarker components and endpoints
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
The rest directive can be used to call the Lithium REST API bull REST calls return a W3CNode context object with the response from call bull If you compare the XML response in a browser to the W3CNode object the
bull
bull To get an attribute use sign bull To check if an attribute exists use nodeattribute[0]
bull To get nodes use Notation
Examples
REST
ltassign msg = rest(messagesid5)message gt
ltif msgboardhref[0]gt
$msgboardhref
ltifgt
ltlist restadmin(usersid$useridcroles)rolesrole as rolegt hellip ltlistgt
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Demo
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Calling External Services (how to call external services and use them in Freemarker)
Doug Schroeder (Developer LDN team)
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Endpoints Endpoints give you the ability to specify your own HTTP URL(s)
to serve community data from bull Could be a snippit of HTML
bull Could be a JSON response which combines calls to the Lithium REST API with other Lithium REST API calls or with calls to an external API
bull Could be XML CSV or Plain Text as well lt--render a JSON response that combines a couple Lithium REST API calls to give you more detailed information about a message author --gt
ltassign messageid = httprequestparametersnameget(ldquomessage_idrdquo)numberc gt
ltassign message = rest(ldquomessagesidrdquo + messageid)message gt
ltif messagegt
ltassign author = rest(messageauthorhref)user gt
ldquomessagerdquo
ldquoidrdquo ldquo$messageidrdquo ldquoauthorrdquo
ldquoidrdquo ldquo$authorid
ldquologinrdquo ldquo$authorloginrdquo
ltifgt
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Page Initialization Script The page initialization script lets you write Freemarker logic that runs early on in every request and gives you access to do things such as
bull Issue a redirect to another URL bull Change the skin that is being used just for the duration of the request bull Change the page quilt that is being used just for the duration of the request bull Make httpclient requests to grab data from other APIs (more on this in a bit)
lt--redirect all requests with anonymous users to a custom landing page named
custom-anonymous-user-landing-page Send registered users to the default community page--gt
ltif useranonymous ampamp pagename == CommunityPagegt
$httpresponsesetRedirectUrl(
webuisupporturlspagenameget(custom-anonymous-user-landing-page)
build())
ltelseif useranonymous ampamp pagename == custom-anonymous-user-landing-pagegt
$httpresponsesetRedirectUrl(communityurlsfrontPage)
ltifgt
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Page Initialization Script There are some common ways you can ldquoshoot yourself in the footrdquo
bull Add logic that always redirects to another URL now you canrsquot get back to your community to stop it from redirecting
bull Change the page skin or quilt to something that breaks the page but yoursquove written the logic so it does this for any request to any page
lt-- Dont do this --gt
$httpresponsesetRedirect(httpwwwgooglecom)
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
httpclient
A Lithium-provided Freemarker object that allows you to make server-side calls to external APIs from endpoints bull You can configure what domains are allowed via the Lithium Admin
bull You can add headers fragments cookies and parameters to the request
bull Currently HTML is not allowed in the responses and will be rejected
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
httpclient Creating a Request
ltassign resp = httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
json()get() gt
ltassign resp = eval(httpclientrequest(ldquohttpssomeapiurlsomepathrdquo)
call(ldquoGETrdquo)) gt
ltassign = httpclientrequest(ldquohttpsrdquordquosomeapiurlrdquordquosomepathrdquo)
xml()parameter(ldquoparamNamerdquordquoparamValuerdquo)post() gt
bull Use HTTP GET POST PUT DELETE or OPTIONS
bull Use explicit methods or dynamically choose using the call method
bull Use a full URL string or specify the protocol hostname path and parameters separately
bull Specify whether you expect results in JSON XML or Plain Text
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
httpclient Handling the Response
ltassign response = httpclientrequest(ldquohttpssomeurlrdquo)json()get()gt
ltif responsehasErrorgt
ldquoerrorrdquo ldquo$responseerrormessagerdquo
ltelsegt
ltassign content = responsecontent gt
lt-- do cool stuff with content --gt
ltifgt
bull Calls to get() post() put() delete() options() or call(ldquoltmethodgtrdquo) return an httpresponse object
bull Use httpresponsehasError to check if the call was successful
bull httpresponseerrormessage will contain the error message if there is one
bull Use httpresponsecontent to get the content of the response (if there is not an error)
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Demo
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Lightning talk Security
Paolo Tagliaferri (Technical Consultant)
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Coding best practices
We must code our components keeping in mind certain aspects bull Extensibility
bull Maintainability
bull Robustness
bull Security
bull Performance
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Security
What we want the community to be secure to provide a safer environment for the users
Why
bull Users provide PII sensitive information at registration and in their profile
bull Malicious third parties could exploit security vulnerabilities to steal data scam users
bull Potential PR disaster
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Cross Site Scripting (XSS)
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications XSS enables attackers to inject client-side script into Web pages viewed by other (Wikipedia)
Non Persistent most commonly exploiting the HTTP request parameters
Persistent the injected code is stored in persistent storage
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
XSS attack
Example (non persistent XSS) consider the following component
It reads a request parameter (login) prints on screen and implements a button to retrieve and display the avatar associated with that login name
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLogin
var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
$(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
XSS attack JSON response
response
status success
image
type image
href usersid5profilesavatar
width
type integer
null true
$ null
height
type integer
null true
$ null
url
type string
$ httpemeadevstagelithiumcomt5imageserverpageavatar-namerobotoyavatar-themecandyavatar-collectionrobotsavatar-display-sizemessage
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
XSS Attack
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=PaoloT
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=FilipK
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSlogin=22alert(22I20am20an20hacker22)22
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
XSS Attack
Freemarker has built-ins that help in preventing these scenarios
var userLogin = $userLoginjs_string
hellipEscapes the string with the escaping rules of JavaScript language string
literals so its safe to insert the value into a string
httpfreemarkerorgdocsref_builtins_stringhtmlref_builtin_js_string
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Input Validation
Principle All the user input is a potential vector for attacks -gt Do not trust the user input 1 When collecting user input convert it into the expected format
bull string number c matches (regular expression)
2 Escape the strings according to the usage context
bull js_string json_string html url (docs)
3 For more complex scenarios use the OWASP GDATA strippers
1 Exposed by Lithium via the Utils Freemarker Context Object (doc)
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
XSS Attack - fixed
httpemeadevstagelithiumcomt5custompagepage-idCustomPaoloXSSfixedlogin=22alert(22I20am20an20hacker22)22
No more code injection execution
There are other aspects to improve of course
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
XSS attack
ltassign userLogin = httprequestparametersnameget(loginPaoloT)stringgt
ltpgt
Hello ltstronggt$userLoginltstronggt
ltinput type=button id=avatarDispl value=Display Avatar gt
ltpgt
ltdiv id=avatarAreagtltdivgt
ltliaAddScriptgt
(function($)
var userLogin = $userLoginjs_string var communityBaseRestUrl = emeadevstagelithiumcomrestapivc
$(document)ready(function()
$(avatarDispl)on(clickfunction()
$ajax (
url communityBaseRestUrl+userslogin+userLogin+profilesavatarrestapiresponse_format=json
)done(function(data)
var response = dataresponse
if ( responsestatus === success ) $(avatarArea)html(ltimg src=+responseimageurl$+ alt=Avatar gt)
else
$(avatarArea)html(Sorry - no avatar found)
)
)
)
)(LITHIUMjQuery)
ltliaAddScriptgt
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Food for thought
Using restadmin bull Will you leak PII information that the user has chosen to remain private
bull Could an anonymous user exploit your endpoint to modify data
Mixed content warnings bull Are you loading external resources over http
bull Could these resources be embedded in the Studio Asset Library instead
External APIs bull Are you exposing credentials required to make external calls
Thank you
Thank you