(JSF)? - owasp

Securing JSF Applications
Against the OWASP Top Ten
OWASP &
WASC
AppSec 2007
Conference
San Jose – Nov 2007
http://www.webappsec.org/
David Chandler
Sr. Engineer, Intuit
[email protected]
770-349-1294
Copyright © 2007 - The OWASP Foundation
Permission is granted to copy, distribute and/or modify this document under the
terms of the Creative Commons Attribution-ShareAlike 2.5 License. To view this
license, visit http://creativecommons.org/licenses/by-sa/2.5/
The OWASP Foundation
http://www.owasp.org/
JSF is a Great Framework
 Tool-friendly
 MVC
 Component-orientation makes reuse easy
 But….
Is it safe?
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Framework Security Continuum
More
secure
Framework makes it impossible for
developers to write insecure code
Developers must do all the right stuff, but
you can use code scanning tools and
limited inspection to find holes
Possible, but developers must do all the
right stuff
Not possible to create a secure app
(framework is flawed)
Less secure
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Security Analysis Goals
Address framework / implementation
vulnerabilities
Lock front door and back door
Inspect application code for vulnerabilities
Ideally, centralize validation and use other JSF
extensions to minimize inspection points
Use automated scanning tools to verify that
 Application code uses only safe components / extensions
 Application code does not access the external context
directly (HttpSession) or use Lifecycle in unsafe ways
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Our Mission Today
Learn how to secure JSF applications
Using the OWASP Top Ten as a guide
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
What is JavaServer Faces (JSF)?
What is JSF?
Spec, not an implementation (JSR 127)
Many vendor implementations and two free
 Sun’s reference implementation (RI)
 Apache myFaces
Where does it fit in the frameworks universe?
MVC, component-based framework servlet
Builds on Struts controller, form bean concepts
Builds on Tapestry components
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
What’s in a Typical JSF App
View templates (JSP or Facelets)
Managed bean for each view registered in facesconfig.xml
Navigation rules in faces-config.xml
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Major JSF Concepts
Components
Renderers
Managed beans
Converters / Validators
Controller (navigation model)
Event handling
Request lifecycle
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Components
 Separate business logic from presentation
 Every view is composed of a component hierarchy
 Components can be added to view programmatically or
via template (JSP by default, Facelets for superior
performance and ease of development)
 Standard components divided into two groups:
 Faces Core <f:view>, <f:loadBundle>
 HTML wrappers <h:dataTable>, <h:selectMany>, etc.
 Component = class + [renderer] + tag handler (JSP)
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Renderers
Component renderer encodes (generates the
HTML) for the component
Renderer also decodes (sets component values
from URL query string and form vars)
Renderers are grouped into render kits
Default render kit is HTML
Provide device independence w/o changing the
templating language or components themselves
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Managed Beans
Link view to the model (like controller)
Provide event handler methods which in turn call
appropriate model code (save, new)
Provide helper methods (getAvailableSelectItems)
Hold references to one or more domain objects
Managed by the framework in Application,
Session, Request, or no scope
Can inject references to related beans for nested
flows
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Value Binding
Component values bind to model beans
For each request, the framework
Converts each input value (String) into the underlying
Java type (MoneyAmount)
On output, converts underlying Java type to String
You register converters for custom types
All security validation therefore handled centrally
and automatically by model type
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Value Binding Example
view.xhtml
In logger object
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Value Binding Example
view.xhtml
Managed beans are registered in faces-config.xml
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Converters / Validators
Converters are bi-directional
Input converter: getAsObject()
Output converter: getAsString()
Validators work with Objects, not just Strings
JSF supplies standard converters for date / time,
numbers, etc.
You write custom converters for rich types or
special behavior
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Converters / Validators
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Converter Example
Converter is registered in faces-config.xml, so all
ValuedTypesafeEnum properties of any bean will use this converter
Validators also registered in faces-config.xml, but not by class
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Controller
 Stateful or stateless navigation model
 Framework selects next view based on
 Previous view
 Outcome of the event handler
 Event itself (regardless of outcome)
 Any combination of the above
 Possibilities
 Universal error view (triggered by “error” outcome)
 Wildcard matching permitted in outcomes, view IDs
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Event Handling
 <h:commandButton action=“#{ReportCtrl.save}”>
 Generates an event when pressed
 save() is a method on a managed bean
 JSF calls ReportController.save()
 Can also define action listeners associated with other
components in the form
 Example: AccountSearch on any page without having to tell JSF
navigation controller about each instance
 Custom ActionListenerImpl runs before invoking method
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Request Lifecycle
Restore
View
Retrieve component tree
from client or session
Apply Request
Values
Request
Decode components
(populate w/ String values)
Convert Strings to Objects
Validate Objects
Process
Validations
Call setters
on managed beans
Update
Model
Invoke bean method(s)
Compute navigation
Response
May skip to
render phase
or abort request
Invoke
Application
Call bean getters to
populate components
Render
Response
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Extension Points
Custom components
Phase listeners (before, after any phase)
Custom converters / validators
Custom renderers
Custion ActionListenerImpl to handle event
Decorate or replace view handler, navigation
handler, state manager, etc.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Configuration
faces-config.xml
Contains navigation rules as well as any
customizations / extensions
Can be split among directories and subdirectories as well as jars
Set javax.faces.application.CONFIG_FILES in web.xml
Or put META-INF/faces-config.xml in jars so can
bundle required configuration with code
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
OWASP Top Ten (2004 Release)
A1 Unvalidated Input
A2 Broken Access
Control
A3 Broken Authentication
and Session Mgmt
A4 Cross Site Scripting
A5 Buffer Overflow
A6 Injection Flaws
A7 Improper Error
Handling
A8 Insecure Storage
A9 Application Denial of
Service
A10 Insecure
Configuration Mgmt
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
 A1 Unvalidated Input
Parameter tampering (hidden & list boxes)
Required fields
Length, data type, allowed values
Forced browsing
Buffer overflows (see A5)
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
JSF Validation Process
Validation is part of the request lifecycle
When validation fails
Throw ConverterException or ValidationException
Add message to the message queue
 Message is associated with offending component
 Use <h:messages/>
or <h:message for=“component_id”/>
 Don’t forget one of these in your view!
Skip directly to render response phase
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
JSF Request Lifecycle
Retrieve component tree
Restore
from client or session
View
Apply Request
Decode components
Values
(populate w/ String values)
Convert Strings to Objects
Validate Objects
Process
Validations
Request
Call setters
on managed beans
Update
Model
Invoke bean method(s)
Compute navigation
Response
May skip to
render phase
or abort request
Invoke
Application
Call bean getters to
populate components
Render
Response
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
JSF Validation Process
 Thing of beauty!
 Model values never updated with invalid data
 User remains on current view
 No action methods called
 Messages tagged with component ID
 Unless…
 immediate=“true” for some component
 If so, managed bean can access raw component values through
component tree (don’t!)
 JSF will NEVER update model unless validation passes
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
Parameter Tampering
Hidden fields
Multiple choices (radio, check box, select)
Required fields
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
Parameter Tampering (Hidden Fields)
 Did you say hidden
fields…?
YUCK!
 Of course, they can be
tampered with!
 Must rely on validation as
with any other field
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
Parameter Tampering (Select Options)
List boxes, radio buttons, check boxes
<h:selectOneRadio value=“#{bean.choice}”>
<f:selectItems value=“#{bean.allChoices}>
</h:selectOneRadio>
 JSF selectOne and selectMany components validate
selected items against available choices
 Component calls selectItems getter again and compares
selected String with available Strings
 See java.faces.component.UISelectOne/Many
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
Parameter Tampering (Req’d Fields)
Required fields
<h:inputText value=“#{bean.prop}”
required=“true or EL” />
If required field is empty (“”, not null),
JSF will fail validation as usual
Can change default msg in properties file
Or for really custom requiredness checking, write a
custom converter (because validator doesn’t get
called for empty fields, but converter does)
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
Validating Length, Format, Data Type
Built-in validators for length & range
<f:validateLength…/>, <f:validateDoubleRange…/>,
<f:validateLongRange…/>
maxLength DOESN’T affect validation
Built-in converters
For all wrapper types (Boolean, Byte, etc.)
<f:convertDateTime…/>, <f:convertNumber…/>
See Tomahawk for e-mail, regex, credit card
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
Custom Validators
Simple interface
public void validate(…)
throws ValidatorException
Can invoke one of three ways
setValidator() in custom component
As validator tag (Facelets auto-wiring ) like built-ins
<my:customValidator … />
<h:inputText validator=“id | #{bean.validator}…>
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
Custom Converters
Simple interface
getAsObject(…)
getAsString(…)
Invoke one of four ways
By type of model property bound to component
setConverter() in custom component
As converter tag (Facelets auto-wiring ) like builtins <my:customConverter … />
<h:inputText converter=“id | #{bean.converter}…>
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
Rich Type (Model Centric) Converter
 <converter-for-class>StringAN</…>
public static class UserCode extends StringAN {
Public UserCode (String value) throws InvalidStringException {
super(value, 14); // length
}
}
 In your model class, define & use type UserCode
 Now all components bound to property of type UserCode
are automatically converted / validated
 StringAN does validation in constructor so an invalid
instance can never be created
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
JSF Validation Summary
Strengths
All validations declarative
Associated with view, not action (so can’t be
overlooked in case of multiple actions)
Model never updated unless all validations pass
Converter-for-class eliminates need for explicit
validator on every widget
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
JSF Validation Summary
Weaknesses
No way to confirm that you didn’t miss a validator or
two
Unless…
You use only custom converters / validators that add
the id of each validated component to a Request
variable
And use a phase listener after validation to walk the
component tree and find unvalidated UIInputs
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
JSF Validation Extra
How can I validate related fields together?
i.e., StartDate < EndDate
Can do in bean action method. Not part of validation
lifecyle, but can have all the same effects
 Return null outcome to remain on view
 Add message to queue
 Skip remainder of action code
Alternatively, put a dummy tag after last form field
<h:inputHidden validator=“#{bean.method}” />
 But model not updated yet, so must hard code component
IDs in bean
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
What About JSF and AJAX?
Approach 1
Separate servlet or JSF phase listener to intercept
and handle AJAX queries
Bypasses JSF validation (ouch)
Approach 2
ICEFaces and AJAX4JSF provide simple AJAX-capable
JSF components
Retains JSF server-side validation (good!)
Neither approach sends data to client using
JavaScript, so neither is subject to JS hijacking
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
Forced Browsing
JSF prevents forced actions
Example
 Simulate clicking a button not on view
 Like http://server/someAction.do?...
Every JSF URL contains the previous view ID
JSF restores component tree from prior request
Only processes events for components in the saved
view
But can still force an action on another view
How do we solve it? View / mappings?
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A1 Unvalidated Input
Forced Browsing
JSF Can Be Extended to Prevent All Forced
Browsing and Session Riding
Form action is obtained from the ViewHandler
Decorate ViewHandlerImpl to override getActionURL()
and append a hash of the URL
Write custom phase listener to
 Generate new token in Session for each request
 Compare hash in the URL with expected token
All <h:commandLink>s and <h:commandButton>s
are now protected (w/ no mappings required!)
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
 A2 Broken Access Control
Insecure IDs
Forced Browsing Past Access Control Checks
Path Traversal
File Permissions
Client Side Caching
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A2 Broken Access Control
Forced Browsing Past Access Control
Safe approaches to user authentication
Use built-in features of servlet container or portal
Servlet filter
Extend MyFacesGenericPortlet with auth hooks
Portlet filter—see MyFaces JIRA 434
Phase listener before RESTORE_VIEW
 ExternalContext.getUserPrincipal()
 ExternalContext.isUserInRole()
 Both servlet impl and portlet impl define these methods
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A2 Broken Access Control
Forced Browsing Past Access Control
Safe ways to control access to views
(easy) Use rendered attribute with bean permission
getters for fine-grained control
<h:panelGroup rendered=“#{bean.hasPermX}”/>
Use above with forced browsing preventer
 Only have to check view perms when you display a link
Mapping approaches
 Phase listener that maps view IDs to user perms
 And/or custom component to restrict access to view
<my:authChecker reqPerm=“view_accounts” />
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A2 Broken Access Control
Forced Browsing Past Access Control
Safe ways to control access to actions
(easy) Check perms in each bean action method
Use rendered attribute with bean permission getters
when displaying links
 <h:commandLink rendered=“#{bean.hasEditPerm}” />
 JSF automatically prevents forcing the action, even without
forced browsing preventer
Centralized approach
 Decorate ActionListenerImpl to intercept events
 Conceivable to annotate bean methods with req’d perm
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A2 Broken Access Control
Client Side Caching
Concern: browser caching, shared terminals
Use phase listener to write no-cache headers
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
 A3 Broken Authentication
and Session Management
Not JSF-specific
Password policy, storage
Roll-your-own session management (don’t!)
Protect login via SSL
Login page should always POST, not GET
 JSF forms are always POSTed
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
 A4 Cross Site Scripting
Two types of attacks
Stored (ex: malicious input stored in DB)
Reflected (ex: malicious e-mail submits a request
with cookie-stealing Javascript in text field)
 Reflected attacks are initiated externally (as via e-mail)
 Forced browsing / session riding preventer stops these since
request doesn’t contain a valid hash
 Just make sure you don’t put an unchecked HTTP header or
cookie in the error message
Two approaches: input & output filtering
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A4 Cross Site Scripting
Approach 1: Input Filtering
Filter all input with Converters, Validators
Positive enforcement (allowed characters only)
stronger than negative enforcement (remove “bad”
chars)
JSF numeric converters protect numeric properties
Don’t forget HTTP headers & cookies are input, too
Rich type converters greatly help with text input
(i.e., UserCode = alphanumeric, maxlen 14)
Then you only need to worry about value bindings to
free form String model properties
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A4 Cross Site Scripting
Approach 2: Output Filtering
MyFaces does this mostly for you
<h:outputText> and <h:outputFormat> values are
escaped unless you explicitly turn off with
escape=”false”
<h:outputLink> URIs beginning with “javascript:” are
escaped
All other HTML components (<h:> tags) are safely
rendered
Tag attributes are escaped for all components
Escaped chars are < > “ & (not sufficient w/in JS)
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A4 Cross Site Scripting
XSS Code Review
What to look for in view templates
<h:outputText/Format escape=“false” />
<h:outputLink value=“#{bean.non_js_prop}” />
Any output components between <script> tags
What to look for elsewhere
Rich type constructors and/or getAsString() for rich
type converters
Custom components and renderers
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
 A5 Buffer Overflows
Not an issue in Java per se
Might be an issue for 3rd party systems (DB)
Always validate input for length
Numeric types are safe (Integer, Long, etc.)
Prefer rich types to Strings
Use <f:maxLength> for String properties
Keeping max lengths short also helps with XSS
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
 A6 Injection Flaws
Ex: SQL injection
SELECT * FROM users where ID = URL.ID
Suppose URL.ID = “34; DROP TABLE users”
Most effective protection is nearest the calls to
external system
Use O/R mapping
Parameterize all queries
Nevertheless, JSF can be of some help
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A6 Injection Flaws
Common Problem: IDs in URLs
JSF <h:dataTable> uses indexed rows
Don’t use <f:param> with real IDs
Use ListDataModel and getRowData(). JSF will do the
mapping and get the Object for you
What if an item is added to the table between clicks?
Could write custom dataTable component that
overrides getClientId() to hash row values vs. index
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A6 Injection Flaws
Common Problem: IDs in OPTIONs
Values of select options, radio buttons, check
boxes often use real IDs
Parameter tampering OK, but possible info leakage
Several ways to avoid this
Populate <f:selectItems> with Integer values that
index into an array stored in your managed bean
 Could write SelectItemsHelper to map real values to indexed
values, but creates dependency
Better: create a custom converter w/ encrypted hash
 <my:hashConverter> used inside Select components
 Or perhaps even <my:selectItems> to replace JSF’s
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A6 Injection Flaws
Summary
Not an issue with JSF
But JSF can help
Once again, converters are the key
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
 A7 Improper Error Handling
Not a JSF issue per se
Use standard servlet techniques
<error-page> in web.xml, etc.
Try not to
Show the user a stack trace
Reveal names of internal machines, etc.
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A7 Improper Error Handling
Facelets Has Beautiful Error Messages
 Beautiful, but more
than the customer
needs to know
<context-param>
<param-name>
facelets.DEVELOPMENT
</param-name>
<param-value>
false
</param-value>
</context-param>
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
 A8 Insecure Storage
Not a Web tier problem
Use hashes instead of encryption
Don’t write your own encryption algorithm!
Except for one thing in web.xml (see A10)
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A9 Application Denial of Service
All Web apps are vulnerable to some degree
Forced browsing listener will minimize damage by
rejecting bogus requests early
No known “magic bullets” for JSF like
ping –L 65510
Load test
Load test
Load test
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
 A10 Insecure Config Mgmt
Primarily concerned with
Server OS, software, misconfigurations
Improper file & directory permissions, etc.
Unnecessary services
What about JSF configuration?
State saving method
View handler (JSP or Facelets)
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A10 Insecure Configuration Mgmt
Beware Client State Saving
Server- (default) or client-side state saving
Out of the box, client-side state saving is Base64
encoded only (no encryption!)
Allows hacker to alter component tree(!)
Replace converters & validators
Change EL expressions that populate fields, select
boxes
Change EL in command link to call different event
handler, remove action listener
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A10 Insecure Configuration Mgmt
Enable Client State-Saving Encryption
If client saving, provide encryption key in <initparam> org.apache.myfaces.secret
Default algorithm is DES
See myfaces-shared-impl StateUtils class to
change
Org.apache.myfaces.algorithm
Org.apache.myfaces.algorithm.parameters
Org.apache.myfaces.secret.cache
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
A10 Insecure Configuration Mgmt
Lock Down .xhtml with Facelets
Lock down .xhtml extension if using Facelets
Rejecting servlet
Or <security-constraint> in web.xml
See Facelets doc for details
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Putting It All Together
Use only rich types in model beans
Rich type converter(s) should
Provide positive input validation
Index values for select components (radio, check,
menu)
Escape all other output
Use listener to check for unvalidated
components
Use forced browsing / session riding preventer
Dump JSP for Facelets
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007
Resources
www.owasp.org
facelets.dev.java.net
icefaces.org
learnjsf.com
(blog, code samples, etc.)
http://labs.jboss.com/jbossrichfaces/
OWASP & WASC AppSec 2007 Conference – San Jose – Nov 2007