Search: Home Bugtraq Vulnerabilities Mailing Lists Jobs Tools Vista
      Digg this story   Add to del.icio.us   (page 2 of 2 ) previous 
Building Secure Applications: Consistent Logging
Rohit Sethi and Nish Bhalla 2007-02-26

Article continued from Page 1

Defense using a centralized handler

One approach to resolving these issues is to design a centralized logging handler within the application logic. Create a static Singleton (named “AppLog” for discussion purposes). AppLog would essentially be an adapter between the current application and a log file analysis tool. AppLog would, at a minimum, provide four publicly accessible methods:

  • AppLog.logDebugMessage(logMessage, logPriority, callingObject)
  • AppLog.logSecurtyMessage(logMessage, logPriority, callingObject)
  • AppLog.logBusinessLogicError(logMessage, logPriority, callingObject)
  • AppLog.logSystemMessage(logMessage, logPriority, callingObject)

This syntax forces developers to choose a log type rather than simply choose a priority, and the logPriority parameter allows them to retain the ability to choose a priority level. The callingObject parameter (of Object type) will allow the AppLog to automatically append the class of the calling object. Furthermore, the AppLog code can add the syntax parameters required for a particular log file analysis tool before actually writing to a file or using the existing tools such as Log4J and Log4Net; new AppLog subclasses can be built for each analysis tool. Other than the implementer(s) of AppLog and its subclasses, individual developers do not need to be aware of the required syntax of external analysis tools.

This alone, however, does not solve the problems listed above. Two developers could still send very different messages to the logSecurityMessage() function. To solve this, developers should add specific methods to AppLog for particular security events, such as logInvalidAccessAttempt(user_id, timestamp, callingObject) and logSQLInjectionAttempt(user_id, timestamp, maliciousChar, inputString, callingObject). This function would construct a specific message and call the logSystemMessage function. The final logged event might look something like this:

"code:312,app:MyApp,event:Invalid_auth_attempt,user:admin,time:3713252,
calling-obj:com.mycompany.package.MyClass"

This syntax is meaningful to a particular log file analysis tool, and if the tool ever changes then it is simply a matter of changing the functions within AppLog or sub-classing AppLog rather than updating all logging calls across the application. Developers from different modules will have the same syntax for logging an invalid access attempt since there is no guesswork about which English-language phrase to use to describe the attempt (such as, “Login failed”).

Revisiting the SQL injection example, two disparate calls to the central logger with both call the logSQLInjectionAttempt and the resulting log file might look something like:

1st event:
"code:312,app:MyApp,event:sql_injection_attempt,user:myuser1,mal-char:"-
",input-string:" Some description' OR 1=1 --; ",time:371245,calling-
obj:com.mycompany.DAO.CustomerDAO"

2nd event:
"code:312,app:MyApp,event:sql_injection_attempt,user:myuser1,mal-char:"-
",input-string:"An order name' OR 1=1 --;",time:371253,calling-
obj:com.mycompany.DAO.OrderDAO"

Administrators could configure the log file analysis tool to recognize that there were two or more SQL injection attempts made by a single user within a short time – a task greatly facilitated by a consistent logging format. Of course if your application is attacked like this on a regular basis, perhaps sending an alarm after two SQL injection attempts may make this analysis more of an annoyance to operational staff than an effective security feature. In that case, administrators can simply configure the tool to send an alert for a more substantial number such as 100 or 1000 injection attempts.

Logging – an infrastructure responsibility?

Some people will argue that this is the wrong approach to solving the problem of application-layer logging. They maintain that this functionality should be handled somewhere within the infrastructure (such as a LDAP directory or web-application firewall). While there is merit in striving to take away security concerns from the developer as much as possible, it’s not always possible in every architecture to log security issues at the infrastructure level (as with a proprietary SQL authentication database for a single application, custom session management, and so on). Furthermore, there are certain instances where it’s just not possible to detect these attacks without applying application logic (e.g. somebody entering in the wrong value for a CAPTCHA image during a registration page). Ultimately the developer will always share some responsibility for recognizing security-relevant events along with the infrastructure.

A low-cost investment

Apart from the costs of the log-file analysis engine itself, building this kind of logging functionality is a relatively inexpensive exercise. Implementation only requires drafting a standard, building a simple adapter tool that adheres to the standard, and disseminating those standards to the developers. Even if a log file analysis tool will not be used in the near future, augmenting the design of an application will allow it to take advantage of the functionality quickly if such a tool is eventually used. In addition, standardization will facilitate manual review of the logs by making them easier to read. Most enterprise developers will concede that they only use their application-layer logs as a last-resort for troubleshooting, and that sorting through them is time-consuming and cumbersome due to their colossal size and haphazard syntax. In the case of manual analysis, consider creating the logs in an easily parse-able format such as CSV so that they can be analyzed with your favorite spreadsheet application.

Refactoring costs

Some developers and architects will point out that there are significant costs and risk associated with refactoring code. If implemented properly, standardized logging should have minimal impact on functionality and thereby be a relatively low risk change since it is generally only changing the syntax of non-functional code (such as logging calls).

That being said, for applications in the order of tens of thousands or hundreds of thousands of lines of code, this seemingly simple refactoring exercise could indeed turn into a Herculean effort. In those cases, consider starting off by only implementing the new logging standards to the security-sensitive areas (such as: authentication, authorization, session management, input validation, configuration, administration, etc.), and make sure that any newly introduced code continues to adhere to the new format.

Taking a proactive approach to application security is a cost-effective approach to good IT governance and it starts with building secure applications.

For more information on Log4J please see http://logging.apache.org/log4j/docs/ and for Log4net please see http://logging.apache.org/log4net/.

About the authors

Rohit Sethi & Nish Bhalla are leading application security consultants at Security Compass.

Reprints or translations

Reprint or translation requests require prior approval from SecurityFocus.

© 2007 SecurityFocus

Comments?

Public comments for Infocus technical articles, as shown below, require technical merit to be published. General comments, article suggestions and feedback are encouraged but should be sent to the editorial team instead.



SecurityFocus accepts Infocus article submissions from members of the security community. Articles are published based on outstanding merit and level of technical detail. Full submission guidelines can be found at http://www.securityfocus.com/static/submissions.html.
    Digg this story   Add to del.icio.us   (page 2 of 2 ) previous 
Comments Mode:







 

Privacy Statement
Copyright 2007, SecurityFocus