520 likes | 680 Views
Java Application Security Integration. WAS CLASS. Agenda. Introduction Challenges Technology Overview Examples of Use solving problems integration Conclusion. Core Pillars Authentication Authorization Integrity Confidentiality Non-repudiation. Disciplines Threat Assessment
E N D
Java Application Security Integration WAS CLASS
Agenda • Introduction • Challenges • Technology Overview • Examples of Use • solving problems • integration • Conclusion
Core Pillars Authentication Authorization Integrity Confidentiality Non-repudiation Disciplines Threat Assessment Policy Definition Administration Intrusion Detection Optimization/Vulnerability Assessment What is Security? “Freedom from risk or danger; safety.” source: dictionary.com Application security builds on infrastructure security
Authentication Challenges • Multiple Realms • Different technologies • OS, directory, database, AAA, file, legacy… • Multiple instances • internally and cross-organization (trust) • Single-sign on/reduced sign-on • Strong authentication • PKI: how to do key management? • Multi-factor? • Delegation
Authorization Challenges • Defining roles & permissions • Mapping & specializing • Functional authorization • For resource, service, component, class & method • Data-driven authorization • For instance-level & field-level • UI: showing only authorized • Fields, commands (buttons) • Consistent enforcement
Additional Challenges • Non-Repudiation • Tracking audit trails • Digital signatures? • Confidentiality • Field-level encryption • At-rest encryption (preferably infrastructure!) • Integrity • Digital signatures
Service end-user operations Application Security Architecture Interaction Tier ApplicationTier Resource Tier Perimeter
Security Technologies • The Java platform • JAAS • Application servers • Security products • Fine grained security • Aspect-Oriented Programming • Filters and Proxies • Web services
Application Security Domains Security Servers (AAA) Web Ser-vices SSL/PKI Data-base Fine-grainedSecurity (AOP…) Application Servers,JAAS
Java Security • Secure platform since inception • sandbox supports untrusted code • no pointers, bounds checking, GC • JCA, JCE • cryptography, certificates, keys • JAAS • pluggable authentication • AccessController authorizes access • J2SE 1.4 moves JAAS capabilities into core
JAAS Authentication Source: Sun Microsystems
JAAS Authorization Source: Sun Microsystems
J2EE Security • Declarative • Role names and mapping • Web resource constraints • EJB component and method constraints • Programmatic • Principal (name) • Role membership
Application Server Integration • Until now • Container-specific realms for authentication • Container-specific policy for authorization • JAAS not integrated • J2EE 1.4 will standardize with JAAS • Java Authorization Contract for Containers • Java Authentication Service Provider Interface for Containers
J2EE 1.4 Security Architecture Source: Sun Microsystems
Service end-user operations AAA products Interaction Tier ApplicationTier Resource Tier Perimeter E.g., Netegrity, RSA, Oblix, Tivoli, Oracle… PEP admin identity, access PDP
Security Integration Framework Example Weblogic Security Framework 8.1, Quadrasis Source: BEA
Web Services Security Source: Sun Microsystems
Into this AOP turns this... Aspect-Oriented Programming (AOP) • Auxiliary concerns are scattered and tangled • Security: authorization, identity management, audit trail • Business rules • Error handling • So AOP uses aspects to provide: • modular support for crosscutting concerns • language and tool integration • Evolutionary step for software development • structured objects components aspects
Filters & Proxies • Special-case support for crosscutting • Servlet Filters • Allow all/certain servlet requests to enforce policy • Authentication (JAAS, single-sign on…) • Authorization (set up doAsSubject…) • Dynamic Proxies • Allow wrapping interfaces • Can separate data-driven authorization • Still scatters policy implementation
Functional Authorization Example • Add bug use case • Forces authentication • Projects in groups with corresponding roles • Functional authorization: check bug entry role • UI Filtering: only employees can edit status
Web Deployment Descriptor <security-constraint> <web-resource-collection> <web-resource-name>Protected Area</> <url-pattern>/aTrack/internal/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>internal</role-name> </auth-constraint> </security-constraint> …
Web Deployment Descriptor … <login-config> <auth-method>FORM</auth-method> <realm-name>aTrack</realm-name> <form-login-config> <form-login-page>/aTrack/protected/login.jsp</> <form-error-page>/aTrack/protected/error.jsp</> </form-login-config> </login-config> <security-role> <role-name>internal</role-name> </security-role>
Tomcat 4.x JDBC Realm Setup <Server className="org.apache.catalina.core.StandardServer“ debug="0" port="8005" shutdown="SHUTDOWN"> … <Realm className="org.apache.catalina.realm.JDBCRealm“ debug="99" driverName="org.gjt.mm.mysql.Driver" connectionURL="jdbc:mysql://localhost/authority?user=dbuser&password=dbpass" userTable="users" userNameCol="user_name“ userCredCol="user_pass“ userRoleTable="user_roles“ roleNameCol="role_name"/> …
UI Filtering … <% if (SecurityUtils.getRoles(getUser()). contains("internal")) { %> <html:list property="status"> <% } else { %> <html:label property="status"> <% } %>
Servlet Filter to Set Up JAAS public class AccessFilter implements Filter { public void doFilter(ServletRequest request, …) { Session session = ((HttpServletRequest)request).getSession(); Subject subject = session.getAttribute(SUBJECT_ID); if (subject == null) // redirect to force authentication try { Subject.doAsPrivileged(subject, new PrivilegedExceptionAction() { public Object run() throws Exception { chain.doFilter(request, response); } }, null); } catch (PrivilegedActionException e) { throw e.getException(); } } }
JAAS Authorization public class AddBugAction extends Action { publicActionForwardexecute(ActionMappingmapping, ActionFormform,HttpServletRequestrequest, HttpServletResponseresponse)throwsException{ // does the user have permission to enter bugs? AccessController.checkPermission( new AtrackPermission("bugEntry")); … } }
UI Filtering … <% if (getUserPrincipals().contains("internal")) { %> <html:list property="status"> <% } else { %> <html:label property="status"> <% } %> …
AspectJ JAAS Authentication public aspect RoleBasedAccess { private pointcut request(HttpServletRequest request, HttpServletResponse response) : execution(* HttpServlet.do*(..)) && this(SensitiveServlet) && args(request, response); private pointcut sensitiveOperations() : execution(* atrack.model.sensitive.*.* (..));
AspectJ JAAS Authentication … void around(HttpServletRequest request, HttpServletResponse response): request(request, response) { HttpSession session = request.getSession(); Subject subject = session.getAttribute(SUBJECT_ID); if (subject == null) // redirect to force authentication try { Subject.doAsPrivileged(subject, new PrivilegedExceptionAction() { public Object run() throws Exception { proceed(request, response); } }, null); } catch (PrivilegedActionException e) { throw e.getException(); } } …
AspectJ JAAS Authorization … before(SensitiveServlet servlet, HttpServletRequest request, HttpServletResponse response): sensitiveOperations() { Permission permission = getPermission(thisJoinPoint. getSignature().getName()); AccessController.checkPermission(permission); } private Permission getPermission(String methodName) { // config or database lookup } }
Data-Driven Authorization Example • Edit employee data • Data-driven: employee, manager (transitively) and HR admin role • UI Filtering: invisible, visible, editable • Possible extension • Trust delegation: check in domain tier on commit
Data-Driven Authorization EJB security
EJB Implementation publicclass Employee { … public int getSSN(EjbContext securityContext) { Principal p = securityContext.getPrincipal(); Employee caller = Employee.getEmployee(p); if (caller==null || !employee.reportsTo(caller))) { // record attempted security violation thrownew AuthorizationException("…"); } // and log data access to audit trail return ssn; } public double getSalary(EjbContext securityContext) { Principal p = securityContext.getPrincipal(); … } }
Propagating Context publicclass ServiceEjb { public int getEmployeeDetails() { … employees.getRows(getContext()); } … } publicclass Employees { … public int getRows(EjbContext securityContext) { … employee.getSSN(securityContext); … } }
JAAS Implementation publicclass Employee { public int getSSN(Subject subject) { Set s = subject.getPrincipals(Employee.class); boolean ok = false; for (Iterator it = s.iterator(); it.hasNext();) { Employee caller = (Employee)s.next(); if (employee.reportsTo(caller))) ok = true; } if (!ok) { // record attempted security violation thrownew AuthorizationException("…"); } // and log data access to audit trail return ssn; } public double getSalary(Subject subject) { Set s = subject.getPrincipals(Employee.class); …
JAAS Set Up public class Service { public int getEmployeeDetails() { Subject subject = session.getAttribute(SUBJECT_ID); if (subject == null) // forward to force authentication try { Subject.doAsPrivileged(subject, new PrivilegedExceptionAction() { public Object run() throws Exception { … employees.getRows(subject); … } }, null); } catch (PrivilegedActionException e) { throw e.getException(); } } …
Proxy Set Up publicclass EmployeeFactory { public Employee getEmployee(int key, Subject subject) { InvocationHandler handler = new EmployeeInvocationHandler(subject); return (Employee) Proxy.newProxyInstance( Employee.class.getClassLoader(), new Class[] { Employee.class }), handler); } }
Proxy Implementation publicclass EmployeeInvocationHandler { public EmployeeInvocationHandler(EjbContext context) { this.context = context; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (proxy instanceof Employee && isSensitive(method)) { Principal p = context.getPrincipal(); Employee caller = Employee.getEmployee(p); Employee employee = (Employee)proxy; if (caller==null || !employee.reportsTo(caller))) { // record attempted security violation thrownew AuthorizationException("…"); } // and log data access to audit trail return method.invoke(proxy, args); } …
EmployeeDataAuthorization Aspect Data-Driven Authorization Using Aspects
Policy Definition Aspect publicaspect SecurityPolicy { publicpointcut securedCall(ManagedSessionBean ejb): cflow(EjbPointcuts.ejbTopLevelExec(*) && this(ejb)) && (call(* Employee.getSalary(..)) || call(* Employee.getSSN(..)) || call(* Employee.getAddress(..))); }
Data Authorization Aspect publicaspect EmployeeDataAuthorization { before(ManagedSessionBean ejb, Employee employee) : SecurityPolicy.securedCall(ejb) && target(employee) { Principal p = ejb.getContext().getPrincipal(); Employee caller = Employee.getEmployee(p); if (caller==null || !employee.reportsTo(caller))) { // record attempted security violation thrownew AuthorizationException("…"); } // and log data access to audit trail } }
Security: UI Filtering Requirements • Only authorized fields • Only links to authorized resources • Edit field only if authorized • Saved same key as edited • Within JSP, Servlet, etc.
AOP Implementation Strategy for JSP • Advice finds unauthorized field display • catch SecurityExceptions and flag • Filter removes complete context • We’ll use a servlet filter • Can also intercept PageContextFactory to extend PageContext to wrap the PrintWriter • Deployment options: • precompile JSPs, then link aspects in • configure JSP compiler to use ajc (we’ll use this with Tomcat) • the classloader (if available, e.g., WLS)
Catching Unauthorized Fields in JSP Object around() throws JspException: securityChecks() && call(* *(..) throws (Throwable || Exception || JSPException)) { try { returnproceed(); } catch (JspException je) { Exception e = (Exception)pageContext.getAttribute( Globals.EXCEPTION_KEY, PageContext.REQUEST_SCOPE); if (e != null && e instanceof SecurityException) { handleSecurityException(e); returnnull; // void or filtered... } throw je; } }
Aspect Uses FilteringResponse Object around() : securityChecks() { try { returnproceed(); } catch (SecurityException e) { handleSecurityException(e); returnnull; // void or filtered... } } privatevoid handleSecurityException(Exception e) { try { jspWriter.flush(); // force buffer synch } catch (java.io.IOException ioe) { thrownew RuntimeException("error flushing", ioe); } // specialized Response object adds the position to // a list of “locations to filter”; the contents are // then removed when flushing the buffer response.removeCurrentSection(); }