Chapter 19. Expresso Security

Table of Contents

Introduction
Security Architecture Overview
User Authentication and Authorization
Authentication
Authorization
Servlet Engine Container Authentication
Filtering
LDAP Integration
SSL and Web Applications
A Super Quick Introduction To SSL
Configuring Expresso to use SSL
Coding Expresso to utilize SSL
Application Security
Administrative Security
Database Security
Encryption
Cross Site Scripting Countermeasures
SQL Injection Countermeasures
RowSecuredDBObject
Cookie Encryption
Tips for Securing a Production Expresso Environment
Conclusion
Contributors

Note

If you find this EDG documentation helpful please consider DONATING! to keep the doc alive and current.

 Maintainer:David Lloyd

Expresso allows a visitor to the site to register and become a member of the community. It is focused directly on creating login information and includes security functionality. Expresso allows for administration of sophisticated security that is in addition to any security provided by your choice of application server product, and portable accross all deployment environments.

Introduction

User management is the route that we took with Expresso. Expresso's security framework came into being long before container-based security became a possibility. Though now we also have contained managed security integrated into Expresso.

This release also includes a major usability refactoring of our self-registration code. As you will see a generic self-registration system is definitely not a trivial task.

Security is applied at several levels in the package:

  • Login Security

  • Database Object Security

  • Application Security

To administer security in your application, use the Expresso Administrative Menu and select the Security selection. This page allows the system administrator to control what users are allowed to access what functions. Users can be registered, assigned to groups, and those groups granted appropriate security access. Each application is then assigned a list of groups which are allowed to access it, and every database object is assigned security by group and method (add/update/delete/search) as well. To use Expresso with no security restrictions: Override isAllowed() for your data entry controller to return true for all situations; otherwise, you can just derive directly from Controller instead of DBController to not use any security systems.

Here are some helpful hints to follow when starting to use Expresso Security:

  • Make a copy of the existing Login and Registration controllers to your code base (or modify the existing ones)

  • Modify/add mappings in struts-config.xml or your own config file to change the use of the /Login.do and /Registration.do mappings (if your wanting to change the look and feel, change the associated JSPs also).

  • Be careful of the inner-dependencies between LoginController and RegistrationController. In some instances, the transitions are called by class name, so you'll have to update the location of the controllers if you migrate the controllers into your packages.

  • Also see section, Tips for Securing a Production Expresso Environment.

Security Architecture Overview

Expresso security includes Authentication with every access, and will include Authorization tests as well, if the application has required them.

Authentication involves a login with username and password to ascertain identity. See com.jcorporate.expresso.services.controller.LoginController for details. Identity is stored in a persistent session, in the session provided by the Container servlet engine. On the login screen, the user is given a checkbox to "remember" the login.If the user checks this box, a 30-day-duration cookie is written to the user's browser with the username and password. Clearly, this cookie is appropriate only for relatively low- stakes security. If your application should not allow such a cookie to be written, remove the checkbox from the GUI. During repeated access, first the session is checked, and if that Authentication fails, the cookie is attempted. See com.jcorporate.expresso.core.servlet.CheckLogin for details. Also, if a user tries to access a page and fails because of a lack of login, Expresso from version 5.0 will automatically reroute the request to a login page, and subsequent to a successful login, reroute to the user's original destination.

Authorization checks pertain to every user access if the Expresso application subclasses (Row)SecuredDBObject and DBController. In other words, if your application requires Authorization checks, then subclass either SecuredDBObject or RowSecuredDBObject for your objects that need authorization,and subclass DBController for controllers for controllers in your application, rather than the unsecured DBObject and Controller superclasses. Most of the Expresso administrative code subclasses SecuredDBObject and DBController for this reason. Authorization checks occur whenever a user attempts to access a page which in turn accesses a DBController method, and usually thereby accesses a (Row)SecuredDBObject.

Authentication can be administered via the Security pane, User Information link where new users can be added, and their membership within groups administered. Expresso employs the concept of group membership for all security permissions. A group is enabled, and therefore all members of the group are enabled, and vice-versa.

Authorization can be administered via the Security pane, and links: 'Administer Database Object Security', 'Administer Controller Security' and 'Administer Job Security'. These present a matrix of permissions, where a group of users is given permissions per SecuredDBObject. There are typically 4 types of permissions: search, add, update, and delete. These are directly analogous to the ability to execute SQL commands 'select', 'insert', 'update', and 'delete' against the table associated with a given SecuredDBObject. Administration of row-based permissions is typically handled by the application, showing row permissions to users just as it displays row content.

User Authentication and Authorization

User management is the route that we took with Expresso. Expresso's security framework came into being long before container-based security became a possibility. Though now we also have contained managed security integrated into Expresso.

Version 5.0 also included a major usability refactoring of our self-registration code. As you will see a generic self-registration system is definitely not a trivial task.

The user security features in Expresso include:

  • Allows a user to register and obtain a username and password

  • Provides required fields checking facilities on the quality of the registration

  • Mechanism to extend default user fields in Registration Process

  • Checks for confirmation of password before making the account active

  • Confirms registration by sending a welcome email to the user including the username and password. This email is user-definable, which allows for customizable message

  • Method to approve membership before joining fully

  • Alternative mechanism to log in with the user's email and password

  • Function for users to change their password once they have logged in

  • Function for users to update their user profile such as address and contact information

  • Function for user to log out

  • Mechanism to verify the identity of users by email if a user forgets their login and/or password - and to email the user their login and a new password

  • User's Address and contact information is available for contact member directory

  • Ability to add Users to User Groups which is used to define user roles.

  • Facility to grant Database Object Security to User Groups.

  • Provides user authentication for all member-related services

  • Provides user membership that can be extended with additional components. i.e. by other applications such as eContent's ability to protect resource access and prevent non-members seeing content , or through custom development of Expresso based applications

If you want to have to avoid the Expresso Login mechanism, then it boils down to this. Servlets depend on a "session" linking the client to the server. Expresso login mechanism simply stores a username in the session, after authenticating it. So, if you need to use some other login mechanism, what'd you'd do is write a class that intercepts a new session being created, and then set the username variable just like Expresso's Login controller does.

Authentication

The first layer of security in Expresso is the Authentication - this is the process of identifying the user and verifying that the user is in fact who they say they are: At it's simplest level this is done via a user name/password login process, but is "pluggable" to allow more sophisticated authentication schemes, integration with LDAP servers, etc to easily be added.

If appropriate, authenication information can be stored on the client as a cookie to enable the user to bypass the manual login process when they next visit the application.

Login requires a login name and password for all secured functions. Some functions may be unsecured - that is, any user may access them without logging in, but ordinarily most functions will require a login. If the user goes directly to the URL of a function that requires a login, but has not yet logged-in, they will be presented with the login screen, and upon a successful login will continue on to the function they originally selected.

A successful login establishes a session - a session is maintained until the user either logs out, leaves their browser (e.g. exits the browser application), or until the server is restarted for some reason. (Sessions will also time out after a period of inactivity).

Expresso also has an auto-redirect feature to redirect the user to where they logged in from.

Authorization

Once a user is identified and associated with a session, their authorization is determined by identifying which user groups a user belongs to. Similar to user groups in the Unix environment, or to "roles" as defined by many application servers, groups can however be nested within other groups to make management of extremely large user communities very efficient. Permission is then granted at any of several levels to the group, and thus to the members of the group. Permissions can be assigned at:

  1. Database Object Level: Assigning permission to add/update/delete/search for any database object (table) in the application.

  2. Controller Level: Allowing access to all or selected "states" of each Controller in the application, controlling precisely which functions specific groups of users are allowed to perform.

  3. Job Level: Allowing access to specific background jobs.

  4. Custom level: Allowing access at a customized level for a specific application: for example, allowing users to subscribe to different discussion groups for a forum application (such as eForum).

Servlet Engine Container Authentication

CheckLogin has been modified to allow for Expresso to get the currently logged in user as far as the container is concerned and hook into it's own Security system this way. Expresso now will utilize getUser() from the servlet engine to log the user in that way. It uses standard Servlet API's so it shouldn't be a problem for various Servlet engines. The roles the user receives are still Expresso-based.

As of Expresso version 5.0, we have successfully tested with integration with Tomcat's servlet engine authentication. We go about this simply by checking the user name with the Session.getUser() call to the standard Servlet API. We are in the process of getting more data about container compatibility, but if you require Container-based authentication, trying Tomcat may assist you in finding what you need. Even with container security integration, we will keep the current database tables as the default implementation (although pluggable security matrices are in the works) since they've been SO convenient and nice to work with. As of this writing , sometimes container integration can be a major hassle, especially when switching from container to container. Staying container independent at this phase, and slowly integrating in as container spec conformance comes about seems like an appropriate plan.

Filtering

Field data entered into an application can have "filters" applied to it automatically to avoid attacks on system security by embedding information in the entered data (such as Javascript or other scripting languages). See more below under string filters.

LDAP Integration

A LDAP component will be available as part of the Expresso Enterprise which includes commercial extensions to Expresso. Individual components of Expresso Enterprise may be purchased separately. A release of Expresso Enterprise will be available sometime in the next quarter. Enables a Tomcat based Expresso solution to handle single sign on (SSO) for all types of web content, from jsp to html/doc/etc, using an LDAP-server. It also enables SSO for multiple web applications under a single Tomcat instance. Users: Can change their password transparently using regular Expresso functionality. Admin: Uses export tool after setting up or changing groups. User information is handled transparently. With some minor coding this can be made to work under any J2EE compliant web container.

SSL and Web Applications

As of Expresso version 5.0, the ability to utilize the ability to enter and exit SSL pages has been automatically added. In this section we cover the basic installation concepts as it applies basic expresso configuration, and then we continue with how to utilize these new features in your own code.

A Super Quick Introduction To SSL

As of Expresso 5.0, the ability to utilize the ability to enter and exit SSL pages has been automatically added. Expresso can now set various states in a controller as secure, by simply in the constructor, call myState.setSecure(true). If this is true, then Expresso will automatically redirect to SSL protocol (or back) without losing session! This is the most critical component in an eCommerce application. The best part about it is that this is backwards compatible. If you do not set useSSL in your context configuration, then even if a state is 'secure' then Expresso will NOT attempt to use SSL.

Why SSL? SSL is an encrypted protocol that allows you to pass data between the webserver and web client without the myriad of computers sitting between you and the webserver being able to find out what communication took place. This is extremely important for any situation where you may have information that you do not want other people to steal just by listening in on your web transaction. Examples include Credit Card information, passwords, personal registration information, and many other possibilities.

Why isn't everything done over SSL then? The biggest answer is price. To set up a secure webserver you have to do several things. First is acquire a digital certificate from a certificate authority such as http://www.verisign.com or http://www.thawte.com/ These cost money for each server you run this one. The more important aspect, however, is that encrypted connections require A LOT more CPU power than a standard non-encrypted password. If a site is completely encrypted, it will be must less responsive than a non-encrypted site.

Therefore, before you really use SSL, you need to decide where in your application you require it. Examples are login pages, online store checkout systems. For the latter example, for instance, you wouldn't necessarily want to encrypt all data between you and the customer concealing what was in their shopping card. But you WOULD want to encrypt the page where the customer includes the credit card.

One final consideration when setting up Expresso security is that you will want both the page that prompts for the secure information AND the page that processes that secure information encrypted over SSL. Otherwise Expresso's features will be unable to automatically compensate for the user's data entry.

Configuring Expresso to use SSL

Configuring your application server.

The steps to configure your application can vary widely. The basic steps are to acquire the appropriate cryptographic libraries and then set up your application server to utilize these libraries.

If you are using Expresso complete or the Tomcat servlet engine, you can download the JSSE cryptographic library at http://java.sun.com/products/jsse/ or if you are running under the JDK version 1.4 or later, JSSE will automatically be included in your system.

You can then configure your servlet engine by following the instructions as provided at the Jakarta Apache site: http://jakarta.apache.org/tomcat/tomcat-4.0-doc/ssl-howto.html. When you are finished configuring your system, you can test it by attempting to go to the link: https://localhost<port number>/ If the Tomcat home or Expresso home page comes up, you've successfully installed SSL onto your webserver.

Setting up the Expresso configuration file

To utilize SSL in your system you need to configure the expresso-config.xml file in two places. The first is to add the following to your <expresso-config> context. After the encryptMode tag, add the following tags:

<httpPort>80</httpPort> <sslPort>443</sslPort>
These define the ports that your webserver is configured for SSL and nonSSL traffic. For example, on a default Tomcat installation httpPort=8080 and sslPort=8443. Please consult your application server's documentation for the proper numbers to add to this location.

The second location is within the context tag. To do this, add the following attribute to the context tag that you wish to secure with SSL:

useSSL="true"
Note that you can define which database contexts use SSL at all and which do not. This gives you an added fine-grain access capability within Expresso.

Coding Expresso to utilize SSL

We've talked a bit about deciding what to secure within your web application. All that you have to do to secure your application once you've decided which controller states is to modify your controller's constructor to utilize secured states. In your constructor once you have created your state with the new operator, secure it with the single line of code: myState.setSecure(true); And that's it! You can test your setup now to make sure you are utilizing SSL capabilities as expected.

Application Security

Any object (servlet or otherwise) can be registered as an application. Applications then have security applied to them in a manner very similar to that of database objects. In addition, applications may have a more detailed level of security, called application methods: For example, if a user is allowed to use the ledger posting application, they might be able to post only their own transactions, or to post any transactions. These "methods" are application specific. The Expresso Framework provides a complete system for applying all of these security facilities, ready to add your own application-specific objects into.

Administrative Security

Any of the table maintenance/administrative functions can be secured. For all table maintenance functions, security is achieved by granting group access to certain database objects, as required for the particular function. Database Object Security can be granted in any of the following degrees:

Table 19.1. Administrative Security

FunctionDescription
AddAdd new records to the table
UpdateUpdate existing records
DeleteRemove records
BrowseView and search existing records

  • Once appropriate administrative privileges have been granted to a group, it is then straightforward to add administrative users to that group as required.

  • A special group called "Everybody" is recognized automatically by the system. This group can be used to grant global permissions, such as universal ability to read the job queue, for example. Use extreme caution in granting access to the Everybody group.

  • For a user to access the privileges assigned to his/her group, they must log in (separate from their regular network login). A user who has not yet logged in is assigned the user login name "Anonymous", which is a member of the "Everybody" group only.

  • A login is valid until the web browser is closed or until the servlet-runner process is restarted. Passwords may be set explicitly via the user administration program, or may be changed by the individual user on the Login web page using the appropriate form.

  • Logging in is only necessary for users not already authenticated by a system logon (i.e. Unix logon or NT domain users).

Database Security

All database objects (which, as we discussed, may or may not have a one-to-one relationship with database tables) have security attributes. A group of users can be granted permission to any combination of Search, Add, Update or Delete security.

This security information is, for performance reasons, read into a cache when the first database connection is made & read from that cache until a change requires it to be re-read. Changing any of the user/group or security tables will cause security to be re-read, and this re-reading takes place as a background thread until it is complete - then the old security information is replaced in a single operation - this prevents partially-read security information causing problems.

Expresso supports row-level authorization. RowSecuredDBObject is the key class. By subclassing RowSecuredDBObject, an application can have authorization checks that vary per row.

The checks within SecuredDBObject correspond roughly to permission checks for an entire database table: users either have access to the entire table or not.

Below is an example of how to programmatically set security for all DBObjects and Controllers in a given schema. You can just override, in your "MySchema.java", the method otherSetup() in superclass Schema.java. This method is run automatically during dbcreate (the "setup" initialization phase that can be run at any time from the admin panel). The example below gives full permissions for any logged in user.

public synchronized void otherSetup(String dbName) throws DBException { // add security for logged-in users Enumeration enumeration = getMembers(); while (enumeration.hasMoreElements()) { DBObject dbObject = (DBObject) enumeration.nextElement(); if (dbObject instanceof SecuredDBObject) { // setup sec. object DBObjSecurity security = new DBObjSecurity(SecuredDBObject.SYSTEM_ACCOUNT); security.setDBName(dbName); security.setField( DBObjSecurity.DBOBJECT_NAME, dbObject.getClass().getName()); security.setField(DBObjSecurity.GROUP_NAME, UserGroup.ALL_USERS_GROUP); for (int j = 0; j < RowSecuredDBObject.ALL_FUNCTIONS.length; j++) { String function = RowSecuredDBObject.ALL_FUNCTIONS[j]; security.setField(DBObjSecurity.METHOD_ALLOWED_CODE, function); security.addIfNeeded(); } // for all functions } // only for secured objects } // all dbobjects in this schema ControllerSecurity sec = new ControllerSecurity(SecuredDBObject.SYSTEM_ACCOUNT); sec.setDBName(dbName); sec.setField(ControllerSecurity.STATES, ControllerSecurity.ANY_STATE_WILDCARD); List list = getControllerList(); for (Iterator iterator = list.iterator(); iterator.hasNext();) { Controller controller = (Controller) iterator.next(); sec.setField( ControllerSecurity.CONTROLLER_CLASS, controller.getClass().getName()); sec.setField(ControllerSecurity.GROUP_NAME, UserGroup.ALL_USERS_GROUP); sec.addIfNeeded(); } } /* otherSetup(String) */

Checks by RowSecuredDBObject provide row-level authorization, providing UNIX-style permissions for the row's owner, group, and others. Thus a user can have access to one row, but not another, within the same table. See more information on RowSecuredDBObject the subsection below.

The checks within DBController correspond roughly to pages, since the central "Run" methods of a DBController are typically one method per page. A user either has access to the page (the DBController method or 'state') or not.

Encryption

Both basic and sophisticated encryption is available for securing any data within the system, so that only authorized users can access the specified data. This deals with the issue of users gaining access to the database server directly and attempting to bypass application security in this manner.

Cross Site Scripting Countermeasures

Expresso uses a two-phase (input and output) filtering mechanism. An EscapeHandler does filtering on DB insertion side. Raw text is saved EXCEPT for what is replaced to accommodate a given DB. For example, DoubleQuoteEscapeHandler.java removes double quotes ("), and escapes single quotes. FilterManager does filtering on the output side. There are 'static' filters and 'instance' filters, which persist in metadata, and only affect a single DBObject filter, respectively.

FilterManager

FilterManager is a singleton class that does translation/filtering of strings when you call getField(). That is, on the way FROM the database, strings are filtered. One of the most common filters is the HtmlFilter. It filters out HTML tags that might be entered by users. A malicious user can enter codes which get returned to a web browser, and these codes can cause the web browser to act on them in a way contrary to what the site author intended--it could be a breach of security. For more on these see: http://www.cert.org/tech_tips/malicious_code_mitigation.html; Understanding Malicious Content Mitigation for Web Developers.

All Filters implement the 3 methods in the Filter interface, which typically have the following implementations (although your Filter can, of course, do whatever you like):

    // Replace control characters with appropriate values, protect against
    // XSS attacks
    public static final String STANDARD_FILTER = "standardFilter";

    // Strip out any unwanted characters, but do not replace them with
    // anything public static final String STRIP_FILTER = "stripFilter";
    // Don't do anything
    public static final String RAW_FILTER = "rawFilter";
 

Setting Filter Characteristics in DBObject

By default, the filter class is HtmlFilter.java, and the method is set to 'standardFilter'. To set the filter method for a field in your DBObject, use setStringFilter(fieldname, filtername) within your setupFields() of the object, like

protected synchronized void setupFields() throws DBException {
    ...
    setStringFilter("myfield", FilterManager.RAW_FILTER);
    ...
}
(There is also DBObject.setStringFilterOnAll() if you want to have the same filter on all fields. Call this AFTER adding all fields in setupFields().)

Note that setStringFilter() sets the filter PERMANENTLY FOR ALL INVOCATIONS for your class because it sets the "metadata" information, which is held statically. If you need some special filtering, on a permanent basis, a different Filter class can be set by getting the metadata and setting DBField.setFilterClass() like

protected synchronized void setupFields() throws DBException {
    ...
    fieldMeta = (DBField) getMetaData().getFieldMetadata("myfield");
    fieldMeta.setFilterClass(HtmlPlusURLFilter.class);
    ...

In order to set the string filter for just an instance, you can use DBObject.setFilterClass(Filter); note the contrast: above was DBField, which is permanent in metadata, and here we are talking about DBObject.setFilterClass(Filter), which only pertains to the instance, the DBObject instance explitly referenced. For example, let's say you have a field which is edited (after initial storage) as a text area, and you want its contents to show up for editing with regular line feeds, instead of <br> for breaks in the text area. You can do the following in some controller which creates the Input for the text area:

    Filter old = existing.setFilterClass(new RawFilter());
    summaryStr = existing.getField("MyField");
    // restore existing.setFilterClass(old);
    Input title = new Input("myinput");
    title.setType(Input.ATTRIBUTE_TEXTAREA);
    title.setDefaultValue(summaryStr);
DBObject.setFilterClass(Filter) changes the Filter class on the instance, but not the filter method, which is specified on the metadata statically. Here we have used RawFilter(), which returns the raw text, no matter what filter method is called on the Filter, no matter what field is accessed. Again, the Filter class applies to all fields. There is currently no way to specify a method name in a per-instance way, or to specify a per-field filter per instance, but from the usage above, such fine-grained approaches may not be necessary.

In addition to HtmlFilter and RawFilter, there is XmlFilter, suitable for generating XML (if you are not using XSL for that), and also HtmlPlusURLFilter. HtmlPlusURLFilter subclassess HtmlFilter, adding an ability to recognize user-entered text which begins with 'http://' or 'www.', etc., and automatically create an anchor (<a>) tag from it.

SQL Injection Countermeasures

Expresso filters and validates all field values that are getting sent to a database. To do this, we put the code through a database escape handler. The escape handler's job is to filter various escape codes and put the appropriate literal value back into the database SQL. Current implementations of the escape handler are:

  • DefaultEscapeHandler - Used by databases such as Postgresql. Escapes ' as \'

  • DoubleQuoteEscapeHandler - Most common filter. Escapes ' as ''

  • MySQLEscapeHandler - mySQL specific escape handler. Performs several escape sequences

The particular escape handler is set in the jdbc section of the expresso-config.xml file.

RowSecuredDBObject

Checks by RowSecuredDBObject provide row-level authorization, providing UNIX-style permissions for the row's owner, group, and others. RowSecuredDBObject extends the idea of group permissions beyond the UNIX-style permissions, in that RowSecuredDBObject allows multiple groups to have different permissions. For example, imagine a row where the owner of a row has read/write/administrate permissions, "others" have just read permissions, group A has read/write permissions, and group B has read permission. A person who is a member of both group A and group B will have write permissions for the row. In a sample application, users could be members of different groups, and could read each other's rows but could not edit row data that their group had not created. This happens without much effort because the default permissions for a row make it writable by the primary group (see User.getPrimaryGroup()) of a user, but only readable by others. Furthermore, when getting a list of rows from a search, only the rows that are readable are returned to the requesting user.

Fundamentally, the idea is that you don't have to do much extra. You establish your groups and group memberships, and then the objects that these groups create have default permissions, allowing reading by others, but writing only by group members. Here is a code snippet for using permissions to determine what to show:

// add link to edit if we have privileges if (myObject.canRequesterWrite()) { Transition trans = new Transition( PROMPT_EDIT_SCORING_MATRIX, "Edit matrix", MatrixAction.class, PROMPT_EDIT_SCORING_MATRIX); trans.addParam(Node.NODE_ID, nodeId); response.add(trans); }

Cookie Encryption

If you use Persistent.setClientAttribute() all cookies sent to the client are encrypted. This significantly increases the ability to guard against cracking the contents of the cookies to reveal items such as passwords.

Note that encryption does not prevent an attack called "replay". In the replay attack, a malicious user grabs a cookie, doesn't crack it's contents, but does send it back to the web server to, for example, gain access as the user of the encrypted cookie. For this reason, sometime's it's better to prevent setting of cookies at login for high security websites.

Tips for Securing a Production Expresso Environment

Expresso has many security features that enable rock-solid deployment options. However, it should always be kept in mind by all system administrators the number one rule about security:

Security Is a Process

What this means is that any application server should be routinely audited, and there will always be new security enhancements available. Routine updates, audits and patches will always be needed. If a company tells you that they have bullet-proof, unpenetrable security..... They're Lying! This list is the start of a checklist to help you secure your Expresso environment:

  • Run your application under the most recent version of the JVM as possible : There are always bugfixes that are included in every new release, and some old bugs may be able to be exploited by a hacker.

  • Install strong encryption: Strong encryption helps prevent attackers from stealing the actual passwords that you may use to log into your system. To get this going, you must set strongCrypto="Y" in the expresso-config.xml file. Then download and install the bouncy castle cryptographic provider. This cryptography library can be found here.

  • Run your expresso setup under a java security policy: As of JDK version 1.2, Java has some extremely fine-grained security possibilities. Things to do with the policy include but are not limited to:

    • Limiting the classes that can access to the file system to only those necessary. This will mainly be limited to the configuration classes and that should be it.

    • Limiting the classes that can make network connection. You also have the ability to determine what ip address you will allow connection from. This is very good if you are running your application server as dependant on another web server (See the Apache Jakarta project for what I mean by this). By and large, you'll only want connections coming in directly from the web server. You'll also want to make sure that only the JDBC client classes, and the classes responsible for connections to the webserver are the only classes allowed to make outbound connections. This way a hacker cannot add a a small class that sends passwords directly to his own site. See your JDK documentation for more information on creating a policy file.

  • Secure the file system: Make sure that the only users that have access to the Application server directories are root for full control, and the account that the Application Server is going to run under for read only and execute control. If you have some directories where the Application Server is going to write files, open that directory, but remember, whever a file can be written to your hard drive is a point of entry that a hacker may come in through. So keep the file system permissions are limited. Also make sure that you have completely restricted access to the Expresso config directory.

  • Secure the database JDBC drivers: Depending on what machine the database is located on, this may be different than the "Run under a security policy" step. Make sure that the db drivers only accept connections from certain sources, and block out all other connection attempts.

  • Employ Firewalls between the internet and your database: It's embarassing if your web server gets defaced..... It's a legal problem if your entire credit card database gets read by a hacker.... Protect your database with every available means.

  • Run the Expresso database user with restricted privliges: Although Expresso does a fine job of saying what users can and can't add/update/delete records. It would be possible to steal the Expresso database config file, log directly into the database and issue a command something like this: DROP TABLE CUSTOMER_ORDERS; COMMIT; So make sure that there are only permissions granted to the Expresso app that coincide with what is absolutely necessary to run.

  • Remove all unnecessary services: Some servlets and services may not be used in a production environment. For example, the runSQL servlet won't probably be used directly. Or maybe your application doesn't use the file download features. Remove every service on your application server that is not required for the web site to function properly.

  • Remove all default passwords: The Openhack Project got cracked simply because somebody forgot to change a default password that comes with Oracle. Make sure you change all passwords for default user accounts. Or better yet, create an Administrative account under a different name, and then delete the default user accounts all together. That way a hacker _has_ to start from scratch.

  • Run security monitoring applications: Most determined hackers will eventually get in. Its just a matter of time. Its best to have a series of Intrusion detection systems in place. This way you can get notified if suspicious activity is going on. Or if you have the budget for it, check out the monitoring service that Counterpane Internet Security offers.

  • Run External Audits: It's next to impossible to see your own mistakes. Have a security firm (or two) do at least a basic audit of your webserver system. This will at least catch some of the more common mistakes you might make in your installation.

  • Make sure that strong crypto is used with the library: By default this is turned on, but unless its very necessary, please don't turn it off.

  • Don't use Windows 95 or Windows 98 for your server!!!!! I'm sorry that this even has to go into this article, but many people think that Personal Web Server / Win98 is secure enough for production use.. THIS IS COMPLETELY UNTRUE!People can gain complete control of a Win95/98 system faster than you can say "What Happened?" If you have to use windows for your server machine, at the very least use Windows 2000, or better yet, NT4 with Service Pack 6. [I know that NT4 is older, but MS added a number of untested features into Win2K that probably won't be ironed out security wise until Service Pack #2 or #3. Once there's enough service packs out there... go for it and ditch NT4]

I repeat that security will always be a process. You will always be having to modify things in your server to make things more secure, even if its just to apply the latest security patches available from various sources. But this document should give you a decent starting point of what to deal with when using a production security environment. If you are unfamiliar with creating production-quality secure machines, please do a search on the internet for things like "Security FAQ" and check out books on security to get a better idea of what you're guarding yourself against, and how best to do it.

Conclusion

Here are a few areas of ehancements coming in new releases:

  • The ability to export security settings so you can set all the security settings you want on your test environment, upload the file to your production environment when you're ready to go online and let 'er rip. Probably displaying the current security settings in an xml file would be most doable...

  • You'll see integration with JAAS coming up...

Contributors

The following persons have contributed their time to this chapter:

Note

Was this EDG documentation helpful? Do you wish to express your appreciation for the time expended over years developing the EDG doc? We now accept and appreciate monetary donations. Your support will keep the EDG doc alive and current. Please click the Donate button and enter ANY amount you think the EDG doc is worth. In appreciation of a $35+ donation, we'll give you a subscription service by emailing you notifications of doc updates; and donations $75+ will also receive an Expresso T-shirt. All online donation forms are SSL secured and payment can be made via Credit Card or your Paypal account. Thank you in advance.

Copyright © 2001-2004 Jcorporate Ltd. All rights reserved.