How can we prevent frame injection in Java application?
Like in a Penetration testing,
it is found that if a hacker drafts a demo html page,
and inside that page he has used iframe,
which has the URL of the working application,
he/she can see the data through that URL/request(created in an iframe).
suppose this is the hackers file, test.html:
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head><body>
<iframe id="inner" src="http://hostname:8080/Application_Name/ABC/DEF/SomePage.jsp?ABC=QWERTYL&XYZ=1&CDE=24" width="600" height="400" scrolling="yes">
</iframe>
</body>
</html>
And now the hacker is able to retrieve the data within the application. How to stop this?
This is clickjacking attack: https://www.owasp.org/index.php/Clickjacking
The simpliest way to prevent it is to add header "X-Frame-Options" with value "DENY". This can be done using filter. Register it in your web.xml and use code like this:
#Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException,
ServletException {
HttpServletResponse response = (HttpServletResponse) resp;
response.addHeader("X-Frame-Options", "DENY");
chain.doFilter(req, resp);
}
All modern browsers support this header, but to protect users with legacy browsers you will need also defensive javascript in the UI. More details: https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet
Related
I am trying to build a site that displays report results based on a date range inputted by the user. First I built the front-end "aesthetics" part of it in HTML/CSS/JS using dummy json data to retrieve the results. Now I am trying to eliminate the json and actually integrate it with the backend, which I have no experience with so am struggling a bit.
Right now I have a Java servlet written, and it works alright. I'm writing the ResultSet from the database query by doing response.getWriter().write(""); Now from what I've seen the next step is to display the results by appending to the URL, but the code that formats and displays it properly is just a div currently. What is the proper way to do this/modify the code?
Sorry if this is a badly written question, I'm not totally sure of all the terminology or best practices, although I'm trying to learn.
EDIT: Currently on the html page I have
$('#gen-report').click(function(){
$("#auction-report").fadeIn({ duration: 400 });
}
In the auction-report div is all of my formatting & elements (charts, displays, etc.) Is there a way to make use of this code instead of having to start my jsp page from scratch?
Put parameters in servlet to request, then invoke forward from request.getRequestDispatcher.
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("now", LocalDate.now());
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/view/test.jsp");
dispatcher.forward(request, response);
}
Now you have access to params which you put in request. Here jsp:
<%# page language="java" contentType="text/html; charset=windows-1255"
pageEncoding="windows-1255"%>
<!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=windows-1255">
<title>Test</title>
</head>
<body>
<h2>Date</h2>
<%= request.getParameter("now") %>
</body>
</html>
Trying to find the best way to make a quasi java-javascript web application. I want to write a java servlet (for the controller and backend) with a jQuery front end. What's the best approach to having these two communicate with each other? I'm used to coding in both but never worked on them together.
Can anybody help me out? I suppose a start would be having a Java Servlet call from jQuery code and getting a response back from the servlet.
Thanks!
Create REST backend using one of JAX-RS implementations (Jersey, RESTeasy etc.). Writing web service with plain old Servlet API is tedious.
You can start learning JAX-RS from here.
Take a look at jQuery's ajax function. Here is a simple example:
// Servlet
#SuppressWarnings("serial")
public class AjaxHandler extends HttpServlet {
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
resp.setContentType("text/plain");
resp.getWriter().print("Hello jQuery!");
}
}
// View.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<title>Insert title here</title>
</head>
<body>
<script>
$(document).ready(function() {
$.ajax({
url : '/AjaxHandler', // servlet mapping ("web.xml")
success : function(responseText) {
$('#ajaxHandlerResponse').text(responseText);
}
});
});
</script>
Servlet's message: <span id="ajaxHandlerResponse"></span>
</body>
</html>
I know that response.sendRedirect() destroys the request/response object and new request is sent to the resource. So how come request.getParameter("") fetches me the value if the earlier request/response object has already been destroyed.
NewFile.HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action ="MyServlet">
<label>Username</label>
<input type="text" name="textbox1"/><br>
<label>Password</label><input type="password" name="textbox2"/>
<input type="submit"/>
</form>
</body>
</html>
Servlet
/**
* Servlet implementation class MyServlet
*/
#WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String user = request.getParameter("textbox1");
String password = request.getParameter("textbox2");
if (user.equals("abc")&&password.equals("123"))
{
response.sendRedirect("NewFile.jsp?name="+user);
}
}
}
Newfile.jsp
<%= "hi there"+request.getParameter("name") %>
I repeated here the comment so you can mark your question as solved by this answer :D
If you are talking about your jsp getting parameter "name"... it's simply because you have put the request directly in the url (NewFile.jsp?name=xuser). If not, I didn't understand your question, please try to be clearer
It is because at very first request, you are getting the parameter, after that you are sending redirect response, if you will do same thing on redirected page or servlet, you will not able to get any thing. In your case, you are sending parameter name with value, so you will be able to get it.
Go to your "NewFile.jsp" page, in that page <%=request.getParameter("name")>.
It will simply get the value you passed in URL("NewFile.jsp?name="+user).
I have written a filter to add some header values to Response object.
The doFilter is setting some header value as shown below
public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain filterChain)
throws IOException, ServletException
{
final HttpServletResponse response = (HttpServletResponse) res;
final HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("X-FRAME-OPTIONS", "SAMEORIGIN");
filterChain.doFilter(req, res);
}
Filter mapping is "/*".
I have index.jsp page as welcome page and this is the only page in my application. I am trying to read the header value set in above method.
My index.jsp is
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#page import="java.util.*" %>
<!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=ISO-8859-1">
<title>Hello world</title>
</head>
<body>
<%
out.println("<br/><br/>XFRAME"+request.getHeader("X-FRAME-OPTIONS"));
%>
<br/>
</body>
</html>
I am getting Null output in the page. I could not get how I got null value if the value is set to "SAMEORIGIN".
XFRAMEnull
can any one help on this.
That's simple, you have added an attribute in the HttpServletResponse headers and expect to read it from the HttpServletRequest headers. That doesn't work that way.
What you need to understand is the HTTP Protocol. The HttpServletRequest is the request coming from the client side to the server while the HttpServletResponse is the response of data and streams coming from the server and translated back to client message (rendered by the browser).
Each headers from either the request/response has information necessary for the server to know what it receives, how to translate the received data and what response to return. Hence why the HttpServletRequest.getHeaders() will almost never be identical to HttpServletResponse.getHeaders() as each of the request/response conforms to the HTTP request/response protocols.
Also, you can never expect to populate a response and magically appear on the request.
I hope this helps.
I know this has been discusses at least a million times here but every servlet was redirecting or flushing the output before calling forward(). I have the same problem but I am not doing anything with the output. My servlet just takes the request parameters and commits to the database and sets an attribute on the request. Then, it forwards the request to a jsp which them displays the attribute. I am using Servlet 3.0 on Tomcat 7. Here is my servlet doPost method followed byt the jsp that this is forwarding to:
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.doPost(req, resp);
DAOFactory daoFactory = DAOFactory.getFactory();
daoFactory.getCompanyDAO().beginTransaction();
Company company = new Company();
company.setName(req.getParameter("companyName"));
company.setContactEmail(req.getParameter("companyEmail"));
company.setContactPhone(new Long(req.getParameter("companyMobile")));
company.setAddressLine1(req.getParameter("companyAddressLine1"));
company.setAddressLine2(req.getParameter("companyAddressLine2"));
company.setCity(req.getParameter("companyCity"));
company.setZipcode(Integer.parseInt(req.getParameter("companyZip")));
company.setState(req.getParameter("companyState"));
company = daoFactory.getCompanyDAO().save(company);
daoFactory.getCompanyDAO().commitTransaction();
Employee owner = new Employee();
owner.setFirstname(req.getParameter("ownerFirstName"));
owner.setLastname(req.getParameter("ownerLastName"));
owner.setEmail(req.getParameter("ownerEmail"));
owner.setMobileNum(new Long(req.getParameter("ownerCellPhone")));
owner.setZipcode(Integer.parseInt(req.getParameter("ownerZip")));
owner.setRole("Employer");
owner.setCompany(company);
daoFactory.getEmployeeDAO().beginTransaction();
owner = daoFactory.getEmployeeDAO().save(owner);
daoFactory.getEmployeeDAO().commitTransaction();
company.addEmployee(owner);
company.setOwnerId(owner.getId());
daoFactory.getCompanyDAO().beginTransaction();
company = daoFactory.getCompanyDAO().save(company);
daoFactory.getCompanyDAO().commitTransaction();
req.setAttribute("company", company);
RequestDispatcher rd = getServletConfig().getServletContext().getRequestDispatcher("/jsp/companyConfirmation.jsp");
rd.forward(req, resp);
}
JSP:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h3>The Company was saved successfully</h3>
<p>
Company name: ${company.name}
</p>
</body>
</html>
I am sure I may have missed something very trivial. I cannot figure out what it is especially when I am not writing anything to the output before forwarding the request.
PS: I also tried putting a return; statement after the forward but no change.
Thanks!
You should remove the super.doPost(req, resp) method call. The default implementation of doPost method from HTTPServlet returns HTTP 405 status code meaning "Method not supported" and that's the response which has been committed. Therefore, you can not forward your request to other jsp.
This is part of the RequestDispatcher.forward(ServletRequest req, ServletResponse resp) method description: "forward should be called before the response has been committed to the client (before response body output has been flushed). If the response already has been committed, this method throws an IllegalStateException. Uncommitted output in the response buffer is automatically cleared before the forward".