- Problem: The URL(s) accessible without login to the application
- Affected To: Sensitive information exposure (email, username, sensitive key/parameter, hashed password, etc.)
- Solution: Giving auth validation for each URL access.
BACKEND
//Check if user role allowed to this Page
if(!isActionAllowed((String) model.get("roleRequest"))){
if(getUserRole().equals("NO_ROLE")){
model.clear();
return "redirect:/login";
} else {
model.clear();
return "redirect:/403";
}
}
FRONTEND
Object mySession = session.getAttribute(SESSION_KEY);
if(mySession == null) {
return "redirect:/login";
}
- Problem: Attacker could target unsuspecting application users with a malicious client-side script that steals session cookies and allows an attacker control of user session (session hijacking). Such malicious script could also compromise private information e.g. steal sensitive information, account owner details or other sensitive information accessible to application user.
- Affected To: Steal sensitive information, possible to do phising attack, launch browser exploit.
- Solution:
- On client side: do filter for using special characters (< > & " ') this solution has weakness, when user know how to disable Javascript
- On server side: remove or replace any special characters (< > & " ') after submitting form (special characters validation). Or halt submit process when there is any special characters.
protected String ptrnNOHTML = ".*[<].*|.*[>].*";
if(BILLER_NAME.isEmpty()) {
isValid = false;Error+="|bill-name:<li>`Biller Name` must not be empty</li>|";
} else if(BILLER_NAME.matches(ptrnNOHTML)) {
isValid = false;Error+="|bill-name:<li>`Biller Name` must not be filled with `<` and/or `>`</li>|";
}
- Problem: Attacker launched dictionary attack on username pentest02; the account was not locked out even after brute-forcing it with more than 50 wrong passwords. By exploiting this vulnerability, an attacker could perform an arbitrary number of authentication attempts using different username/passwords or performing brute force attack on the application. Password quality policy was also not implemented in the application.
Lack of protection from automated password attacks could expose application to password brute forcing or dictionary attacks.
- Affected To: Possibility to do infinity brute force attack, could perform an arbitrary number of auth attempts using different username/password combination.
- Solution: There are 2 solutions for this case:
- Validation for maximum authentication failed attempt. (in MRP Mandiri case set to max. 3 failed attempt and account locked for 10 minutes). If failed for next attempt, updated locked time for next 10 minutes. (for MRP Mandiri case, we use this solution)
- Block attacker IP address. (put it on database for blacklist IP address)
@Service("serviceUserAttempt")
public class Service_UserAttemptImpl implements Service_UserAttempt {
@Autowired private Mapper_UserAttempt mapperUserAttempt;
@Autowired private Mapper_AppUserLogin mapperUserLogin;
private static final int MAX_ATTEMPT = 3;
private static final int BLOCKED_EXPIRED_MIN = 10;
@Override
public UserAttempt getUserAttempt(String username) {
try {
UserAttempt userAttempt = mapperUserAttempt.getUserAttempt(username);
return userAttempt;
} catch(NullPointerException npe) {
return null;
}
}
@Override
public void updateFailAttempt(String username) {
DateTime currentDatetime = new DateTime();
UserAttempt userAttempt = getUserAttempt(username);
if(userAttempt == null) {
if(isUserExists(username)) {
// if no record, insert a new
UserAttempt data = new UserAttempt();
data.setUsername(username);
data.setAttempt(1);
data.setLastModified(currentDatetime.toString());
mapperUserAttempt.insertAttempt(data);
}
} else {
// check if last_modified is more than 10 minutes
if(userAttempt.getLastModified() != null) {
DateTimeFormatter f = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
DateTime lastModified = f.parseDateTime(userAttempt.getLastModified());
// DateTime lastModified = DateTime.parse(userAttempt.getLastModified());
DateTime expiredDatetime = lastModified.plusMinutes(BLOCKED_EXPIRED_MIN);
if(expiredDatetime.isBeforeNow()) {
AppUserLogin dataUser = new AppUserLogin();
dataUser.setUsrACCOUNT_NON_LOCKED(true);
dataUser.setUsrUNAME(username);
mapperUserAttempt.resetAttempt(username);
mapperUserLogin.updateUserLocked(dataUser);
//throw unlocked exception
}
}
// update attempt + 1
if(isUserExists(username)) {
UserAttempt data = new UserAttempt();
data.setUsername(username);
data.setLastModified(currentDatetime.toString());
System.out.println("data"+data);
mapperUserAttempt.updateAttempt(data);
}
// if attempt >= max attempt, then throw LockedException
UserAttempt userAttemptNew = getUserAttempt(username);
if(userAttemptNew.getAttempt() >= MAX_ATTEMPT) {
// locked user
AppUserLogin dataUser = new AppUserLogin();
dataUser.setUsrACCOUNT_NON_LOCKED(false);
dataUser.setUsrUNAME(username);
mapperUserLogin.updateUserLocked(dataUser);
// throw exception
throw new LockedException("User Account is blocked due to maximum failed login attempt. Please contact bank admin for further assistance.");
}
}
}
@Override
public void resetFailAttempt(String username) {
mapperUserAttempt.resetAttempt(username);
}
private boolean isUserExists(String username) {
boolean result = false;
AppUserLogin userLogin = mapperUserLogin.getUser_byUsername(username);
if(userLogin != null) {
result = true;
}
return result;
}
}
- Problem: Attacker who gains access to the computer can capture stored credentials like Username, Email, and maybe Password too.
- Affected To: Steal credential information.
- Solution:
Include html attribute autocomplete="off" within the <form>
tag to protect all fields OR within each <input>
tag to protect specific individual fields.
<form name="loginForm" id="loginForm" action="<c:url value="login" />" autocomplete="off" method='POST'>
</form>
OR
<input type="text" name="username" class="form-control" id="inlineFormInput" autocomplete="off" placeholder="Username">
<input type="password" name="password" class="form-control" id="inlineFormInputGroup" autocomplete="off" placeholder="Password">
- Problem: Attacker successfully demonstrated scenario, where they could use CSRF attacks to change Report Setting on behalf of targeted customer.
- Affected To: Report Setting information changed without knowledge of the targeted user.
- Solution: (null)