Struts 2 Conditional Annotation Validation without XML - java

I have a form with several fields (i.e. a,b,c,d,...) and the project I am currently doing right now is using Annotations for form validation in Struts2. XML usage is being discouraged.
I need to check a certain condition before I will validate form elements b, c, and d.
I was able to do the following:
#Validations {
requiredStrings = {
#RequiredStringValidator(...),
#RequiredStringValidator(...),
}
}
public String doSomething(){
...
return SUCCESS;
}
Is there a way to do this in Struts2 Annotation alone? Most similar questions I have found in SO all tell me to use XML method. Thanks.

Use an expression validator, or write a custom validator.

Related

Common Validation filter for Servlet-Jsp project [duplicate]

How can I prevent XSS attacks in a JSP/Servlet web application?
XSS can be prevented in JSP by using JSTL <c:out> tag or fn:escapeXml() EL function when (re)displaying user-controlled input. This includes request parameters, headers, cookies, URL, body, etc. Anything which you extract from the request object. Also the user-controlled input from previous requests which is stored in a database needs to be escaped during redisplaying.
For example:
<p><c:out value="${bean.userControlledValue}"></p>
<p><input name="foo" value="${fn:escapeXml(param.foo)}"></p>
This will escape characters which may malform the rendered HTML such as <, >, ", ' and & into HTML/XML entities such as <, >, ", &apos; and &.
Note that you don't need to escape them in the Java (Servlet) code, since they are harmless over there. Some may opt to escape them during request processing (as you do in Servlet or Filter) instead of response processing (as you do in JSP), but this way you may risk that the data unnecessarily get double-escaped (e.g. & becomes &amp; instead of & and ultimately the enduser would see & being presented), or that the DB-stored data becomes unportable (e.g. when exporting data to JSON, CSV, XLS, PDF, etc which doesn't require HTML-escaping at all). You'll also lose social control because you don't know anymore what the user has actually filled in. You'd as being a site admin really like to know which users/IPs are trying to perform XSS, so that you can easily track them and take actions accordingly. Escaping during request processing should only and only be used as latest resort when you really need to fix a train wreck of a badly developed legacy web application in the shortest time as possible. Still, you should ultimately rewrite your JSP files to become XSS-safe.
If you'd like to redisplay user-controlled input as HTML wherein you would like to allow only a specific subset of HTML tags like <b>, <i>, <u>, etc, then you need to sanitize the input by a whitelist. You can use a HTML parser like Jsoup for this. But, much better is to introduce a human friendly markup language such as Markdown (also used here on Stack Overflow). Then you can use a Markdown parser like CommonMark for this. It has also builtin HTML sanitizing capabilities. See also Markdown or HTML.
The only concern in the server side with regard to databases is SQL injection prevention. You need to make sure that you never string-concatenate user-controlled input straight in the SQL or JPQL query and that you're using parameterized queries all the way. In JDBC terms, this means that you should use PreparedStatement instead of Statement. In JPA terms, use Query.
An alternative would be to migrate from JSP/Servlet to Java EE's MVC framework JSF. It has builtin XSS (and CSRF!) prevention over all place. See also CSRF, XSS and SQL Injection attack prevention in JSF.
The how-to-prevent-xss has been asked several times. You will find a lot of information in StackOverflow. Also, OWASP website has an XSS prevention cheat sheet that you should go through.
On the libraries to use, OWASP's ESAPI library has a java flavour. You should try that out. Besides that, every framework that you use has some protection against XSS. Again, OWASP website has information on most popular frameworks, so I would recommend going through their site.
I had great luck with OWASP Anti-Samy and an AspectJ advisor on all my Spring Controllers that blocks XSS from getting in.
public class UserInputSanitizer {
private static Policy policy;
private static AntiSamy antiSamy;
private static AntiSamy getAntiSamy() throws PolicyException {
if (antiSamy == null) {
policy = getPolicy("evocatus-default");
antiSamy = new AntiSamy();
}
return antiSamy;
}
public static String sanitize(String input) {
CleanResults cr;
try {
cr = getAntiSamy().scan(input, policy);
} catch (Exception e) {
throw new RuntimeException(e);
}
return cr.getCleanHTML();
}
private static Policy getPolicy(String name) throws PolicyException {
Policy policy =
Policy.getInstance(Policy.class.getResourceAsStream("/META-INF/antisamy/" + name + ".xml"));
return policy;
}
}
You can get the AspectJ advisor from the this stackoverflow post
I think this is a better approach then c:out particular if you do a lot of javascript.
Managing XSS requires multiple validations, data from the client side.
Input Validations (form validation) on the Server side. There are multiple ways of going about it. You can try JSR 303 bean validation(hibernate validator), or ESAPI Input Validation framework. Though I've not tried it myself (yet), there is an annotation that checks for safe html (#SafeHtml). You could in fact use Hibernate validator with Spring MVC for bean validations -> Ref
Escaping URL requests - For all your HTTP requests, use some sort of XSS filter. I've used the following for our web app and it takes care of cleaning up the HTTP URL request - http://www.servletsuite.com/servlets/xssflt.htm
Escaping data/html returned to the client (look above at #BalusC explanation).
I would suggest regularly testing for vulnerabilities using an automated tool, and fixing whatever it finds. It's a lot easier to suggest a library to help with a specific vulnerability then for all XSS attacks in general.
Skipfish is an open source tool from Google that I've been investigating: it finds quite a lot of stuff, and seems worth using.
There is no easy, out of the box solution against XSS. The OWASP ESAPI API has some support for the escaping that is very usefull, and they have tag libraries.
My approach was to basically to extend the stuts 2 tags in following ways.
Modify s:property tag so it can take extra attributes stating what sort of escaping is required (escapeHtmlAttribute="true" etc.). This involves creating a new Property and PropertyTag classes. The Property class uses OWASP ESAPI api for the escaping.
Change freemarker templates to use the new version of s:property and set the escaping.
If you didn't want to modify the classes in step 1, another approach would be to import the ESAPI tags into the freemarker templates and escape as needed. Then if you need to use a s:property tag in your JSP, wrap it with and ESAPI tag.
I have written a more detailed explanation here.
http://www.nutshellsoftware.org/software/securing-struts-2-using-esapi-part-1-securing-outputs/
I agree escaping inputs is not ideal.
My personal opinion is that you should avoid using JSP/ASP/PHP/etc pages. Instead output to an API similar to SAX (only designed for calling rather than handling). That way there is a single layer that has to create well formed output.
If you want to automatically escape all JSP variables without having to explicitly wrap each variable, you can use an EL resolver as detailed here with full source and an example (JSP 2.0 or newer), and discussed in more detail here:
For example, by using the above mentioned EL resolver, your JSP code will remain like so, but each variable will be automatically escaped by the resolver
...
<c:forEach items="${orders}" var="item">
<p>${item.name}</p>
<p>${item.price}</p>
<p>${item.description}</p>
</c:forEach>
...
If you want to force escaping by default in Spring, you could consider this as well, but it doesn't escape EL expressions, just tag output, I think:
http://forum.springsource.org/showthread.php?61418-Spring-cross-site-scripting&p=205646#post205646
Note: Another approach to EL escaping that uses XSL transformations to preprocess JSP files can be found here:
http://therning.org/niklas/2007/09/preprocessing-jsp-files-to-automatically-escape-el-expressions/
If you want to make sure that your $ operator does not suffer from XSS hack you can implement ServletContextListener and do some checks there.
The complete solution at: http://pukkaone.github.io/2011/01/03/jsp-cross-site-scripting-elresolver.html
#WebListener
public class EscapeXmlELResolverListener implements ServletContextListener {
private static final Logger LOG = LoggerFactory.getLogger(EscapeXmlELResolverListener.class);
#Override
public void contextInitialized(ServletContextEvent event) {
LOG.info("EscapeXmlELResolverListener initialized ...");
JspFactory.getDefaultFactory()
.getJspApplicationContext(event.getServletContext())
.addELResolver(new EscapeXmlELResolver());
}
#Override
public void contextDestroyed(ServletContextEvent event) {
LOG.info("EscapeXmlELResolverListener destroyed");
}
/**
* {#link ELResolver} which escapes XML in String values.
*/
public class EscapeXmlELResolver extends ELResolver {
private ThreadLocal<Boolean> excludeMe = new ThreadLocal<Boolean>() {
#Override
protected Boolean initialValue() {
return Boolean.FALSE;
}
};
#Override
public Object getValue(ELContext context, Object base, Object property) {
try {
if (excludeMe.get()) {
return null;
}
// This resolver is in the original resolver chain. To prevent
// infinite recursion, set a flag to prevent this resolver from
// invoking the original resolver chain again when its turn in the
// chain comes around.
excludeMe.set(Boolean.TRUE);
Object value = context.getELResolver().getValue(
context, base, property);
if (value instanceof String) {
value = StringEscapeUtils.escapeHtml4((String) value);
}
return value;
} finally {
excludeMe.remove();
}
}
#Override
public Class<?> getCommonPropertyType(ELContext context, Object base) {
return null;
}
#Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base){
return null;
}
#Override
public Class<?> getType(ELContext context, Object base, Object property) {
return null;
}
#Override
public boolean isReadOnly(ELContext context, Object base, Object property) {
return true;
}
#Override
public void setValue(ELContext context, Object base, Object property, Object value){
throw new UnsupportedOperationException();
}
}
}
Again: This only guards the $. Please also see other answers.
<%# page import="org.apache.commons.lang.StringEscapeUtils" %>
String str=request.getParameter("urlParam");
String safeOuput = StringEscapeUtils.escapeXml(str);

Java - Custom/standard validation with Annotations

I'm using annotations in a project. The thing is i'm making custom validation that (partly) depends on annotations. I'm also making own annotations, but I want to use as much as I can from the JSR 303 standard.
to check if a field 'passes' the annotation constraints i've written some methods. Example:
static boolean isNotNullValid(Field f){
boolean valid = true;
if(f.isAnnotationPresent(NotNull.class)){
Object o = ObjectGetter.getFieldValue(f);
if(o==null){
valid = false;
}
}
return valid;
}
It's quite a lot of work to do this type of validation for all annotations. Is there some method i'm missing, like .isValid() ? I mean, of course, for the standard annotations.
Thanks in advance
You're not supposed to code that by yourself. You should instead rely on an implementation of the JSR, for example Hibernate Validator. The Validator it implements allows getting a set of constraint violations based on the annotations on the bean.

Are multiple roles allowed in the #Secured annotation with Spring Security

I would like to allow access to a particular method to more than one group of users. Is it possible in Spring Security 3.x to do such a thing using the #Secured annotation? Consider two groups (roles) OPERATOR and USER, would this code be valid:
#Secured("ROLE_OPERATOR", "ROLE_USER")
public void doWork() {
// do useful processing
}
You're almost there. Syntactically, you need to write it like this:
#Secured({"ROLE_OPERATOR", "ROLE_USER"})
public void doWork() { ... }
This is because you're supplying multiple values to a single array attribute of the annotation. (Java syntactically special-cases handing in a single value, but now you need to do it “properly”.)
#Donal Fellows answer is correct for Spring apps. However, if you're working in Grails, you need to use the Groovy syntax for lists so the code would look like this
#Secured(["ROLE_OPERATOR", "ROLE_USER"])
public void doWork() { ... }

java design problem for validations

I have the following requirement:
I have a validation system. One of the things that I need to do is perform validations on XML files, meaning validating that tag X equals a given value. I have more than one possible scenario, and in each scenario there is a different set of tags that need to be validated.
I don't want to repeat same code when testing same tags in different scenarios.
I'm trying to figure out a design that will solve this issue.
Any ideas?
Thanks.
I'd define pairs of XPath expressions and expected results for the scenarios.
The validator then would take a scenario (object), compile and apply the associated expressions to the xml document. This would select an element and the validator would check, if the element's content matches the expected value.
Erm, delegate to a shared method? Like:
void validateAppleScenario(Xml xml) {
validateFruit(xml);
// validate apples specific tags
}
void validateBanana(Xml xml) {
validateFruit(xml);
// validate banana specific tags
}
void validateFruit(Xml xml) {
// validate tags common to all fruit
}
Or if you prefer validators to be seperate objects, you can use subtyping:
interface Validator {
void validate(Xml xml);
}
class FruitValidator implements Validator {
void validate(Xml xml) {
// validate tags common to all fruit
}
}
class AppleValidator extends FruitValidator {
void validate(Xml xml) {
super.validate(xml);
// validate tags specific to apples
}
}
One approach would be to parse the XML into an object and then validate it in accordance with Bean Validation spec (JSR 303). Hibernate Validator is the reference implementation.* You can annotate your properties with validation constraints, and then specify validation groups so that certain fields get validated in certain scenarios.
There is more info here and here.
*Hibernate Validator is different from Hibernate ORM. They're only related in that Hibernate ORM uses Validator for its constraint checking.

spring mvc validation best practices

I am learning myself Spring MVC 2.5 mostly from the docs. Can someone explain the following:
Advantages/differences of using command objects versus using #ModelAttribute to pass in the object.
Is there an easier way to do validation other then writing a Validator object?
Also, in this code how does the line ValidationUtils.rejectIfEmpty(e, "name", "name.empty"); work? How can it check if the name is empty on the person object when the person object is not passed in?
public void validate(Object obj, Errors e) {
ValidationUtils.rejectIfEmpty(e, "name", "name.empty");
Person p = (Person) obj;
if (p.getAge() < 0) {
e.rejectValue("age", "negativevalue");
} else if (p.getAge() > 110) {
e.rejectValue("age", "too.darn.old");
}
}
(this code is from section 5.2 from the docs)
Thanks
The question about command object is not very clear. If you mean the following syntax
#RequestMapping(...) public ModelAndView foo(Command c) { ... }
then it is the same as the following
#RequestMapping(...) public ModelAndView foo(#ModelAttribute Command c) { ... }
because #ModelAttribute can be omitted. The only case when it's actually needed is then you need to specify attribute name explicitly (otherwise it would be inferred as a class name with the first letter decapitalized, i.e. command)
In Spring 2.5 - no. In Spring 3.0 you can use declarative validation with JSR-303 Bean Validation API.
The Errors object has a reference to the object being validated.
Here is the answer of your first question.
http://chompingatbits.com/2009/08/25/spring-formtag-commandname-vs-modelattribute/
according to my experience there isn't easier way to fullfill validation, because it's easy enough. You can get it easier integrating libraries such as commons-validator into your project and use pre-defined validation rules in your forms.
http://numberformat.wordpress.com/tag/spring-mvc-validation/
and also with 3rd version of Spring you can use Bean validation using annotations.

Categories