Runtime.getRuntime() inside JSP and security - shell

From a JSP, I need to call a shell Unix.
To do that I tried the following code as an example :
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<%
try {
Runtime runtime = Runtime.getRuntime();
Process exec = runtime.exec(new String[]{"/path/to/shell/myshell.sh", "param1", "param2"});
int i = exec.waitFor();
System.out.println(i);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
%>
hi
</body>
</html>
All is ok, my shell is correctly called by the JSP, and the JSP got in return the correct value.
Although the code is executed on the server side, is it a problem for security to call shell Unix from JSP ? Are there any prerequisites about it ?

Related

"Server error" while hitting a URL from controller in SAP Hybris

I am trying to practice SAP Hybris basic flow and while hitting the URL from the controller I am getting a "server error" as the response as shown below.
The controller looks something like this:
#Controller
public class NewCustomerController {
#RequestMapping(value = "/custid", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String getCustomerNameFromCustId(#RequestBody final Model model){
final List<NewCustomerData> nameList = newCustomerFacade.getCustomerNamefromID();
model.addAttribute("nameList",nameList);
return ControllerConstants.Views.Pages.NewCustomer.CustId;
}
}
The JSP page "custid.jsp" looks something like this:
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%# taglib prefix="" tagdir="" %>
<html>
<head>
<title>Customer ID detail</title>
</head>
<body>
<h1>This page displays the name of the customer based on customer ID</h1>
<h3>The name of the customer is ${nameList}.<h3>
</body>
</html>
In the dao layer, when I evaluate the call to execute the query, I get this error:
Can anyone help me please what am I doing wrong? I am stuck on this since 2 days now.

First ajax portlet shows the seconds ones response

I am new to liferay. I want two portlet to fetch data from the two different tables of the database. The data has to be fetched automatically without refreshing the page(using ajax). The problem is the portlets I created are fetching the data and showing it properly, if one of them is deployed in a page. If both of them are deployed then they are showing the second portlets tables data i.e if only one portlet is in the portal its showing the correct data (the specific portlet's table) and automatically fetching, if both are in portal they are fetching the second deployed portlet's data(showing same data for both portlets).
Here is the jsp code of both of my portlet, I am using service builder for fetching data.
Portlet A
view.jsp
<%#page contentType="text/html"%>
<%#page pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%# taglib uri="http://alloy.liferay.com/tld/aui" prefix="aui"%>
<%# taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui"%>
<%# page import="javax.portlet.PortletContext"%>
<%# page import="com.liferay.portal.kernel.portlet.LiferayWindowState"%>
<%# page import="javax.portlet.RenderRequest"%>
<%# page import="java.util.*"%>
<%# page import="javax.portlet.*"%>
<portlet:defineObjects />
<portlet:actionURL
windowState="<%=LiferayWindowState.EXCLUSIVE.toString()%>"
var="fetchDatabase">
<portlet:param name="databaseFetch" value="fetchWorkData"></portlet:param>
</portlet:actionURL>
<%
PortletPreferences prefs = renderRequest.getPreferences();
%>
<script type="text/javascript">
var url = '<%=fetchDatabase.toString()%>';
$(document).ready(function() {
$("#fetchLink").click(function() {
$.post(url).done(function(data) {
$("#fetchData").html(data);
});
});
});
$(document).ready(function() {
//For Initial loading of database
$('#fetchData').load(url);
function timeRefresh() {
// setTimeout("location.reload(true);",timeoutPeriod);
// make a ajax call here.
$.post(url).done(function(data) {
$("#fetchData").html(data);
});
}
//Recalling the function repeatedly in given interval
setInterval(function() {
timeRefresh();
}, 6000);
});
</script>
<aui:layout id="fetchedData">
<aui:button value="Refresh" id="fetchLink"></aui:button>
<hr />
<aui:layout id="fetchData"></aui:layout>
</aui:layout>
FetchData.java
package com.cherry.ajax.database;
import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import com.cherry.ajax.database.service.TestLocalServiceUtil;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.util.bridges.mvc.MVCPortlet;
/**
* Portlet implementation class FetchData
*/
public class FetchData extends MVCPortlet {
String action = "";
#Override
public void processAction(ActionRequest request, ActionResponse response)
throws IOException, PortletException {
action = request.getParameter("databaseFetch");
try {
TestLocalServiceUtil.add();
} catch (SystemException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void doView(RenderRequest request, RenderResponse response)
throws IOException, PortletException {
response.setContentType("text/html");
PortletRequestDispatcher dispatcher = null;
if (action.equals("fetchWorkData")) {
dispatcher = getPortletContext().getRequestDispatcher(
"/html/jsp/showData.jsp");
} else {
dispatcher = getPortletContext().getRequestDispatcher(
"/html/jsp/view.jsp");
}
action = "";
dispatcher.include(request, response);
}
}
Portlet B
view.jsp
<%#page contentType="text/html"%>
<%#page pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%# taglib uri="http://alloy.liferay.com/tld/aui" prefix="aui"%>
<%# taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui"%>
<%# page import="javax.portlet.PortletContext"%>
<%# page import="com.liferay.portal.kernel.portlet.LiferayWindowState"%>
<%# page import="javax.portlet.RenderRequest"%>
<%# page import="java.util.*"%>
<%# page import="javax.portlet.*"%>
<portlet:defineObjects />
<portlet:actionURL
windowState="<%=LiferayWindowState.EXCLUSIVE.toString()%>"
var="workloadUrl">
<portlet:param name="drAction" value="getWorkData"></portlet:param>
</portlet:actionURL>
<%
PortletPreferences prefs = renderRequest.getPreferences();
%>
<script type="text/javascript">
var url = '<%=workloadUrl.toString()%>';
$(document).ready(function() {
$("#workloadLink").click(function() {
$.post(url).done(function(data) {
$("#drData").html(data);
});
});
});
$(document).ready(function() {
//For Initial loading of database
$('#drData').load(url);
function refresh() {
// setTimeout("location.reload(true);",timeoutPeriod);
// make a ajax call here.
$.post(url).done(function(data) {
$("#drData").html(data);
});
}
//Recalling the function repeatedly in given interval
setInterval(function() {
refresh();
}, 6000);
});
</script>
<aui:layout id="DrWorkload">
<aui:button value="Refresh" id="workloadLink"></aui:button>
<hr />
<aui:layout id="drData"></aui:layout>
</aui:layout>
DrStatus.java
package com.cherry.ajax.database;
import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import com.cherry.ajax.database.service.WorkloadLocalServiceUtil;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.util.bridges.mvc.MVCPortlet;
/**
* Portlet implementation class DrStatus
*/
public class DrStatus extends MVCPortlet {
String action = "";
#Override
public void processAction(ActionRequest request, ActionResponse response)
throws IOException, PortletException {
action = request.getParameter("drAction");
try {
WorkloadLocalServiceUtil.check();
} catch (SystemException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void doView(RenderRequest request, RenderResponse response)
throws IOException, PortletException {
response.setContentType("text/html");
PortletRequestDispatcher dispatcher = null;
if (action.equals("getWorkData")) {
dispatcher = getPortletContext().getRequestDispatcher(
"/html/drstatus/workloadData.jsp");
} else {
dispatcher = getPortletContext().getRequestDispatcher(
"/html/drstatus/view.jsp");
}
action = "";
dispatcher.include(request, response);
}
}
Please suggest me if I am doing any thing wrong ...
Thanks in advance
Samith K S
The problem is most likely that you have two DOM elements with the same ID (from both portlets). This is a common problem in portals: You never know whom you share the page with, thus you'll have to generate guaranteed-to-be-unique identifiers.
One way to do this is to use the output of <portlet:namespace/> - this is a standardized tag that generates a unique value per portlet. It's always identical within the same portlet. Then use this to generate your ID values:
<div id="<portlet:namespace />fetchData">
...
</div>
<script type="text/javascript">
var url = '<%=fetchDatabase.toString()%>';
$(document).ready(function() {
$("#fetchLink").click(function() {
$.post(url).done(function(data) {
$("#<portlet:namespace />fetchData").html(data);
});
});
});
Note: I've only used this on your example fetchData, not yet on fetchLink - that'll be your task now that you know what goes wrong :)
As you state in your comment, the same holds for variable names that end up as global variables in the DOM: Be aware that they all share the same HTML document in the end - one way to work around this is to use <portlet:namespace/> to "decorate" variable names as well, but the resulting code is ugly and hard to maintain. This is part of the reason why Liferay ended up with AlloyUI as replacement for jQuery: AUI defaults to namespacing and enables dynamic module loading. Within one namespace you didn't rely on global variables but have the variables local to that one block - including the modules that you wanted to load:
AUI().use('node', 'module2', 'module3', function (A) {
A.foo.bar()
// this variable is scoped to just this function
// no conflict with other content on the same page!
var someVariable = 'something';
doSomething();
});
As a rule, in Javascript, you should call your <aui:> components like
$('#<portlet:namespace/>aui_component_id')
If you view your html source, you'll see that all <aui> components have the 'portlet_id' as prefix in the 'id' attribute
Also, I can't understand hoe you make that work by using processAction, that is called from actionUrls. You need the 'resource' phase to fetch data without refreshing the page, so you'll need to override the MVCPortlet's serveResource function, and call it in your jsp's by calling resourceUrls
Thank you all of your resopnse.
I figure out what the problem is.
I am using same variable name for the both portlets urls (var url = '<%=workloadUrl.toString()%>'; && var url = '<%=fetchDatabase.toString()%>';).
I changed the variable name of the second portlet and now its working.
I didn't know I can't use same variable names in different portlets.

Servlet to jsp communication best practice

I'm learning how to write java servlets and jsp pages on google app engine. I'm attempting to use an MVC model but I'm not sure if I'm doing it right. Currently, I have a servlet that is called when a page is accessed. The servlet does all the processing and creates a HomePageViewModel object that is forwarded to the jsp like this:
// Do processing here
// ...
HomePageViewModel viewModel = new HomePageViewModel();
req.setAttribute("viewModel", viewModel);
//Servlet JSP communication
RequestDispatcher reqDispatcher = getServletConfig().getServletContext().getRequestDispatcher("/jsp/home.jsp");
reqDispatcher.forward(req, resp);
Over on the jsp side, I have something like this:
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<%# page import="viewmodels.HomePageViewModel" %>
<%
HomePageViewModel viewModel = (HomePageViewModel) request.getAttribute("viewModel");
pageContext.setAttribute("viewModel", viewModel);
%>
<html>
<body>
<% out.println(((HomePageViewModel)pageContext.getAttribute("viewModel")).Test); %>
</body>
</html>
So my question is two fold. First, is this a reasonable way to do things for a small webapp? This is just a small project for a class I'm taking. And second, in the jsp file, is there a better way to access the viewmodel data?
If you adhere the Javabeans spec (i.e. use private properties with public getters/setters),
public class HomePageViewModel {
private String test;
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
}
then you can just use EL (Expression Language) to access the data.
<%# page pageEncoding="UTF-8" %>
<html>
<body>
${viewModel.test}
</body>
</html>
See also:
Our Servlets wiki page
Our JSP wiki page
Our EL wiki page
How to avoid Java code in JSP files?

request.getParameter() returns null

Got a homework assignment that is giving me problems.... Its modifying a JSF project with two pages and a bean to fit MVC2 by adding two more pages and a controller servlet and another bean for the two additional pages. the new main page forwards to either the second new page or the old first page. My issue is response.getParameter() always results in null.
<%#page session="false" import="java.util.Iterator"%>
<%#taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%#taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<jsp:useBean id="status" scope="request" class="JSFRegistration.Status" />
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>JSP Page</title>
</head>
<body>
<% if (status!=null && !status.isSuccessful()){%>
<font color="red">Processing errors:
<ul><%Iterator errors=status.getExceptions();
while (errors.hasNext()){
Exception e = (Exception) errors.next();%>
<li><%= e.getMessage()%><%}%></ul></font><%}%>
<form action="LoginServlet" method="POST">
<% String username = request.getParameter("username");
if (username==null) username="";%>
<input type="text" name="usernameTF" value="<%=username%>" />
<% String password = request.getParameter("password");
if (password==null) password="";%>
<input type="password" name="passwordTF" value="<%=password%>" />
<input type="submit" value="Login" />
</form>
</body>
</html>
this is basically a direct copy from our book but the fields I need for the new main page. Same for the controller servlet, a direct copy except only contains the fields I need.
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
RequestDispatcher view = null;
Status status = new Status();
request.setAttribute("status", status);
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username==null || username.length()==0)
status.addException(new Exception("Please enter username"));
if (password==null)
status.addException(new Exception("Please enter password"));
if (!status.isSuccessful()){
view = request.getRequestDispatcher("Login.jsp");
//view.forward(request, response);
}
else
try{
request.setAttribute("username", username);
request.setAttribute("password", password);
view = request.getRequestDispatcher("Registration.jsp");
} catch (Exception e) {
status.addException(new Exception("Error"));
view = request.getRequestDispatcher("Login.jsp");
}
view.forward(request, response);
}
and the Status class, again a direct copy from the book.
public class Status {
private ArrayList exceptions;
public Status(){
exceptions = new ArrayList();
}
public void addException(Exception exception) {
exceptions.add(exception);
}
public boolean isSuccessful(){
return (exceptions.isEmpty());
}
public Iterator getExceptions(){
return exceptions.iterator();
}
regardless of what is typed into the two boxes, stepping through a debug shows the values not getting passed to the parameters. I get the created exceptions printed above the screen for both fields if both have text, if only one has text and when both are empty.
Your request parameter names do not match the input field names. You've assigned the input fields a name of usernameTF and passwordTF. They are then available by exactly those names as request parameter, but you're attempting to get them using the names username and password. So you need either to fix the input field names, or the request parameter names so that they match each other.
By the way, why falling back from a modern MVC framework like JSF to awkward 90's style JSP with mingled business code? Is that really what the homework assignment is asking you? Also the HTML <font> element is deprecated since 1998. Where did you learn about it? Is the quality of the course really good?

spring mvc addAttribute to model, how to get it from jsp javascript

i have a controller with a model which i do addAttribute("show", "yes");
how do I retrieve this value inside javascript?...assuming I have jstl
Inserting it in a javasript would be the same as showing it in the html code of the jsp.
Try to do this:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
Show value is <c:out value="${show}"/>
if you can see the value in the JSP then JSTL is working. In any other case there may be another problem. For example that your configuration ignores EL. You can add this at the top of your JSP:
<%# page isELIgnored="false" %>
When you see the value in the HTML code then the JSTL is working in that case you can use it in Javascript. As your setting the value for tha variable "show" to yes it cannot be used as a boolean value (because it should be true or false). In this case you should use it as a string adding quotations
<script type="text/javascript">
var showVar = '<c:out value="${show}"/>';
alert("The variable show is "+showVar);
</script>
You can use Firebug to check that your javascript is working and you don't have any error on it.

Resources