0

In my web application I'm trying to prevent users from inserting JavaScript in the freeText parameter when they're running a search.

To do this, I've written code in the header Velocity file to check whether the query string contains a parameter called freeText, and if so, use the replace method to replace the characters within the parameter value. However, when you load the page, it still displays the original query string - I'm unsure on how to replace the original query string with my new one which has the replaced characters.

This is my code:

#set($freeTextParameter = "$request.getParameter('freeText')")
freeTextParameter: $freeTextParameter

#if($freeTextParameter)
    ##Do the replacement: 
    #set($replacedQueryString = "$freeTextParameter.replace('confirm','replaced')")
    replacedQueryString after doing the replace: $replacedQueryString
    The query string now: $request.getQueryString()
    The freeText parameter now: $request.getParameter('freeText')
#end

In the code above, the replacedQueryString variable has changed as expected (ie the replacement has been carried out as expected), but the $request.getQueryString() and $request.getParameter('freeText') are still the same as before, as if the replacement had never happened.

Seeing as there is a request.getParameter method which works fine for getting the parameters, I assumed there would be a request.setParameter method to do the same thing in reverse, but there isn't.

Victoria
  • 901
  • 3
  • 15
  • 30
  • May I ask what you expect from that replacement? (Of course, other than having a new string where the old one was. What process do you whish to change/prevent?) I'm asking because I think it might be too late to do that while rendering the view **after** a request and **server sided**. – MyBrainHurts Apr 04 '16 at 11:37

2 Answers2

0

The Java String is an immutable object, which means that the replace() method will return an altered string, without changing the original one.

Since the parameters map given by the HttpServletRequest object cannot be modified, this approach doesn't work well if your templates rely on $request.getParameter('freeText').

Instead, if you rely on VelocityTools, then you can rather rely on $params.freeText in your templates. Then, you can tune your WEB-INF/tools.xml file to make this parameters map alterable:

<?xml version="1.0">
<tools>
  <toolbox scope="request">
    <tool key="params" readOnly="false"/>
    ...
  </toolbox>
  ...
</tools>

(Version 2.0+ of the tools is required).

Then, in your header, you can do:

#set($params.freeText = params.freeText.replace('confirm','replaced'))
Claude Brisson
  • 4,085
  • 1
  • 22
  • 30
0

I managed to fix the issue myself - it turned out that there was another file (which gets called on every page) in which the $!request.getParameter('freeText')" variable is used. I have updated that file so that it uses the new $!replacedQueryString variable (ie the one with the JavaScript stripped out) instead of the existing "$!request.getParameter('freeText')" variable. This now prevents the JavaScript from being executed on every page.

So, this is the final working code in the header Velocity file:

    #set($freeTextParameter = "$!m.request.httpRequest.getParameter('freeText')")
#if($freeTextParameter)
    #set($replacedQueryString = "$freeTextParameter.replace('confirm','').replace('<','').replace('>','').replace('(','').replace(')','').replace(';','').replace('/','').replace('\"','').replace('&','').replace('+','').replace('script','').replace('prompt','').replace('*','').replace('.','')")
#end
Victoria
  • 901
  • 3
  • 15
  • 30