Monday, November 5, 2012

Liferay 6.1.1 GA2 Application Security

1. Web server type and version disclosure.
Risk Impact

Being able to determine precise software versions might aid an attacker in mounting tailored attacks on the server.

Recommendation
It is recommended removing software versions in use from service banners.

Solution
Add the below property in portal-ext.properties
##
## HTTP Header Reponse
##

    #
    # Set the level of verbosity to use for the Liferay-Portal field in the HTTP
    # header response. Valid values are "full", which gives all of the version
    # information (e.g. Liferay Portal Community Edition 6.1.0 CE etc.) or
    # "partial", which gives only the name portion (e.g. Liferay Portal
    # Community Edition).
    #
    http.header.version.verbosity=partial

2.  Auto complete is enabled

 Risk Impact
 Not setting ‘AutoComplete’ attribute can allow attackers to extract valid credentials of previously logged-in users from public computers or multi-user environments.

 Recommendation
 It is recommended to set auto complete functionality to “off” for sensitive input fields.

 Solution
 Add the below property in portal-ext.properties

    #
    # Set this to true to allow users to autocomplete the login form based on
    # their previously entered values.
    #
    company.security.login.form.autocomplete=false

    #
    # Set this to true to allow users to ask the portal to send them their
    # password.
    #
    company.security.send.password=false

 3. Missing HttpOnly Attribute in Session Cookie

 Risk Impact
 In absence of HTTPOnly attribute in the set-cookie parameter, an attacker can exploit this vulnerability to gain information stored in cookie or can launch theft of modification attack by using malicious.

 Recommendation
 It is recommended enabling HTTPOnly feature for session cookies.
   
 Solution
 Add the below configuration for Tomcat {TOMCAT_HOME}\conf\context.xml file.
<Context useHttpOnly="true">

Tuesday, October 16, 2012

Liferay 6.1.1 : Disable simultaneous login from different sessions

Add the below properties in portal-ext.properties

     ##
     ## Live Users
     ##

    #
    # Set this to true to enable tracking via Live Users.
    #
    live.users.enabled=true

    #
    # Set the following to true if users are allowed to have simultaneous logins
    # from different sessions. This property is not used unless the property
    # "live.users.enabled" is set to true.
    #
    auth.simultaneous.logins=false

Monday, October 15, 2012

Disable "Request processed successfully" Message

1. Add this in portlet.xml

<init-param>
    <name>add-process-action-success-action < /name>
    <value>false
< /init-param>

2. If you want to change for a particular action rather than for all actions.

public void addBook(ActionRequest actionRequest,
                                  ActionResponse actionResponse)
                                throws IOException, PortletException {

   ...............
   .................

    String successMsg = "Book added Successfully!";

    SessionMessages.add(actionRequest, "request_processed", successMsg);
}

AUI Form Validation for Alpha and AlphaNumeric


<aui:input name="field1" >
           
    <!-- Only allow alphabetical characters -->
    <aui:validator name="alpha" />
   
</aui:input>

<aui:input name="field2" >
           
    <!-- Only allow alphanumeric characters/digits -->
    <aui:validator name="alphanum" />
   
</aui:input >

AUI Form Validation For file uploads with extension

<aui:input type="file" name="field2" >

    <!--
    For use with input type="file"
    Only allow file uploads with this extension.
    Specify multiple values either comma delimted 'jpg, png',
    whitespace delimited 'jpg png', or pipe 'jpg|png' delimited.
    Do not include the period before the extension
    -->
    <aui:validator name="acceptFiles">
        'jpg, png'
    </aui:validator>
   
</aui:input>

AUI Form Validator Taglib

< aui:input name="field1" >
    <!-- Example with multiple validators -->

    <!-- Make the field required. If the field is empty, form will not submit -->
    <aui:validator name="required" />

    <!-- Only allow digits in the field -->
    <aui:validator name="digits" />

    <!-- Make sure field value is between 1 and 100 characters in length -->
    <aui:validator name="range" >
    [1,100]
    </aui:validator >

</aui:input >

Wednesday, July 25, 2012

liferay-ui:discussion with custom portlet (MVCPortlet)

liferay-ui:discussion with custom portlet(MVCPortlet / Liferay 6.1)

Add the below code in view.jsp


<%

 WindowState windowState = null;
 PortletMode portletMode = null;
 PortletURL currentURLObj = null;
 if (renderRequest != null) {
          windowState = renderRequest.getWindowState();
          portletMode = renderRequest.getPortletMode();
          currentURLObj = PortletURLUtil.getCurrent(renderRequest, renderResponse);
} else if (resourceRequest != null) {
         windowState = resourceRequest.getWindowState();
          portletMode = resourceRequest.getPortletMode();
          currentURLObj = PortletURLUtil.getCurrent(resourceRequest, resourceResponse);
 }

String currentURL = currentURLObj.toString();

 %>


Add the below invokeTaglibDiscussion method in YourPortletClass. java

public void invokeTaglibDiscussion(ActionRequest actionRequest, ActionResponse actionResponse) throws Exception {

PortletConfig portletConfig = getPortletConfig();

 PortalClassInvoker .invoke(true, "com.liferay.portlet.messageboards.action.EditDiscussionAction",       
                  "processAction", new String[] {
                                  "org.apache.struts.action.ActionMapping",
                                  "org.apache.struts.action.ActionForm",
                                  PortletConfig.class.getName(),
                                  ActionRequest.class.getName(),
                                 ActionResponse.class.getName()
                  }, null, null, portletConfig, actionRequest, actionResponse);
}

Monday, February 14, 2011

jQuery ajax with liferay 6.0.5

jQuery ajax with liferay 6.0.5



<portlet:actionURL var="ajaxURL" name="add" windowState="< %= LiferayWindowState.EXCLUSIVE.toString()%>" />


<form action="" name="fm" id="fm" method="post">
    <a href="#" onclick="submitForm();">confirm < /a>
</form>


<script type="text/javascript" >
    function submitForm(){
        jQuery.ajax({
          type: 'POST',
          url: '<%= ajaxURL % >',
          success: function(data){
              jQuery('#p_p_id<portlet:namespace/ > .portlet-content').html(data);
          }
        });
    }
</script >

Alloy UI with Ajax

<portlet:actionURL var="ajaxURL" name="add" windowState="< %= LiferayWindowState.EXCLUSIVE.toString()%>" />


<form action="" name="fm" id="fm" method="post">
    <a href="#" onclick="submitForm();">confirm < /a>
</form>

<aui:script use="aui-io-request,aui-node" >
    Liferay.provide(
            window,
            'submitForm',
            function() {
               var A = AUI();
            A.io.request('<%= ajaxURL % >', {
              on: {
               success: function() {
                       A.one('#p_p_id<portlet:namespace/ >.portlet-content').html(this.get('responseData'));
               }
              }
            });
        });
</aui:script >
 Liferay Portal 5.2 Systems Development

Monday, January 31, 2011

Custom Sql in Liferay Plugin Portlet

Create a Custom Query in Plugin Portlet for Liferay Models(Liferay 6.0.x).

Step 1 :- Creating a library portlet
===========================

In the $PLUGINS_SDK/portlets(Windows)

create library-portlet "Library"

Step 2 :-

in portlet.xml

< portlet-class > com.liferay.util.bridges.mvc.MVCPortlet < /portlet-class >
replace with
< portlet-class > com.mpower.action.LibraryPortlet < /portlet-class >


Step 3 :-


Create service.xml under docroot/WEB-INF


< ?xml version="1.0" encoding="UTF-8"? >
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.0.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_0_0.dtd" >
< service-builder package-path="com.mpower" >
< author > Arun Kumar < /author >
< namespace > library < /namespace >
< entity name="Book" local-service="true" remote-service="false" >
< column name="bookId" type="long" primary="true" / >
< column name="name" type="String" / >
< column name="author" type="String" / >
< order by="asc" >
< order-column name="name" case-sensitive="false" / >
< /order >
< /entity >
< /service-builder >



Step 4 :-

a. Create a folder custom-sql under src

b. Create a file default.xml under src/custom-sql

< ?xml version="1.0"? >
< custom-sql >
< sql file="custom-sql/book.xml" / >
< /custom-sql >

c. Create a file book.xml, under src/custom-sql

< ?xml version="1.0"? >
< custom-sql >
< sql id="findBooks" >
< ![CDATA[
SELECT
*
FROM
library_book
WHERE
(library_book.name like ?)
]] >
< /sql>
< /custom-sql >

Step 5 :-

Create the file "BookFinderImpl.java" under service/persistence

public class BookFinderImpl extends BasePersistenceImpl implements
BookFinder {

}


Do ant build-service to generate necessary files.



Step 6 :-

Now write the logic to access the custom sql


public List findBooks(String name) throws SystemException {
Session session = null;
try {
session = openSession();
String sql = CustomSQLUtil.get(FIND_BOOKS);
SQLQuery query = session.createSQLQuery(sql);
query.addEntity("Book", BookImpl.class);
QueryPos qPos = QueryPos.getInstance(query);
qPos.add(name);
return (List)query.list();
}catch (Exception e) {
}
return null;
}

public static String FIND_BOOKS = "findBooks";



*** Make the necessary imports.


import java.util.List;

import com.liferay.portal.kernel.dao.orm.QueryPos;
import com.liferay.portal.kernel.dao.orm.SQLQuery;
import com.liferay.portal.kernel.dao.orm.Session;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.service.persistence.impl.BasePersistenceImpl;
import com.liferay.util.dao.orm.CustomSQLUtil;


Step 7 :-

Now write the method in BookLocalServiceImpl.java


public class BookLocalServiceImpl extends BookLocalServiceBaseImpl {

public List findBook(String name) throws PortalException,
SystemException, RemoteException {

return BookFinderUtil.findBooks("%" + name + "%");
}


run ant build-service , this will update the corresponding api with new method defined.

Step 8 :-

a. Create init.jsp under docroot and add the below content


< %@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" % >
< %@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" % >
< portlet:defineObjects / >
< %@ page import="com.mpower.service.BookLocalServiceUtil" % >
< %@ page import="com.mpower.model.Book" % >
< %@ page import="java.util.*" % >

b. Create result.jsp under docroot/


< %@page import="com.liferay.portal.kernel.util.Validator"% >
< %@ include file="init.jsp" % >

<% List books = (List) request.getAttribute("result");
if(Validator.isNull(books))books = new ArrayList();

%>

< liferay-ui:search-container delta="10" emptyResultsMessage="no-books-were-found" >
< liferay-ui:search-container-results
results="< %= books % >"
total="< %= books.size( )% >"
/>

< liferay-ui:search-container-row className="com.mpower.model.Book" modelVar="book" >

< liferay-ui:search-container-column-text
name="Book Title"
property="name"
/ >

< liferay-ui:search-container-column-text
name="Author"
property="author"
/ >

< /liferay-ui:search-container-row >

< liferay-ui:search-iterator / >

< /liferay-ui:search-container >


C. Update the view.jsp

< %@ include file="init.jsp" % >
< portlet:actionURL var="findURL" name="findBooks" / >

< form action="< %= findURL.toString() % >" name="fm" method="post" >


< label > Book Title < /label > < input name="title" value=""/ > < input type="submit" value="Search"/ >

< /form >


d. Create the portlet class LibraryPortlet.java under src/com/mpower/action


package com.mpower.action;

import java.io.IOException;
import java.util.List;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;

import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;
import com.mpower.model.Book;
import com.mpower.service.BookLocalServiceUtil;

public class LibraryPortlet extends MVCPortlet{

public void findBooks(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {

String name = ParamUtil.getString(actionRequest, "title");

try {
List books = BookLocalServiceUtil.findBook(name);
actionRequest.setAttribute("result", books);
actionResponse.setRenderParameter("jspPage", "/result.jsp");
} catch (PortalException e) {
e.printStackTrace();
} catch (SystemException e) {
e.printStackTrace();
}


}
}




run "ant deploy" and check the search functionality in Library portlet.