Showing posts with label Servlet. Show all posts
Showing posts with label Servlet. Show all posts

5.5.10

HTTPOnly cookie flag

HTTPOnly เป็นวิธีหนึ่งที่ใช้ป้องกัน client side script เข้าถึง cookie โดยที่เราไม่อนุญาตเพื่อป้องกันจุดอ่อนของ web application ที่ลดความเสี่ยงเรื่องของ XSS

เริ่มต้นจาก blog ของนาย Jordan Wiens, "No cookie for you!" (ตอนนี้ไปเป็น CTO ของ white hat security) แล้วถูกนำไป implement ครั้งแรกในปี 2002 ใน browser ของ microsoft internet explorer
ถ้าพูดตามหลักแล้ว HttpOnly เป็นเพียงการเพิ่ม flag ลงใน Set-Cookie HTTP response header แต่ browser จะต้องรองรับ flag นี้ด้วยถึงจะเข้าใจความหมาย

ถ้า HttpOnly flag เพิ่มลงใน Http response header, cookie จะไม่สามารถเข้าถึงได้ผ่าน client side script ผลก็คือถ้าเกิด cross-site scripting (XSS) คือผู้ใช้เผลอกด link ที่ไปเข้าหน้าที่เกิด XSS ตัว browser จะกัน client side script ไม่ให้เข้าถึง cookie ได้ แล้วจะ return เป็น empty string กลับคืนมาให้
ถ้า browser ไม่รองรับ HttpOnly และ website ได้มีการกำหนดค่า HttpOnly ตัว client side script ก็จะสามารถเข้าถึง cookie ได้

ตอนนี้มี browser ที่รองรับได้แก่
  • Internet Explorer 6 sp1+ http://www.petefreitag.com/item/644.cfm
  • Firefox 2.0.0.5+ http://www.petefreitag.com/item/644.cfm
  • Opera since 9.5+ (Prevents Read) http://manicode.blogspot.com/2008/06/opera-95-httponly-read-prevention.html
  • Netscape 9.0b3+

ตัวอย่างการใช้งาน
String sessionId= request.getSession().getId();response.setHeader("SET-COOKIE", "JSESSIONID=" + sessionId + "; HttpOnly");
ใน tomcat 6 เราสามารถกำหนด useHttpOnly=true ใน context.xml ได้

สำหรับ servlet 3.0 รองรับ HTTPOnly เช่นกันผ่าน method
void setHttpOnly(boolean isHttpOnly)boolean isHttpOnly()

Reference:
http://msdn.microsoft.com/en-us/library/ms533046.aspx

26.12.09

Servlet 3.0: Introduction

วันนี้อยู่ว่างๆ อยากลองความสามารถใหม่ของ servlet v.3 แต่ตอนนี้พบว่ายังไม่มี application server ตัวไหนรองรับ นอกจาก GlassFish v.3 เข้าใจว่าตอนนี้ application server ค่ายต่างๆ คงกำลังเร่งพัฒนาความสามารถของตัวเองอย่างเต็มที่เพื่อแย่งชิงส่วนแบ่งการใช้งานตรงจุดนี้
ไม่รอช้าครับ ผมโหลดมาติดตั้งเรียบร้อย

เปิด IDE คู่ใจขึ้นมาลองเลยครับ ถ้าใช้ Eclipse Galileo แล้วเกิดปัญหาไม่สามารถเพิ่ม application server adapter ใหม่ที่เป็น GlassFish v.3 เข้าไปได้ ให้ แก้ตามนี้ ส่วน Netbean ไม่ต้องลีลาเยอะสามารถใช้งานได้เลย

ในเวอร์ชั่นนี้ค่อนข้างให้ความสำคัญกับเรื่องของ annotation ที่จะนำมาเป็นทางเลือกหนึ่งในการ configuration web application ได้ค่อนข้างลงตัวทีเดียว ซึ่งในบทความนี้ผมจะละ deployment description (web.xml) ออกไปแล้วหันมาใช้ annotation แทน

เริ่มกันที่ตัวแรก @WebServlet ใช้เพื่อลงทะเบียน Servlet เพื่อบอกกับ servlet container ว่า class นี้เป็น Servlet class เพื่อให้ servlet container จัดการกับ class ตาม servlet lifecycle ข้างในมี attribute ดังนี้
  • name
  • description
  • value
  • urlPatterns
  • initParams
  • loadOnStartup
  • asyncSupported
  • smalIcon
  • largeIcon

ซึ่งความหมายทุกตัวค่อนข้างชัดเจนอยู่แล้ว ถ้าใครเคยเขียน Servlet v.2 มาก่อนมั่นใจว่าเข้าใจได้โดยไม่ต้องอธิบาย ยกเว้นจะมีแต่ asyncSupported ที่เพิ่งเพิ่มเข้ามาใน Servlet v.3 ในตัวอย่างใช้ urlPatterns เพื่อ mapping กับ url โดยมันเก็บค่าที่เป็น array จึงสามารถ mapping url ได้มากกว่า 1

@WebServlet(urlPatterns="/hello")
public class HelloServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
res.setContentType("text/html");
res.getOutputStream().print("

context path: " + req.getContextPath() + "

");
res.getOutputStream().print("

hello world!

");
}
}
ถ้าต้องการส่ง init parameter ให้กับ servlet หรือ filter ใช้ @WebInitParam ซึ่งมี attribute
  • name
  • value
  • description

ตัวอย่างการใช้งาน

@WebServlet (name="SimpleServlet",
urlPatterns={"/simple"},
initParams={
@WebInitParam(name="name", value="Phamonyut"),
@WebInitParam(name="penname", value="tofu")})
public class SimpleServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
PrintWriter out = res.getWriter();
out.println("name parameter: " + getInitParameter("name"));
out.println("penname parameter: " + getInitParameter("penname"));
}
}
@WebListener ใช้เพื่อลงทะเบียน listener ตามประเภทของ listener ดังนี้
  • Context Listener (javax.servlet.ServletContextListener)
  • Context Attribute Listener (javax.servlet.ServletContextAttributeListener)
  • Servlet Request Listener (javax.servlet.ServletRequestListener)
  • Servlet Request Attribute Listener (javax.servlet.ServletRequestAttributeListener)
  • Http Session Listener (javax.servlet.http.HttpSessionListener)
  • Http Session Attribute Listener (javax.servlet.http.HttpSessionAttributeListener)

ใน @WebListener มี attribute ดังนี้
  • filterName
  • description
  • displayName
  • initParams
  • servletNames
  • value
  • urlPatterns
  • dispatcherTypes
  • asyncSupported

การใช้งาน WebListener (ถ้าไม่ implement listener interface มาจะเกิดข้อผิดพลาดได้)

@WebListener
public class FooApplication implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
System.out.println("inti context");
}
public void contextDestroyed(ServletContextEvent event) {
System.out.println("destory context");
}
}
@WebFilter ไว้ลงทะเบียน filter ซึ่งมี attribute ดังนี้
  • filterName
  • description
  • displayName
  • initParams
  • servletNames
  • value
  • urlPatterns
  • dispatcherTypes
  • asyncSupported


@WebFilter(value="/hello",
initParams={
@WebInitParam(name="message", value="Servlet says:")
})
public class TestFilter implements Filter {
private FilterConfig filterConfig;
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
PrintWriter out = res.getWriter();
out.print(filterConfig.getInitParameter("message"));
System.out.println("call request -> filter");
chain.doFilter(req, res);
System.out.println("call filter <- response");
}
public void destroy() {}
}

@WebServlet(value="/hello")
public class HelloServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
System.out.println("call hello servlet");
PrintWriter out = res.getWriter();
out.println("Hello world!");
}
}

21.12.09

Java Captcha

เพื่อนติดปัญหาช่วยแก้เกี่ยวกับ captcha ลองหาดูพบว่า jcaptcha ใช้งานได้ค่อนข้างดี และ implement ไม่ยากนำไปผูกกับ framework ได้อย่างลงตัว

เริ่มแรกไปโหลด library jCaptcha และ library ที่เกี่ยวข้องมาให้เรียบร้อย
  • commons-collections-3.2
  • commons-logging-1.0.4
  • filters-2.0.235
  • jcaptcha-2.0-alpha-1-SNAPSHOT
  • jcaptcha-api-1.0
  • jcaptcha-integration-simple-servlet-2.0-alpha-1-SNAPSHOT

web.xml ระบุว่า jcaptcha ที่จะทำหน้าที่เป็นตัวสร้างภาพ captcha ตัว class ใด และจะเรียกใช้ผ่าน url อย่างไร


jcaptcha
com.octo.captcha.servlet.image.SimpleImageCaptchaServlet


jcaptcha
/jcaptcha.jpg


ตัวอย่างการเรียกใช้งาน






ฝั่ง server รับไปประมวลผล

PrintWriter pw = response.getWriter();
String userCaptchaResponse = request.getParameter("jcaptcha");
boolean captchaPassed = SimpleImageCaptchaServlet.validateResponse(request, userCaptchaResponse);
if(captchaPassed){
pw.println("good job");
}else{
pw.println("fail");
}

เสร็จเรียบร้อย run ได้เลย