Hi,

I am currently developing a Java web application using the Struts 7.0.3
framework, JDK 23, and Tomcat 11.0.5, with a Dynamic Web Module version
6.1. Although the application is intended for an intranet environment, VA
(Vulnerability Assessment) clearance is still required.

To address security concerns, I have implemented a CspInterceptor class.
However, after scanning the application with OWASP ZAP, several
vulnerabilities were reported.

Could you please advise on how to resolve these issues? For your reference,
I have attached the WAR file of the test project along with a few relevant
pages.

Thanks and regards,
Shivam







 test.war
<https://drive.google.com/open?id=1ChtdOQKVdehi27j0Q-xth0w_9H7qD3wg>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<s:form method="post" validate="true" theme="simple" name="form" action="Login"
        id="paraFrm">
        <s:token />

        <table style="margin-left: 40%; margin-top: 20%;">

                <tr>
                        <td style="color: maroon;">User Name :</td>
                        <td><s:textfield
                                        
cssStyle="width:100%;text-align:LEFT;font-size: 12PX;background-color: #FDEBD0;"
                                        name="username" /></td>
                </tr>
                <tr>
                        <td style="color: maroon;">Password :</td>
                        <td><s:password
                                        
cssStyle="width:100%;text-align:LEFT;font-size: 12PX;background-color: #FDEBD0;"
                                        name="passwd" /></td>
                </tr>
                <tr>
                        <td align="center">&nbsp;</td>
                </tr>
                <tr>
                        <td colspan="2"><s:submit cssClass="pagebutton" 
                                        cssStyle="width:100%" value="Submit" 
onclick="return callSubmit();" /></td>
                </tr>

        </table>

</s:form>




<script>
        function callSubmit(){
                var username = 
document.getElementById('paraFrm_username').value;
                var passwd       = 
document.getElementById('paraFrm_passwd').value;
                if(username==""||passwd==""){
                        alert("User Id or password can not be blank");
                }
                else{
                        document.getElementById('paraFrm').target="_self";
                        document.getElementById('paraFrm').action="submitpage";
                        document.getElementById('paraFrm').submit();
                        return true;
                }
        }
 
        </script>
package org.paradyne.lib;

import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.struts2.ActionInvocation;
import org.apache.struts2.ActionContext;
import org.apache.struts2.interceptor.Interceptor;

public class CspInterceptor implements Interceptor {

        private static final long serialVersionUID = -4628112275531928102L;

        @Override
        public void destroy() {
                System.out.println("CSP interceptor destroy  method!!!!!");

        }

        @Override
        public void init() {
                System.out.println("CSP interceptor init method!!!!!");
        }

        @Override
        public String intercept(ActionInvocation ai) throws Exception {
                System.out.println("Before actionInvocation.invoke() 
called!!!!");

                final ActionContext ac = ai.getInvocationContext();
                HttpServletResponse myresponse = ac.getServletResponse();
                HttpSession session = 
org.apache.struts2.ServletActionContext.getRequest().getSession();
                final String jsessionid = session.getId();
                String cookieValue = "JSESSIONID=" + jsessionid + "; 
Path=/test;  HttpOnly; SameSite=Strict";
                myresponse.setHeader("Set-Cookie", cookieValue);
                myresponse.setHeader("X-Frame-Options", "SAMEORIGIN");
                myresponse.setHeader("X-Content-Type-Options", "nosniff");
                myresponse.setHeader("Content-Security-Policy", "default-src 
'self'; img-src 'self'; frame-src 'self';  connect-src 'self'; frame-ancestors 
'self'; font-src 'self'; base-uri 'self'; form-action 'self';  'unsafe-inline' 
'unsafe-eval'  prefetch-src 'none'; manifest-src 'none'; object-src 'self'; 
media-src 'none'; ");
                String resultString = ai.invoke();
                System.out.println("before result");
                return resultString;
        }
}
package org.struts.action.common;

import org.apache.struts2.ActionSupport;
import org.apache.struts2.ModelDriven;
import org.apache.struts2.Preparable;
import org.apache.struts2.action.ServletContextAware;
import org.apache.struts2.action.ServletRequestAware;
import org.apache.struts2.action.ServletResponseAware;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;

import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.struts2.interceptor.parameter.StrutsParameter;
import org.paradyne.bean.common.LoginBean;

import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@Namespace("/common")
@Action("Login")
@Results({
        @Result(name = "success",                               location = 
"login.Login",                       type = "tiles"),
        @Result(name = "welcomepage",                   location = 
"login.successpage",         type = "tiles"),
        @Result(name = "input",                                 location = 
"login.Login",                       type = "tiles")
})
public class LoginAction extends ActionSupport implements
ModelDriven<Object>, Preparable, ServletRequestAware,ServletResponseAware, 
ServletContextAware{

        /**
         * 
         */
        private static final long serialVersionUID = 1L;  
        LoginBean bean;
        @StrutsParameter(depth = 1)
        @Override
        public Object getModel() {
                // TODO Auto-generated method stub
                return bean;
        }
        
        @Action("loginpage")
        public String loginpage() {
                return "input";
        }
        
        @Action("submitpage")
        public String submitpage() {
                System.out.println("password is:"+bean.getUsername());
                System.out.println("user id is:"+bean.getPasswd());
                
if(bean.getUsername().equals("aa")&&bean.getPasswd().equals("aa")) {
                        return "welcomepage";
                }
                return "input";
        }

        @Override
        public void withServletResponse(HttpServletResponse arg0) {
                // TODO Auto-generated method stub
                
        }

        @Override
        public void withServletRequest(HttpServletRequest arg0) {
                // TODO Auto-generated method stub
                
        }

        @Override
        public void prepare() throws Exception {
                // TODO Auto-generated method stub
                bean=new LoginBean();
        }

        @Override
        public void withServletContext(ServletContext arg0) {
                // TODO Auto-generated method stub
                
        }

        
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 6.5//EN"
    "struts-6.5.dtd">

<struts>
    <constant name="struts.devMode" value="true" />
    <constant name="struts.mapper.action.prefix.enabled" value="true"/>
        <constant name="struts.custom.i18n.resources" value="globalMessages" /> 
           
        <constant name="struts.multipart.maxSize" value="100000000" />
        <constant name="struts.allowlist.packageNames" 
value="org.paradyne.bean.common" />
 
        <constant name="struts.convention.default.parent.package" 
value="default" /> 
          <package name="default" extends="struts-default">
          <result-types>
                                <result-type name="tiles" 
class="org.apache.struts2.views.tiles.TilesResult"/>
                        </result-types>
                        
                        <interceptors>
                                <interceptor name="CSPInterceptor"   
class="org.paradyne.lib.CspInterceptor"/>
                                <interceptor-stack name="customStack">
                                <interceptor-ref name="defaultStack" />
                                <interceptor-ref name="CSPInterceptor" />       
                        
                                </interceptor-stack>     
                   </interceptors>   
                   <default-interceptor-ref name="customStack" />
                   
                   
                </package>
</struts>
package org.paradyne.bean.common;

import java.io.Serializable;

import org.apache.struts2.interceptor.parameter.StrutsParameter;


public class LoginBean implements Serializable{


        private static final long serialVersionUID = 1L;

        private String username="";
        private String passwd="";
        


        public String getPasswd() {
                return passwd;
        }
        public String getUsername() {
                return username;
        }
        @StrutsParameter(depth=1)
        public void setUsername(String username) {
                this.username = username;
        }
        @StrutsParameter(depth=1)
        public void setPasswd(String passwd) {
                this.passwd = passwd;
        }
        public static long getSerialversionuid() {
                return serialVersionUID;
        }
        
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns="https://jakarta.ee/xml/ns/jakartaee"; 
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee 
https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"; id="WebApp_ID" 
version="6.0">  
  <display-name>pims</display-name>
 
   <filter>
        <filter-name>struts2</filter-name>
        
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <listener>
        <listener-class>
            org.apache.struts2.tiles.StrutsTilesListener
        </listener-class>
    </listener>
    
  <context-param>
        
<param-name>org.apache.tiles.definition.DefinitionsFactory.DEFINITIONS_CONFIG</param-name>
        <param-value>/WEB-INF/tiles.xml</param-value>
    </context-param>
  
  
  <welcome-file-list>
  <welcome-file>/WEB-INF/home.jsp</welcome-file>
  </welcome-file-list>
  
  <error-page>
        <error-code>401</error-code>
        <location>/error401.jsp</location>
    </error-page>
    <error-page>
        <error-code>500</error-code>
        <location>/error500.jsp</location>
    </error-page>
    
     <error-page>
        <error-code>404</error-code>
        <location>/error404.jsp</location>
    </error-page>
     <error-page>
        <error-code>408</error-code>
        <location>/error408.jsp</location>
    </error-page>
    <session-config>
  <cookie-config>
  <http-only>true</http-only>
  <secure>true</secure>
  </cookie-config>
  <tracking-mode>COOKIE</tracking-mode>
  </session-config>
  
</web-app>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@struts.apache.org
For additional commands, e-mail: user-h...@struts.apache.org

Reply via email to