Modifying HTML and JSP - java

How can I add a HTML comment on every HTML and JSP page?
I've tried to modify it with a filter and it could only modify the JSP pages and not the HTML pages.
I used a filter like this:
package com.app.server.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
public class WaterMarkFilter implements Filter {
private List<String> extensionsToFilter = new ArrayList<>();
#Override
public void init(FilterConfig filterConfig) throws ServletException {
String[] extensions = filterConfig.getInitParameter("extensionsToFilter").split(",");
for (String extension : extensions) {
extensionsToFilter.add(extension.trim());
}
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
postFilter(request, response);
}
#Override
public void destroy() {
}
private void postFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
String path = ((HttpServletRequest) request).getRequestURI();
if (canIntercept(path)) {
response.getWriter().write("modified");
response.getWriter().close();
}
}
private boolean canIntercept(String path) {
if (path.equals("/")) {
return true;
}
for (String extension : extensionsToFilter) {
if (path.endsWith("." + extension)) {
return true;
}
}
return false;
}
}
This is the Web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>com.app.configuration ShoppingCartService</servlet-name>
<servlet-class>com.app.server.servlet.ShoppingCartServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>com.app.configuration ShoppingCartService</servlet-name>
<url-pattern>/application/ShoppingCartServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>test</servlet-name>
<servlet-class>com.app.server.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/application/test</url-pattern>
</servlet-mapping>
<listener>
<listener-class>com.app.server.ApplicationInitializer</listener-class>
</listener>
<filter>
<filter-name>WaterMarkFilter</filter-name>
<filter-class>com.app.server.filter.WaterMarkFilter</filter-class>
<init-param>
<param-name>extensionsToFilter</param-name>
<param-value>jsp, html</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WaterMarkFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

The actual question is how to manipulate the ServletResponse using Filter.
My detailed answer with full code example and many links is here
Short:
In the doFilter implementation:
before the chain.doFilter call, prepare a HttpServletResponseWrapper and a PrintWriter
after the call, write in the PrintWriter a copy of the wrapped response + "the text you want"
Bellow are the code changes in order the filter to work with HTML too:
public class WaterMarkFilter implements Filter {
private ServletRequest request;
private PrintWriter out;
private CharResponseWrapper wrapper;
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
this.request = request;
out = response.getWriter();
wrapper = new CharResponseWrapper((HttpServletResponse) response);
chain.doFilter(request, wrapper);
postFilter();
out.close();
}
private void postFilter() throws IOException, ServletException {
String path = ((HttpServletRequest) request).getRequestURI();
if (canIntercept(path)) {
out.write(wrapper.toString() + "modified");
}
else {
out.write(wrapper.toString());
}
}
}
The CharResponseWrapper is the same as in my detailed answer here.
There is also a better example how to include text into already created html.
Just adding text at the end is good only for plain text files.
For HTML - It is better to insert the text inside the HTML. The example there is with <head> tag, but it could be adapted to insert to <body> tag.

Related

Missing HSTS header in checkmarx report

I am using Checkmarx to analyse my project, and the only remaining medium severity item is Missing_HSTS_Filter, with the Destination name being HSTSFilter. In my web.xml, I have :
<filter>
<filter-name>HSTSFilter</filter-name> <!-- checkmarx says problem is here -->
<filter-class>c.h.i.c.web.security.HSTSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HSTSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The HSTSFilter class :
public class HSTSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse resp = (HttpServletResponse) res;
if (req.isSecure())
resp.setHeader("Strict-Transport-Security", "max-age=31622400; includeSubDomains");
chain.doFilter(req, resp);
}
}
So I tried something else and because I am using Tomcat 7, I tried adding the following instead in web.xml :
<filter> <!-- checkmarx now complains here -->
<filter-name>httpHeaderSecurity</filter-name>
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>hstsMaxAgeSeconds</param-name>
<param-value>31622400</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>httpHeaderSecurity</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
Checkmarx still complains, saying the Destination name this time was StatementCollection. I don't understand what that means.
What am I missing ?
Strange thing. You really use the right configuration. On this Checkmarx rule, I find a lot of False Positive in some scan. Anyway,try to add this lines to your web.xml in the filter configuration :
<init-param>
<param-name>hstsIncludeSubDomains</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>hstsEnabled</param-name>
<param-value>true</param-value>
</init-param>
I got this error in check Marx violations in the JSP where a scriptlet tag is used to execute java source code in JSP. Syntax is as follows: <% java source code %>
So I fixed it just by providing
<% response.setHeader("Strict-Transport-Security" ,"max-age=7776000" ); %>
Also made changes in java code , a class file and web.xml changes :
web.xml :
<filter>
<filter-name>HSTSFilter</filter-name>
<filter-class>com.abc.gbm.test.config.HSTSFilter</filter-class>
<init-param>
<param-name>maxAgeSeconds</param-name>
<param-value>31536000</param-value>
</init-param>
<init-param>
<param-name>includeSubDomains</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>HSTSFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
Java class filter :
package com.abc.gbm.test.config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HSTSFilter implements Filter {
private static final String HEADER_NAME = "Strict-Transport-Security";
private static final String MAX_AGE_DIRECTIVE = "max-age=%s";
private static final String INCLUDE_SUB_DOMAINS_DIRECTIVE = "includeSubDomains";
private static final Logger logger = LoggerFactory.getLogger(HSTSFilter.class);
private int maxAgeSeconds = 0;
private boolean includeSubDomains = false;
private String directives;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
logger.info("request.isSecure() :: {}" , request.isSecure());
if (request.isSecure() && response instanceof HttpServletResponse) {
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader(HEADER_NAME, this.directives);
}
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
maxAgeSeconds = Integer.parseInt(filterConfig.getInitParameter("maxAgeSeconds"));
includeSubDomains = "true".equals(filterConfig.getInitParameter("includeSubDomains"));
if (this.maxAgeSeconds <= 0) {
throw new ServletException("Invalid maxAgeSeconds value :: " + maxAgeSeconds);
}
this.directives = String.format(MAX_AGE_DIRECTIVE, this.maxAgeSeconds);
if (this.includeSubDomains) {
this.directives += (" ; " + INCLUDE_SUB_DOMAINS_DIRECTIVE);
}
System.out.println("directives :: "+directives);
}
#Override
public void destroy() {
}
}

Redirection from filter is not working

I'm trying to redirect my app to the login page in case the session has expired (I have set an interval of 60 minutes). I have created a filter but it seems the redirection is not working properly.
My web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<session-config>
<session-timeout>
60
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>login.html</welcome-file>
</welcome-file-list>
<filter>
<filter-name>RedirectFilter</filter-name>
<filter-class>LoginUtils.RedirectFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RedirectFilter</filter-name>
<url-pattern>/AppUtils/*</url-pattern>
</filter-mapping>
</web-app>
My filter:
#WebFilter("/AppUtils/*")
public class RedirectFilter implements Filter {
private ServletContext context;
public void init(FilterConfig fConfig) throws ServletException {
this.context = fConfig.getServletContext();
this.context.log("RedirectFilter initialized");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String uri = req.getRequestURI();
this.context.log("Requested Resource::" + uri);
HttpSession session = req.getSession(false);
String loginURL = req.getContextPath() + "/login.html";
if (session == null && !req.getRequestURI().equals(loginURL)) {
this.context.log("Unauthorized access request");
res.sendRedirect(loginURL);
} else {
// pass the request along the filter chain
chain.doFilter(request, response);
}
}
public void destroy() {
//no-op
}
}

On my servlet url-pattern, the application works with "/path" but not with "/path/to"

I have the following Java servlet:
package com.controller;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Teste extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
request.setAttribute("teste", "Test");
request.getSession().setAttribute("teste", "Test Session");
RequestDispatcher rd = request.getRequestDispatcher("teste.jsp");
rd.forward(request, response);
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
#Override
public String getServletInfo() {
return "Short description";
}
}
And the following web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<servlet>
<servlet-name>Teste</servlet-name>
<servlet-class>com.controller.Teste</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Teste</servlet-name>
<url-pattern>/teste</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
</web-app>
I can access the servlet through the url http://localhost:8084/myapp/teste
What I want is change the url-pattern to /teste/edit, but when I do that, and try to access the servlet through the url http://localhost:8084/myapp/teste/edit I get the following 404 error:
HTTP Status 404 - /TrabalhoPSW/teste/teste.jsp
type Status report
message /TrabalhoPSW/teste/teste.jsp
description The requested resource is not available. Apache
Tomcat/8.0.27
Why is this happening? How can I fix this?
The problem was the JSP file that the servlet was trying to find. when I changed from
request.getRequestDispatcher("teste.jsp");
to
request.getRequestDispatcher("/teste.jsp");
It worked normally.
if you need than your servlet works with /path and /path/to, Change the mapping of servlet in web.xml to:
<url-pattern>/teste/*</url-pattern>

class not found exception for Servlet filter

I'm trying to create a basic servlet filter, I have created the filter and mapped it in the web.xml file but get filter not found exceptions.
Here's the web.xml file
<display-name>Disertation</display-name>
<filter>
<filter-name>AuthorizationFilter</filter-name>
<filter-class>Disertation.servlets.AuthorizationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthorizationFilter</filter-name>
<servlet-name>LoginServlet</servlet-name>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
Here is the path for the filter class: Disertation/src/servlets/AuthorizationFilter.java
Am i missing something or is my configuration wrong?
EDIT: I took the com out of the web.xml and Here is the filter class
package servlets;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import JavaBeans.User;
/**
* Servlet Filter implementation class AuthorizationFilter.
* Its purpose is to check logged-in user's role and
* and accordingly allow or prevent access to the web resources.
*/
public class AuthorizationFilter implements Filter {
private FilterConfig filterConfig;
/**
* #see Filter#init(FilterConfig)
*/
#Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig=filterConfig;
}
/**
* #see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
ServletContext sc= filterConfig.getServletContext();
String username = request.getParameter("user");
String pwd = request.getParameter("pwd");
System.out.println("first check");
User user = new User (username, pwd, "employee");
System.out.println("is this getting here?");
request.setAttribute("role", user.getRole());
if (request.getAttribute("role").equals("employee")|| request.getAttribute("role").equals("admin"))
chain.doFilter(request, res);
}
/**
* #see Filter#destroy()
*/
#Override
public void destroy() {
filterConfig=null;
}
}
Your filter should be under the following directory Disertation/src/com/Disertation/servlets/AuthorizationFilter.java
to match your filter configuration or change your filter configuration to
<filter-class>servlets.AuthorizationFilter</filter- class>
Are you using the correct package? In AuthorizationFilter.java look for the package name that is declared at the top of the file. Then put that in your web.xml:
<filter-class>com.some.package.AuthorizationFilter</filter-class>
Also, there is a space in your closing tag after the hyphen

How to set Filter to be applied for content-type "html/text" ONLY?

I wrote following code.
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
public class CacheFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse resp = (HttpServletResponse) response;
resp.setHeader("Cache-Control", "no-store, no-cache,must-revalidate,max-age=0");
resp.setHeader("Pragma", "no-cache");
chain.doFilter(request, response);
}
public void destroy() {
//delegate.destroy();
}
public void init(FilterConfig filterConfig) {
//delegate.destroy();
}
}
and here's the maping code in web.xml file
<filter>
<filter-name>CacheFilter</filter-name>
<filter-class>com.util.CacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CacheFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
This thing works but this filter gets applied for all the content, thus slowing my site's performance. I want this filter to be applied for content type "text/html" only. This can be easily achieved through ExpiresFilter like this
<init-param>
<param-name>ExpiresByType text/html</param-name>
<param-value>access plus 0 seconds</param-value>
</init-param>
but how to achieve it in this code?
I'd appreciate your earliest help.
I think you need to write Response Wrapper to modify the response from servlet-
See this links- http://www.java2s.com/Tutorial/Java/0400__Servlet/Filterthatusesaresponsewrappertoconvertalloutputtouppercase.htm
http://sqltech.cl/doc/oas10gR31/web.1013/b28959/filters.htm
http://software.it168.com/manual/servlet/0596005725_jsvltjspckbk-chp-19-sect-7.html
-Thanks

Categories