checkmarx scan issue that password variable is never cleared from memory - properties

Password, which is designated to contain user passwords. However, while plaintext passwords are later assigned to Password, this variable is never cleared from memory.
I have a class with Password property and I am getting above error from Checkmarx scan report.
Please help me how to resolve this error.

Use SecureString, it implements IDisposable Interface. In my case, I created an extension for SecureString.
public static class SecureStringExtension
{
public static string ToUnsecureString(this SecureString source)
{
var returnValue = IntPtr.Zero;
try
{
returnValue = Marshal.SecureStringToGlobalAllocUnicode(source);
return Marshal.PtrToStringUni(returnValue);
}
finally
{
Marshal.ZeroFreeGlobalAllocUnicode(returnValue);
}
}
public static SecureString ToSecureString(this string source)
{
SecureString password = new SecureString();
foreach (char c in source)
{
password.AppendChar(c);
}
password.MakeReadOnly();
return password;
}
}
Usage :
SecureString password = "P#SSword".ToSecureString();
////// business logic here
//////
password.Dispose();

The best solution to clear a Password value, is to rewrite with random content the value, and after this, deleted it. This unsure that the old value are not in place anywhere in memory.

Related

Customize login in Grails Spring Security plugin

I have an application where the login should include an organization number, so the login needs to be username + password + organization number.
Sample case: If the username + password matches with an existing user, I need to check if that user has the organization id. If not, the login should fail.
I saw that the login form from spring security plugin submits to /app/j_spring_security_check but couldn't find where that is actually implemented.
Also I'm not sure if touching that is the right way of implementing this custom login.
My question is where / how to customize the login action? (to make it fail on the case I described above).
We can do this by overriding the filter UserNamePasswordAuthenticationFilter and provide our custom attemptAuthentication.
So, go to DefaultSecurityConfig.groovy file (inside plugins). See tree diagram below:
target
|-work
|-plugins
|-spring-security-core-2.0-RC5
|-conf
|-DefaultSecurityConfig.groovy
In DefaultSecurityConfig.groovy under apf closure we specify filterProcessUrl which we can override in grails application's Config.groovy like we do for other properties (e.g. rejectIfNoRule)
grails.plugin.springsecurity.apf.filterProcessesUrl="your url"
Now we understood how it checks for authentication.Let's customise it own way by overriding the method attemptAuthentication of filter named UsernamePasswordAuthenticationFilter. For example, see below(also, go through the inline comments added there)
package org.springframework.security.web.authentication;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.util.Assert;
public class CustomUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
/** #deprecated */
#Deprecated
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
private String usernameParameter = "j_username";
private String passwordParameter = "j_password";
private String organisationParameter = 'j_organisation'
private boolean postOnly = true;
public UsernamePasswordAuthenticationFilter() {
super("/j_spring_security_check");
}
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if(this.postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
} else {
String username = this.obtainUsername(request);
String password = this.obtainPassword(request);
String password = this.obtainOrganisation(request);
//regular implementation in spring security plugin /**
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
this.setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
**/
//Your custom implementation goes here(Authenticate on the basis of organisation as well). Here you need to customise authenticate as per your requirement so that it checks for organisation as well.
}
protected String obtainOrganisation(HttpServletRequest request) {
return request.getParameter(this.organisationParameter);
}
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(this.passwordParameter);
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(this.usernameParameter);
}
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
}
public void setUsernameParameter(String usernameParameter) {
Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
this.usernameParameter = usernameParameter;
}
public void setPasswordParameter(String passwordParameter) {
Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
this.passwordParameter = passwordParameter;
}
public void setPostOnly(boolean postOnly) {
this.postOnly = postOnly;
}
public final String getUsernameParameter() {
return this.usernameParameter;
}
public final String getPasswordParameter() {
return this.passwordParameter;
}
}
Hence, it's more of a overriding task in terms of spring security.
To get more clearer idea about same read this nice link for java
and
for grails read this
Hope it helps.
These blogs gives a more detailed idea of the same requirements.

vaadin: getting user logindata from external page

i wrote a normal html login form, that forwards to a vaadin project, where i want to receive the username and password and check if its valid. but i have problems getting this request.
when i add a requesthandler in the init() method of my UI class, i can only get the request data after the second call of the vaadin page (because at the first call of init, the hander ist not added yet)
#Override
protected void init(VaadinRequest vaadinRequest) {
setContent(new MainComponent());
VaadinSession.getCurrent().addRequestHandler(
new RequestHandler() {
#Override
public boolean handleRequest(VaadinSession vaadinSession, VaadinRequest vaadinRequest, VaadinResponse vaadinResponse) throws IOException {
String username = vaadinRequest.getParameter("username");
return false;
}
});
so i tried to overwrite the VaadinServlet method doPost, but it does not get triggered. when i overwrite the methode service(HttpServletRequest request, HttpServletResponse response), this method is triggered a serval times for each request, so also not a good place to get just the userdata.
so whats the right way to solve this problem?
i dont't know if this is the best solution, but at least it works. maybe this helps someone.
here a short explanation what i do. i retrieve the posted username and password from the post values of my plain html login formular from another url and see if it is existing in the database. if it exists, it returns the result, otherwise the value ERROR.
i extended the VaadinServlet and overwrote the method service like this
#Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
super.service(request, response);
String username = request.getParameter("username");
if(username != null) { // called several times, only set when username is returned, otherwise the value remains "error"
String password = request.getParameter("password");
this.result = getResult(username, Encrypter.encryp(password));
}
}
and this is inside my class extended from UI
#Override
protected void init(VaadinRequest vaadinRequest) {
MyServlet myServlet = (MyServlet) VaadinServlet.getCurrent();
String result = myServlet.getResult();
if(result .equals(MyServlet.ERROR)){ // check if the result set in the servlet is valid, otherwise forward to the loginpage
goToLogin();
myServlet.resetResult();
return;
}
myServlet.resetResult();
...
}
To whom it may concern - obtaining request and response in Vaadin 8 (which might be also available in Vaadin 7):
VaadinServletRequest vsRequest = (VaadinServletRequest) VaadinService.getCurrentRequest ();
HttpServletRequest httpServletRequest = vsRequest.getHttpServletRequest ();
VaadinServletResponse vsResponse = (VaadinServletResponse) VaadinService.getCurrentResponse ();
HttpServletResponse httpServletResponse = vsResponse.getHttpServletResponse ();
You can read the request parameter directly through the VaadinRequest object that's passed into init():
#Override
protected void init(VaadinRequest vaadinRequest) {
setContent(new MainComponent());
String username = vaadinRequest.getParameter("username");
}
It work for me perfect:
User is my simple class with username, name etc.
setting logged user in session:
public void setLoggedUser(User loggedUser) {
this.loggedUser = loggedUser;
getUI().getSession().getSession().setAttribute("loggedUser", loggedUser);
}
reading user:
loggedUser = (User) getUI().getSession().getSession().getAttribute("loggedUser"); //return null if not logged in

Morphia: #PrePersist running when updating a document

I have a User entity. When I save a user document in the collection I'm hashing the password with #PrePersist but Morphia also calls #PrePersist when I try to update a document without password.
#PrePersist
void prePersist() {
if (password != null) {
System.out.println(password);
PasswordService service = new DefaultPasswordService();
password = service.encryptPassword(password);
}
}
This is my update operation.
#Override
public void updateWithoutPassword(T user) {
Query <T> query = userDAO.createQuery();
query.and(
query.criteria("_id").equal(user.getId())
);
UpdateOperations <T> updateOperations = userDAO.createUpdateOperations();
updateOperations.set("username", user.getUsername());
updateOperations.set("name", user.getName());
updateOperations.set("surname", user.getSurname());
updateOperations.set("department", user.getDepartment());
updateOperations.set("roles", user.getRoles());
userDAO.update(query, updateOperations);
}
When I call the updateWithoutPassword(), #PrePersist is running and password value is being the old password value and trying to hash the old password again. What am I doing wrong?
You should probably hash your password in setPassword() instead. #PrePersist will always run.

Spring Security Password Authentication

need some help or direction using Spring's security 3.1.x.
I am storing an encrypted password in MySql database. Which password is defined as a varchar(60) column.
The first time running the web app, I generated the password with the following code snippet:
String p = "12345";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(p);
I then took the String encodedPassword and pasted into the database column. I kept the code in my authentication-manager (snippet follows), and logged encodedPassword to the server log.
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="usersDAO">
<security:password-encoder ref="encoder" />
</security:authentication-provider>
</security:authentication-manager>
<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
My problem is that authentication fails with exception: Bad credentials when BCryptPasswordEncoder.matches() runs. The stored password is not matching the generated hash from the form input. The same text password that was used in the initial hash generation was used.
Each time I re-run the login entering the same text, the logged encodedPassword is different. Debugging I can see where the entity is being returned from the database correctly, so I don't think that is an issue. The issue seems to me that I'm not doing/setting something correctly in order to generate the same hash each time the text
password is entered.
EDIT:
Adding usersDAO.
import org.springframework.security.core.userdetails.UserDetailsService;
public interface UsersDAO extends Dao<Users>, UserDetailsService
{
Users getByUsername(String username);
}
EDIT:
adding implementation.
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#Repository("usersDAO")
public class UsersDAO_DB extends AbstractHibernateDao<Users> implements UsersDAO
{
final Logger log = LoggerFactory.getLogger(this.getClass());
#Override
public Users getByUsername(String username)
{
String p = "12345";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(p);
log.debug("HELLOZ ----> " + encodedPassword);
notNull(username, "username can't be null");
return (Users) getSession()
.getNamedQuery("users.byUsername")
.setParameter("username", username)
.uniqueResult();
}
#Override
#Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
notNull(username, "username can't be null");
Users users = getByUsername(username);
if (users == null) {
throw new UsernameNotFoundException("No user with username " + username);
}
return users;
}
#Override
public void create(Users t)
{
// TODO Auto-generated method stub
}
#Override
public void update(Users t)
{
// TODO Auto-generated method stub
}
#Override
public void delete(Users t)
{
// TODO Auto-generated method stub
}
}
Any ideas?
This was a newbie error here following a couple of different tutorials.
In the bean I had defined my security encoder as a:
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
To generate a test cryptic password I used the following code:
String p = "12345";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(p);
log.debug("HELLOZ ----> " + encodedPassword);
which was mixing the org.springframework.security.crypto.password.PasswordEncoder and the org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder. See the above code defining passwordEncoder.
Once I changed it to:
String p = "12345";
BCryptPasswordEncoder pe= new BCryptPasswordEncoder();
String encPassword =pe.encode(p);
log.debug("HELLB ----> " + encPassword);
copied the output to my database and retested everything worked fine.
Each time I re-run the login entering the same text, the logged encodedPassword is different".
Where is that logging coming from? Spring Security won't log incoming passwords and if you are using BCrypt it shouldn't be re-encoding them from scratch anywhere.
It sounds like you may be re-encoding the submitted password yourself, possibly in your usersDAO which isn't shown.
If not, please post your complete configuration and the logging output you're talking about.

Using selenium with Dynamic values

I am working with Selenium RC.
I am giving the data manually to selenium.Like below
selenium.type("id=username","myName");
selenium.type("id=password","myPassword");
selenium.click("id=login");
But, my doubt is is there any way to get the data dynamically? Here I am giving my Name directly into selenium.type();
Is there any way to retrieve username and password from other place like textfile or excel file?
Any help?
Short answer - YES.
Longer answer - You need to program it. So it is not possible using Selenium IDE, but you can use Selenium Webdriver. I am doing this in Java, so I will post you little snippets of my code, how do i do it.
1) I have special Java Class to hold the user information:
public class EUAUser {
private String username;
private String password;
private boolean isUsed
public EUAUser(String uname, String pwd){
this.username = uname;
this.password = pwd;
isUsed = false;
}
public String getPassword(){
return password;
}
public String getUsername(){
return username;
}
public void lockUser(){
isUsed = true;
}
}
2) Then I have UserPool to hold all users. So far because I need only 5 different users, I do it by quick and dirty approach:
public class UserPool {
private List<EUAUser> userList = new ArrayList<EUAUser>();
public UserPool(){
userList.add(new EUAUser("firstUser","a"));
userList.add(new EUAUser("MyUsername", "a"));
userList.add(new EUAUser("TestUser", "a"));
userList.add(new EUAUser("TSTUser2", "a"));
}
public EUAUser getNextUser() throws RuntimeException {
for(EUAUser user: userList){
if (!user.isUsed()){
user.lockUser();
return user;
}
}
throw new RuntimeException("No free user found.");
}
3) In tests I have something like this
UserPool pool = new UserPool();
EUAUser user = pool.getNextUser();
selenium.type("id=username", user.getUserName());
selenium.type("id=password", user.getPassword());
selenium.click("id=login");
The above code does
Add all known users to the UserPool
Retreive one free user from the pool
logs him into the app under username and password
In my case its really quick and dirty approach, but you can have list of users in file and load them into the UserPool using fileReader or something. Just giving you idea how you can do this ;)