This is in the view
<g:passwordField name="password" required="" value="${usuarioInstance?.password}"/>
This would be a part of the controller
pass = params.password.encodeAsSHA1()
This will be returned into the view again
${pass.password}
the ${pass.password} needs to change to text or decode the SHA1()
My advice:
don't use sha-1, it's insecure
don't unencrypt a password and display it in a form field. Make the user type it in if they want to change it, if they haven't entered anything then don't update that property
use spring security which by default manages all the headaches of web security and uses Bcrypt out of the box.
Security is something every dev needs to take seriously and if the client insists on unsecure practices then they need to be educated.
Edit: #zaph makes a good point below so I should add it - don't encrypt passwords. A password should never be able to be translated back into plain text. Always hash (and salt) them and compare the user input hash to the stored hash. If you choose not to use Spring Security, you can use Bcrypt standalone and use the static Bcrypt.checkpw(userInputPw, hashedPw) method to check it.
Final Edit: To avoid any confusion (since #zaph seems confused in the comments) my recommendation is to use Bcrypt - specifically, use Spring Security.
Related
Why Spring Security doesn't provide any XSS filter to clean the form input values?
Accordingly to this ticket, such XSS filter is a low priority:
https://jira.spring.io/browse/SEC-2167?jql=text%20~%20%22xss%22
(although the ticket speaks only about URL querystring. Sanitizing POST params would be also required)
In my opinion it would be really useful that spring would provide such a filter instead of building your own. This filter it's a recurrent problem.
XSS is best handled at output stage via the use of encoding. That is, store everything in your database as is, and yes storing <script> is fine, however once output, encode correctly for the context it is output in. For HTML this would be <script>, however if your output context was plain text you would just output as is <script> (assuming the same character set encoding is used). Side note: Use parameterised queries or equivalent for storing in your database to avoid SQL injection, however the text stored should exactly match what was entered.
Microsoft attempts to block inputs that look like XSS via their request validation feature in ASP.NET. However, this isn't very effective and flaws are found quite often. Similar approaches from other frameworks are doomed to fail.
The reason that this is much better is that it makes things much more simple. Imagine if StackOverflow didn't allow HTML or script tags - the site would not be functional as a place for people to post code snippets.
You can use input validation as second line of defence. For example, if you are asking the user to enter their car registration you would only want to allow alphanumerics and space to be entered. However, for more complex fields it is often difficult to restrict input to a safe set as output context is unknown at this stage.
Say your language filtered < and > characters. However you were outputting user input into the following context.
<img src="foo.jpg" alt="USER-INPUT" />
An XSS attack is possible by entering " onmouseover="alert('xss') because it would be rendered as
<img src="foo.jpg" alt="" onmouseover="alert('xss')" />
Similar problems would ensue if you were outputting to JavaScript server-side. This is why it should be up to the developer to select the correct encoding type when using user controlled values.
In all of the reference pages I've found with regards to encrypting the ViewState, the only comment on the password is "your password here".
Are there any recommendations regarding the length / complexity of the password that we should use?
Depends on Mojarra version. It had several flaws/fails in earlier versions.
In Mojarra 1.2.x - 2.1.18, it was never actually used. The JNDI entry name was namely incorrectly documented. It was documented as com.sun.faces.ClientStateSavingPassword (with same prefix as Mojarra's other web.xml context parameters), but the code actually checks for ClientStateSavingPassword. You should then register it on that name instead.
<env-entry>
<env-entry-name>ClientStateSavingPassword</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>[Your Password]</env-entry-value>
</env-entry>
Otherwise, the client state is actually not encrypted.
In Mojarra 1.2.x - 2.0.3, the password will be used as a SecureRandom seed to generate a DES algorithm key. So, generally, the same rules apply as to "real world" passwords. Only, this can be easily compromised if the password is "too easy" and the attacker successfully guesses/bruteforces/figures the password.
In Mojarra 2.0.4 - 2.1.x, they changed the algorithm from DES to AES and the code now don't actually use the provided password anymore to generate the key (to prevent potential comprisions). Instead, a completely random key is generated, which is more safe. The JNDI entry now basically controls whether the client state should be encrypted or not. In other words, it behaves now like a boolean configuration entry. It thus absolutely doesn't matter anymore which password you use.
<env-entry>
<env-entry-name>ClientStateSavingPassword</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>[Any value is interpreted as boolean=true to enable encryption]</env-entry-value>
</env-entry>
In Mojarra 2.1.19 - 2.1.x, they fixed the code to align the documentation on JNDI entry name. So you could use the documented JNDI entry name:
<env-entry>
<env-entry-name>com.sun.faces.ClientStateSavingPassword</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>[Any value is interpreted as boolean=true to enable encryption]</env-entry-value>
</env-entry>
However, this still doesn't affect the AES key, which was changed since 2.0.4, it still basically only enables/disables the encryption.
In Mojarra 2.2.0 - 2.3.x, as part of JSF 2.2 specification (chapter 7.8.2), client side state is now by default always encrypted. It will only be disabled when web.xml context parameter com.sun.faces.disableClientStateEncryption is set with value true. It still uses AES algorithm with a completely random key. The JNDI entry com.sun.faces.ClientStateSavingPassword is now not used anymore.
In Mojarra 2.2.6 - 2.3.x, they added as per issue 3087 a new JNDI entry which allows you to specify the AES key in Base64 encoded format, the jsf/ClientSideSecretKey. This is part of the bugfix on failing client side state when a JSF webapp is used in cluster environment, because each server used a different AES key which would only cause a ERROR: MAC did not verify! when state is restored in a different server than the one which saved the state, as described in issue 2557.
<env-entry>
<env-entry-name>jsf/ClientSideSecretKey</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>[AES key in Base64 format]</env-entry-value>
</env-entry>
You can use this AES key generator to generate one (refresh the page to regenerate), or use below snippet to generate your own Base64-encoded AES256 key:
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // Use 128 for AES128 (when server don't have JCE installed).
String key = Base64.getEncoder().encodeToString(keyGen.generateKey().getEncoded());
System.out.println(key); // Prints AES key in Base64 format.
I am wondering if it is consider good practice to encode user input to database.
Or is it ok to not encode to user input instead.
Currently my way of doing it is to encode it when entering database and use Html.DisplayFor to display it.
No. You want to keep the input in its original form until you need it and know what the output type is. It might be HTML for now, but later if you want to change it to json, text file, xml, etc the encoding might make it look different then you want.
So, first you want to make sure you are securely validating your input. It is a good idea to know what are the requirements for each of your inputs and validate that they are withing the correct length, range, character set, etc. It will be to your interest to limit the type of characters that are allowed as valid characters of an input type. (If using Regular Expressions to validate input ensure you do not use a regular expressions that is susceptible to a Regular Expression Denial of Service.
When moving the data around in your code ensure that you are properly handling the data in a manner that it will not turn into an Injection Attack.
Since you are talking about a database, the best practice is to use paramaterized statements. Check out the prevention methods in the above link.
Then when it comes outputting using MVC, if you are not using RAW or MvcHtmlString functions/calls, then the output is automatically encoded. With the automatic encoding, you want to make sure you are using the AntiXss encoder and not the default (whitelist approach vs. blacklist). Link
If you are using Raw or MvcHtmlString, you want to make sure you COMPLETE TRUST the values (you hard coded them in) or you manually encode them using the AntiXss Encoder class.
No it is not necessary to encode all the user inputs, rather if you want to avoid the script injection either you my try to validate the fields for special characters like '<', '>', '/', etc. else your Html helper method itself will do the needful.
I'm building a little token-based authentication library for my (rails based) api server which uses redis to store generated auth tokens. The line I'm worried about is: user_id = $redis.get("auth:#{token}"), where token is what's passed in to authenticate_or_request_with_http_token.
If this were SQL, that'd be a huge red flag - string interpolated SQL queries are pretty insecure. As far as I can tell, however, doing string interpolation on a redis key query isn't insecure.
My source for the above claim is the redis documentation here: http://redis.io/topics/security (under the string escaping and nosql injection header), but I wanted to make sure that this is the case before I get a Bobby Tables attack.
The documentation you are pointing to is quite explicit:
The Redis protocol has no concept of string escaping, so injection is impossible under normal circumstances using a normal client library. The protocol uses prefixed-length strings and is completely binary safe.
There is a small attack vector for these kinds of string injections. While the redis documentation is clear about the difficulty of executing multiple commands on the database, it does not mention that the key separator (':' in your example) usually needs to be escaped when used as the part of a key.
I have seen a redis database using these keys:
oauth_token:123456 (which contained a hash of OAuth token parameters) and
oauth_token:123456:is_temp (which contained a boolean property to indicate whether the OAuth token is a temporary token)
Trusting the user input without escaping might result in GET oauth_token:#{token} accidentally ending up as GET oauth_token:123456:is_temp (when token has been set to 123456:is_temp by the user).
So I highly recommend to properly escape colons from potential user input to make sure your key paths cannot be tricked like this.
NOTE: Someone recommended to fix the example above by using oauth_token:123456 and oauth_token:is_temp:123456, but that is flawed (for the user-provided token is_temp:123456). The correct solution to that problem (without escaping) would be to use keys oauth_token:info:123456 and oauth_token:is_temp:123456 to make sure these keys cannot overlap whatever the user-provided input was (or simply escape colons).
Basically Redis is immune from escaping issues when the input string is used verbatim. For example:
SET mykey <some-attacker-chosen-data>
However Redis is not immune from issues arising by using non validate input in the context of string interpolation, as showed by Sven Herzberg. In order to turn the Sven example into a safe one, it is possible to just use an Hash, and avoid reverting to interpolation. Otherwise either use not common prefixes to use in conjunction with keys interpolation, or use some basic form of sanity check on the input, which is, filtering away the separator used, or better, validate that the input is actually a number (in the specific example).
So while Redis does not suffer from the typical injection attacks of SQL, when used untrusted input in the context of a string interpolation used to create key names, or even worse, Lua scripts, some care should be taken.
When I allow a user to enter text using s:textfield, he can enter something like <b>Name</b> or something like \Me/. I want that these should be escaped before I am saving them to the database. When we retrieve them, the escaping is done automatically, but I want it to happen also when we are saving it.
I was trying to return a json output from my action class, but due to a name \a/ stored in my database, wrong json was being formed. This would have been avoided if the name had been escaped before being saved into the database.
You can use StringEscapeUtils. You can call escapeJavascript(textfield) in your action and then store it into the database.
#Daud, The problem you explained is called Cross site scripting or XSS.
And I think you should use Filters to clean the request parameters. This is the most sophisticated way. You can call these filters for the actions which are posting some parameters via request.
Visit my blog to see how to avoid XSS threat using Filter approach.
I also faced this issue when our project was tested by well known firm specializing in security testing and they suggested this filter approach.
You can give it a try.