Grails Markup Sanitizer Plugin
Dependency :
compile ":sanitizer:0.8.0"Custom repositories :
mavenRepo "https://repository.sonatype.org/content/repositories/central/"
Summary
Plugin for Sanitizing Markup(HTML, XHTML, CSS) using OWASP AntiSamy.
Filters malicious content from User generated content (such as that entered through Rich Text boxes).Features -
- Ruleset in web-app/WEB-INF/antisamy-policy.xml
- Constraint "markup"
- can be added to domain/command classes to validate that a string is valid and safe markup
- important note: The constraint is for validation only, it does not sanitize the string
- Encoding-only Codec "myText.encodeAsSanitizedMarkup()"
- use the codec or the service to sanitize the string
- (the codec uses the service, too)
- MarkupSanitizerService
- use the codec or the service to sanitize the string
- access in your controllers/services via
- method MarkupSanitizerResult sanitize(String dirtyString)
- method MarkupValidatorResult validateMarkup(String htmlString)
- effectively a singleton, which means the ruleset only needs to be read once on startup
Installation
grails install-plugin sanitizer
Description
Plugin for Sanitizing Markup(HTML, XHTML, CSS) using http://www.owasp.org/index.php/Category:OWASP_AntiSamy_Project OWASP AntiSamy
Filters malicious content from User generated content (such as that entered through Rich Text boxes).In your controller in both the save and the update add:
If you would like a generic error message instead of a specific error message you can edit messages.properties, and simply set:
In the latest version of sanitizer, you can add this config value to Config.groovy
By default, if there is a message given by the sanitizer during cleaning, the sanitizer codec will return an empty string.
Setting trustSanitizer to true will allow you to ignore the messages issued by the sanitizer and just use the output.
Features
- Ruleset in web-app/WEB-INF/antisamy-policy.xml - User chooses which of 3 defaults to use, as well as edit further if necessary.
- Constraint "markup"
- can be added to domain/command classes to validate that a string is valid and safe markup
- important note: The constraint is for validation only, it does not sanitize the string
- Encoding-only Codec "myText.encodeAsSanitizedMarkup()"
- use the codec or the service to sanitize the string
- (the codec uses the service, too)
- MarkupSanitizerService
- use the codec or the service to sanitize the string
- access in your controllers/services via: def markupSanitizerService
- method MarkupSanitizerResult sanitize(String dirtyString)
- method MarkupValidatorResult validateMarkup(String htmlString)
- effectively a singleton, which means the ruleset only needs to be read once on startup
Bugreports - Jira
http://jira.grails.org/browse/GPSANITIZERPlease note the beta nature of the version number. This plugin has not been extensively tested. Please feel free to send me any results of any testing you may do. This module does not sanitize a string that does not contain valid markup. If it does not contain valid markup, it will simply return an empty string.Example using encodeAsSanitizedMarkup
In your domain/command object add a constraint to inform the user if they've submitted invalid markup:static constraints = { text(maxSize: 65000, markup:true)}
@def save = { def newsItemInstance = new NewsItem(params) ... // give the user a clue if(!newsItemInstance.validate()){ render(view: "create", model: [newsItemInstance: newsItemInstance]) return } //Sanitize newsItemInstance.text = newsItemInstance.text.encodeAsSanitizedMarkup() if (newsItemInstance.save(flush: true)) { ...}myCommand.field.markup.error.field=My generic error messagesanitizer.trustSanitizer=trueExample using Service
Use the sanitizer as follows in controllers or other services:import org.grails.plugins.sanitizer.MarkupSanitizerResult...// inject service def markupSanitizerService... // implement the sanitizer in a method of your choice MarkupSanitizerResult result = markupSanitizerService.sanitize(input) if(!result.isInvalidMarkup()) { //return result.cleanString } else { //return result.errorMessages //return result.cleanString }