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
© Copyright 2026 Paperzz