We are using Spring MVC ver 4.3 in one of the projects. The application supports i18n and Locale can be changed using url like http://appurl.com/?locale=en
The problem is when someone sends random value for locale, it is not rejected, rather Spring sets Content-Language
header value = that_random_str
And since we are using CookieLocaleResolver
, Spring also sets localeCookie value to that_random_str.
Is there any way where we can tell Spring to restrict locale values to only few Locales like only English(en) and Hindi(hi) are allowed and IllegalArgumentException
shall be thrown for other values
Asked
Active
Viewed 59 times
2

Chetan Ahirrao
- 1,454
- 11
- 16
-
1Why not validate this in the same way you would validate any other user-provided input? [How to validate a locale in java?](https://stackoverflow.com/q/3684747/12567365) If you only want to support a very small list of predefined values, then it becomes even simpler - use a properties list, or an enum, etc. to provide the set of valid values. Return `400 Bad Request` (and explanation) to the user if the validation fails. – andrewJames May 12 '23 at 12:57
-
(Java [does not validate locale data](https://download.java.net/java/early_access/panama/docs/api/java.base/java/util/Locale.html): "_the Locale class does not provide any validation features. The Builder only checks if an individual field satisfies the syntactic requirement (is well-formed), but does not validate the value itself._". Sounds like Spring doesn't either. So, you have to do it.) – andrewJames May 12 '23 at 12:58
1 Answers
1
Couldn't find any standard solution to this so solved it with my own way.
I extended LocaleChangeInterceptor
and overridden preHandle
method.
public class CustomLocaleChangeInterceptor extends LocaleChangeInterceptor{
private Set<String> validLanguages;
public CustomLocaleChangeInterceptor() {
super();
}
public Set<String> getValidLanguages() {
return validLanguages;
}
public void setValidLanguages(Set<String> validLanguages) {
this.validLanguages = validLanguages;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws ServletException {
String newLocale = request.getParameter(getParamName());
if(newLocale!=null && !"".equals(newLocale)) {
newLocale=newLocale.toLowerCase();
if(!validLanguages.contains(newLocale)) {
throw new IllegalArgumentException("Language/Locale not supported");
}
}
return super.preHandle(request, response, handler);
}
}
and in xml configuration:
<interceptors>
<beans:bean
class="mypackage.CustomLocaleChangeInterceptor">
<beans:property name="paramName" value="language" />
<beans:property name="validLanguages">
<beans:set>
<beans:value>en</beans:value>
<beans:value>hi</beans:value>
</beans:set>
</beans:property>
</beans:bean>
</interceptors>
Though the invalid Locale
doesn't cause any issue, the security team was persistent that Locale
injection is possible so I needed to do this.

Chetan Ahirrao
- 1,454
- 11
- 16