Securing Myfaces Applications Against The Owasp Top Ten: David Chandler
Securing Myfaces Applications Against The Owasp Top Ten: David Chandler
Is it safe?
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
Whats OWASP?
Open Web Application Security Project OWASP tools, documents, forums, and local chapters are free and open to anyone interested in improving application security OWASP Top Ten is a minimum standard for web application security Designed to help developers and adminstrators keep Web apps secure
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.
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
Managed by the framework in Application, Session, Request, or no scope Can inject references to related beans for nested flows
You register converters for custom types All security validation therefore handled centrally and automatically by model type
In logger object
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
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
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
Request
Process Validations
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
A1 Unvalidated Input
Parameter tampering (hidden & list boxes) Required fields Length, data type, allowed values Forced browsing Buffer overflows (see A5)
Convert Strings to Objects Validate Objects Update Model Call setters on managed beans
Invoke Application
Render Response
Unless
immediate=true for some component If so, managed bean can access raw component values through component tree (dont!) JSF will NEVER update model unless validation passes
Built-in converters
For all wrapper types (Boolean, Byte, etc.) <f:convertDateTime/>, <f:convertNumber/>
} 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
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
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?
All <h:commandLink>s and <h:commandButton>s are now protected (w/ no mappings required!)
Mapping approaches
Phase listener that maps view IDs to user perms And/or custom component <my:authChecker reqPerm=view_accounts />
Centralized approach
Decorate ActionListenerImpl to intercept events Conceivable to annotate bean methods with reqd perm
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
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
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
Try not to
Show the user a stack trace Reveal names of internal machines, etc.
A8 Insecure Storage
Not a Web tier problem
Use hashes instead of encryption Dont write your own encryption algorithm!
No known magic bullets for JSF like ping L 65510 Load test Load test Load test
Use listener to check for unvalidated components Use forced browsing / session riding preventer Dump JSP for Facelets
Resources
www.owasp.org facelets.dev.java.net