How to submit a form to Hybris from external application

Gate crash is embarrassing, back door entry is risky. Great is to be welcomed by a friend inside the party, when you are not invited.

Recently, i came to a situation, where i wanted to submit a form to hybris from a application. I thought it would be easy, and all i need is to do a post to a URL.

Booom. It came out with a flat Bad or missing csrf value error.

Once i thought, perhaps i am trying to breach the hybris security. Since there is a contract between client (browser) and the server (hybris) to exchange information. To keep this information just between them, a shared private token is used. This token, known as csrf token, is bound to a session.

@sumitg88 talked about it one of his blog.

Bypassing a request from security layer is one thing. What i wanted was to go through the security layer, and still be able to submit a form, from outside the spring context of Hybris storefront.

I created an API in storefront, which can pass a csrf-token for the current session. The current session can be opened by application, by hitting the home page, may be in an iframe, or through a java program in backend.

Hybris forcefully adds a csrf token inside a hidden field, in every spring mvc form. You can see this happening by going to html source of a page with form. This token is actually validated against the session token to allow a request to pass to the services.

hiddenFields.put(CSRFTokenManager.CSRF_PARAM_NAME, CSRFTokenManager.getTokenForSession(request.getSession()));

In Html forms you can see:

      <input type="hidden" name="CSRFToken" value="0b4eefff-1a05-4bdb-843a-fa9598633dab">

Our API could give the same csrf token, which we can pass through our form in external application. This way, Hybris will take this request as a valid one, and we can submit the form.

The API could look like below:

      public static String getTokenForSession(final HttpSession session)
	{

		// cannot allow more than one token on a session - in the case of two requests trying to
		// init the token concurrently
		Enumeration<String> enumeration=session.getAttributeNames();
		String csrfTokenAttr=null;
		String token=null;
		while(enumeration.hasMoreElements())
		{
			String attrName=enumeration.nextElement();

			if (attrName.contains("CSRFTokenManager.tokenval"))
			{ 
				csrfTokenAttr=attrName;
			}
		}
		synchronized (session)
		{
			token = (String) session.getAttribute(csrfTokenAttr);
			if (null == token)
			{
				token = UUID.randomUUID().toString();
				session.setAttribute(csrfTokenAttr, token);
			}
		}
		return token;
	}

Once you have a valid token, from one of the session, you can submit any form smoothly.

Enjoy!!!!

Error submitting a form due to Cross Site Request Forgery (CSRF)

Recently I faced a problem when I was trying to simply create a Form and a Controller to accept the values submitted from the form. I was using Hybris 5.7 version.

When I entered and submitted some values in the form (or even submitting an empty form) I was continuously getting the following error in the browser and the program control was not reaching my controller:

http status 403 bad or missing CSRF value

After doing lot of googling I found that the above error was coming while sending a “POST” request from any Form and was due to the interceptor “csrfHandlerInterceptor” configured in spring-mvc-config.xml of my storefront. This interceptor is configured to prevent Cross Site Request Forgery (CSRF).

Now to fix this error, there are 2 options:

  1. either the CSRF token in the request matches the session CSRF token to ascertain the validity of incoming posts requests.
  2. or the requested URL is a trusted path and is allowed to go through without CSRF token validation

For the 1st point you need to configure and send a valid CSRF token in your request. You can find information regarding this at: http://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/csrf.html

For the 2nd point you can add your URL entry to “csrfAllowedUrlPatternsList” in your storefront’s spring-mvc-config.xml file as shown below:

<util:list id=”csrfAllowedUrlPatternsList” value-type=”java.lang.String”>
             <value>/upload/createmedia</value>
</util:list>

Please note that for additional details there is a good article on CSRF in Hybris Wiki at the following URL:

https://wiki.hybris.com/display/accdoc/Spring+Security

 

 

Store Locator – Unable to locate stores with Google maps when a proxy is installed

Problem:

Usually while testing the “Store Finder” page on demo site like “electroncis” site, you can’t locate stores with Google maps because of a proxy installed  and generally it works without a proxy.

Solution:

For overcoming this problem, you may try adding the following entries to your hybris installation in the file: hybris\bin\platform\tomcat\conf\catalina.properties

http.proxyHost=
http.proxyPort=
http.proxyUser=
http.proxyPassword=

Note: It may work by just adding the 1st two properties itself.

Dynatrace installation : org.apache.catalina.LifecycleException: An invalid Lifecycle transition was attempted ([before_stop]) for component [StandardService[Catalina]] in state [INITIALIZED]

Are you getting a life cycle exception during server start. This is actually because you followed hybris wiki blindly, without reading instructions carefully.

While installing a dynatrace for your hybris project, you need to add few parameter to tomcat, so that dynatrace agent is loaded. But probably, you overridden all tomcat options.

Solution is to copy tomcat.generaloptions from project.properties of platform extension and add dynatrace properties in the end.

tomcat.generaloptions=-Xmx2G …..-Djava.io.tmpdir=”${HYBRIS_TEMP_DIR}” ${dynatrace.jvm-opts}

Restart cmd and run build again.