April 7, 2014
Security Enhancements in ColdFusion Splendor – PBKDF2 and AntiSamy
Comments
(5)
April 7, 2014
Security Enhancements in ColdFusion Splendor – PBKDF2 and AntiSamy
(5)

ColdFusion 11 added few more security functions to the rich set of coldfusion security functions. Some of them includes protection against XSS using AntiSamy framework, PBKDF2 key derivation etc. In this blog post we will introduce you to the Antisamy and PBKDF2 key derivation functions added in coldfusion Splendor.

AntiSamy Support:

If there is a need to accept HTML/CSS input from the user then there is high possibility that the input containing XSS. In this case We can not use encoding functions as the HTML/CSS as the input need to be rendered by the browser. AntiSamy API provides an input validation technique which helps programmer to verify user-driven HTML/CSS input markup using a whitelist policy to ensure the input does not contain XSS. Antisamy validates using a policy file in which we can specify which HTML tags, attributes, css properties are allowed in the given input. The policy gives us more control on input validation/sanitization by providing directives,  regular expressions, rules for htmt tags and css properties . AntiSamy provides some example policy files which can be downloaded from here. They can be modified to suit your own project requirements. Check AntiSamy developer guide to know more about policy files.

Two new functions isSafeHTML and getSafeHTML were added which validates and cleans the given unsafe html as per the given policy.

isSafeHTML can be used to know whether the given input markup is in accordance with the rules specified in the antisamy policy. Returns true if valid else false if any violations are found.

getSafeHTML sanitizes the given input based on the the rules specified in an antisamy policy file. Returns cleanHTML string by cleaning the input against the defined policy.

The function syntax as below:

getSafeHTML(input [, PolicyFile ], throwOnError])
isSafeHTML(input [, PolicyFile ])
where

input
     
The HTML input markup text to sanitize/validate.

PolicyFile (Optional)
     Specify the path to the AntiSamy policy file. Given path can be an absolute path or a relative to the Application.cfc/cfc.Given path can be an absolute path or a relative to the Application.cfc/cfc.In case if not specified, there is a provision to set this at application level. Else the default policy file shipped with ColdFusion will be used. Default policy antisamybasic.xml can be found in the lib directory.

throwOnError (Optional)
      If set to true and given input violates the allowed HTML rules specified in the policy file an exception will be thrown. The exception message contains the list of violations raised because of the input. If set to false ignores the exception returns the HTML content filtered, cleaned according to the policy rules. Defaults to false.

Policy file can be set at application level using the key this.security.antisamypolicy in Application.cfc. The value must be an absolute path to the policy file or relative to the Application.cfc/cfm.

<cfcomponent>
<cfset this.security.antisamypolicy = "antisamy.xml">
</cfcomponent>

Here is a simple example which uses antisamy-tinymce.xml policy which allows many text formatting tags ,simple css properties and disallows javascript.

<!--- I am just using static input in this example when using this replace it with the relevant form parameter --->
<cfset unsafeHTML = "<script>alert('lorem ipsum lorem ipsum');</script><b>lorem ipsum lorem ipsum</b>">
<cfset isSafe = isSafeHTML(unsafeHTML)>
<cfset SafeHTML = getSafeHTML(unsafeHTML , "", false)>
 
<!--- returns No and provides the clean html as <b>lorem ipsum lorem ipsum</b> removes script from input  --->
<cfoutput> is Safe : #isSafe# Safe HTML : #SafeHTML# </cfoutput>
<cftry>
    <cfset SafeHTML = getSafeHTML(unsafeHTML , "", true)>
<cfcatch type="Application">
<!--- if throwOnError is true get the erros as specified below --->
<cfoutput>
    Errors in the input: <br/> #cfcatch.detail#
</cfoutput>
</cfcatch>
</cftry>

More detailed information and examples on antisamy can be found from here.

PBKDF2 Key Derivation:

PBKDF2 (Password based key derivation function) is a key derivation function which can be used to derive a cryptographic random key of desired key size from the humany-manageable passwords. PBKDF2 is widely used for generating random cryptography keys which can be used as key to encryption and HMAC algorithms. The function syntax as below

GeneratePBKDFKey(algorithm, inputString, salt, iterations, keysize)

algorithm
The encryption algorithm used to generate the encryption key. Supported algorithms are PBKDF2WithHmacSHA1, PBKDF2WithSHA1, PBKDF2WithSHA224,  PBKDF2WithSHA256,PBKDF2WithSHA384, PBKDF2WithSHA512.

inputString
Specify the input string (password/pass-phrase) which will be used for deriving the encryption key.

salt
Random cryptographic salt. Recommended length is 64 bits (8 characters) and must be randomly generated using a pseudo random number generator.

iterations
Desired Number of Iterations to perform the cryptographic operation. The minimum recommended number of iterations is 1000.

keySize
Desired arbitrary key length size in bits.

Below example shows how to derive a 192 bit encryption key from the given password. Then we are using key to encrypt and decrypt the data using AES algorithm. No need to store the encryption key as it will be derived from the password.

salt="A41n9t0Q";
        <!--- hard coding the password but in real password should be from some form parameter ---> 
	password = "Password@123";
	PBKDFalgorithm = "PBKDF2WithSHA224";
	dataToEncrypt= "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua";
	encryptionAlgorithm = "AES";
	derivedKey = GeneratePBKDFKey(PBKDFalgorithm ,password ,salt,4096,192);
	writeOutput("Generated PBKDFKey (Base 64) : " & derivedKey);
	encryptedData = encrypt(dataToEncrypt, derivedKey, encryptionAlgorithm, "BASE64");
	writeoutput("Data After Encryption: " & encryptedData);

        
	salt="A41n9t0Q";
	password = "Password@123";
	PBEalgorithm = "PBKDF2WithSHA224";
	derivedKey = GeneratePBKDFKey(PBKDFalgorithm ,password ,salt,4096,192);
	decryptedData = decrypt(encryptedData, derivedKey, encryptionAlgorithm, "BASE64");
	writeoutput("Data After Decryption: " & decryptedData);

More information and examples on PBKDF2 can be found from here.

5 Comments
2014-05-08 07:58:29
2014-05-08 07:58:29

Is there a reason ColdFusion went with OWASP AntiSamy in particular as opposed to similar projects like OWASP Java HTML Sanitizer?

Also, is Adobe going to contribute back to AntiSamy (a no-fee, open source project) with bug fixes and performance enhancements?

Like
2014-04-13 16:00:36
2014-04-13 16:00:36

Could you please clarify which AntiSamy policies with be included? It appears that only one is, antisamy-basic.xml, which isn’t listed as any part of the OWASP AntiSamy distribution. It does appear to be a copy/rename of antisamy-slashdot.xml.

Please verify and be sure to include in the documentation about where to get additional policies.

Like
2014-04-12 03:48:54
2014-04-12 03:48:54

Thanks for writing about AntiSamy, I didn’t realise the new safeHTML functions existed in CF11. I’d been using the jsoup Java lib to do that which was a learning curve requiring some kind assistance from the CF community.

Like
2014-04-09 10:44:58
2014-04-09 10:44:58

@Tom thanks for pointing it out. Fixed it.

Like
2014-04-09 07:15:54
2014-04-09 07:15:54

“The function syntax as below:” has misplaced square brackets around the policyfile argument

Like
Add Comment