Skip to content

Commit 2367bb1

Browse files
committed
Issue fixed during security audit
1)Implement SameSite=Lax for all request 2)Implement csrf token for all importent request 3)Update privilige level of accessing issue in all user operations 4)Restrict accessing Mis application untill new password is set by new user 5)Block accessing templates by loging in as normal user 6)removed the password from resetPassword api's response 7)Allowed only for admin user to access this url "http://192.168.200.112:8080/NMSReportingSuite/nms/user/roles" 8)Fix issue in API rate limiting 9)removed tomcat banner grabbing
1 parent 1ac6d47 commit 2367bb1

File tree

14 files changed

+158
-40
lines changed

14 files changed

+158
-40
lines changed

NMSReportingSuite/src/main/java/com/beehyv/nmsreporting/business/impl/CookiesInterceptor.java renamed to NMSReportingSuite/src/main/java/com/beehyv/nmsreporting/business/impl/CsrfInterceptor.java

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,38 @@
11
package com.beehyv.nmsreporting.business.impl;
22

3+
import com.beehyv.nmsreporting.business.UserService;
4+
import com.beehyv.nmsreporting.model.User;
5+
import org.springframework.beans.factory.annotation.Autowired;
36
import org.springframework.web.servlet.ModelAndView;
47
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
58

6-
import javax.servlet.http.Cookie;
79
import javax.servlet.http.HttpServletRequest;
810
import javax.servlet.http.HttpServletResponse;
911

10-
public class CookiesInterceptor extends HandlerInterceptorAdapter {
12+
public class CsrfInterceptor extends HandlerInterceptorAdapter {
13+
@Autowired
14+
private UserService userService;
1115

12-
@Override
13-
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
14-
}
1516
@Override
1617
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
17-
Cookie cookie = new Cookie("SameSite", "Lax");
18-
response.addCookie(cookie);
18+
User currentUser = userService.getCurrentUser();
1919

20-
return true;
20+
if(currentUser == null) {
21+
return false;
22+
}
23+
String token = "dhty" + currentUser.getUserId().toString() + "alkihkf";
24+
return request.getHeader("csrfToken").equals(token);
2125
}
26+
2227
@Override
23-
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception {}
28+
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
29+
}
30+
31+
@Override
32+
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
33+
}
2434

2535
@Override
2636
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
2737
}
28-
}
38+
}

NMSReportingSuite/src/main/java/com/beehyv/nmsreporting/business/impl/UserServiceImpl.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,6 @@ public Map<Integer, String> createNewUser(User user) {
143143
responseMap.put(rowNum, userNameError);
144144
return responseMap;
145145
}
146-
if (userDao.findByUserName(user.getUsername()) != null) {
147-
String userNameError = "Username already exists.";
148-
responseMap.put(rowNum, userNameError);
149-
return responseMap;
150-
}
151146

152147
String userPhone = user.getPhoneNumber();
153148
String regexStr1 = "^[0-9]*$";
@@ -314,6 +309,11 @@ else if (user.getAccessLevel().equalsIgnoreCase(AccessLevel.DISTRICT.getAccessLe
314309
// return responseMap;
315310
// }
316311
}
312+
if (userDao.findByUserName(user.getUsername()) != null) {
313+
String userNameError = "Username already exists.";
314+
responseMap.put(rowNum, userNameError);
315+
return responseMap;
316+
}
317317
String password = serviceFunctions.generatePassword();
318318
user.setPassword(passwordEncoder.encode(password));
319319
user.setCreationDate(new Date());

NMSReportingSuite/src/main/java/com/beehyv/nmsreporting/controller/AdminController.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,12 @@ public Map uploadFileHandler(@RequestParam("bulkCsv") MultipartFile file) {
107107
@ResponseBody
108108
public String getBulkDataImportCSV(HttpServletResponse response) throws ParseException, java.text.ParseException{
109109

110-
response.setContentType("APPLICATION/OCTECT-STREAM");
110+
User user = userService.getCurrentUser();
111+
if(user==null||!(user.getRoleName().equals("MASTER ADMIN"))&&!(user.getRoleName().equals("ADMIN"))){
112+
return "Not Authorized";
113+
}
114+
115+
response.setContentType("APPLICATION/OCTECT-STREAM");
111116
try {
112117
PrintWriter out=response.getWriter();
113118
String filename="BulkImportData.csv";
@@ -192,7 +197,9 @@ public String getCumulativeCourseCompletion(@PathVariable("state") String State,
192197
modification.setModifiedByUserId(userService.getCurrentUser().getUserId());
193198
modificationTrackerService.saveModification(modification);
194199
}
195-
return map;
200+
Map<Integer, String> requiredmap=new HashMap<>();
201+
requiredmap.put(0,map.get(0));
202+
return requiredmap;
196203
}
197204
@RequestMapping(value = "/create", method = RequestMethod.GET)
198205
@ResponseBody

NMSReportingSuite/src/main/java/com/beehyv/nmsreporting/controller/UserController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public class UserController {
136136
@RequestMapping(value={"/roles"} , method = RequestMethod.POST)
137137
public @ResponseBody List<Role> getRoles() {
138138
User currentUser = userService.getCurrentUser();
139-
if(currentUser.getUserId() != null){
139+
if(currentUser.getUserId() != null&&((currentUser.getRoleName().equals("MASTER ADMIN"))||(currentUser.getRoleName().equals("ADMIN")))){
140140
return roleService.getRoles();
141141
} else
142142
return null;

NMSReportingSuite/src/main/webapp/WEB-INF/applicationContext.xml

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,82 @@
136136
</bean>
137137

138138
<mvc:interceptors>
139+
140+
<!-- Csrf Interceptor Open-->
141+
<mvc:interceptor>
142+
<mvc:mapping path="/nms/admin/changePassword"/>
143+
<bean class="com.beehyv.nmsreporting.business.impl.CsrfInterceptor">
144+
</bean>
145+
</mvc:interceptor>
146+
147+
<mvc:interceptor>
148+
<mvc:mapping path="/nms/admin/uploadFile"/>
149+
<bean class="com.beehyv.nmsreporting.business.impl.CsrfInterceptor">
150+
</bean>
151+
</mvc:interceptor>
152+
153+
<mvc:interceptor>
154+
<mvc:mapping path="/nms/mail/sendEmailForContactUs"/>
155+
<bean class="com.beehyv.nmsreporting.business.impl.CsrfInterceptor">
156+
</bean>
157+
</mvc:interceptor>
158+
159+
<mvc:interceptor>
160+
<mvc:mapping path="/nms/mail/sendFeedback"/>
161+
<bean class="com.beehyv.nmsreporting.business.impl.CsrfInterceptor">
162+
</bean>
163+
</mvc:interceptor>
164+
165+
<mvc:interceptor>
166+
<mvc:mapping path="/nms/user/createUser"/>
167+
<bean class="com.beehyv.nmsreporting.business.impl.CsrfInterceptor">
168+
</bean>
169+
</mvc:interceptor>
170+
139171
<mvc:interceptor>
140-
<mvc:mapping path="/nms/**"/>
141-
<bean class="com.beehyv.nmsreporting.business.impl.CookiesInterceptor">
172+
<mvc:mapping path="/nms/user/deleteUser"/>
173+
<bean class="com.beehyv.nmsreporting.business.impl.CsrfInterceptor">
142174
</bean>
143175
</mvc:interceptor>
176+
177+
<mvc:interceptor>
178+
<mvc:mapping path="/nms/user/downloadAggPdf"/>
179+
<bean class="com.beehyv.nmsreporting.business.impl.CsrfInterceptor">
180+
</bean>
181+
</mvc:interceptor>
182+
183+
<mvc:interceptor>
184+
<mvc:mapping path="/nms/user/generateAgg"/>
185+
<bean class="com.beehyv.nmsreporting.business.impl.CsrfInterceptor">
186+
</bean>
187+
</mvc:interceptor>
188+
189+
<mvc:interceptor>
190+
<mvc:mapping path="/nms/user/getReport"/>
191+
<bean class="com.beehyv.nmsreporting.business.impl.CsrfInterceptor">
192+
</bean>
193+
</mvc:interceptor>
194+
195+
<mvc:interceptor>
196+
<mvc:mapping path="/nms/user/resetPassword"/>
197+
<bean class="com.beehyv.nmsreporting.business.impl.CsrfInterceptor">
198+
</bean>
199+
</mvc:interceptor>
200+
201+
<mvc:interceptor>
202+
<mvc:mapping path="/nms/user/updateContacts"/>
203+
<bean class="com.beehyv.nmsreporting.business.impl.CsrfInterceptor">
204+
</bean>
205+
</mvc:interceptor>
206+
207+
<mvc:interceptor>
208+
<mvc:mapping path="/nms/user/updateUser"/>
209+
<bean class="com.beehyv.nmsreporting.business.impl.CsrfInterceptor">
210+
</bean>
211+
</mvc:interceptor>
212+
213+
<!-- Csrf Interceptor clode-->
214+
144215
</mvc:interceptors>
145216
<bean id="autoReportMail" class="com.beehyv.nmsreporting.job.AutoReportEmailGeneration"/>
146217
<task:scheduled-tasks>

app/scripts/app.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
var nmsReportsApp = angular.module('nmsReports', ['vcRecaptcha','ui.bootstrap', 'ui.validate', 'ngMessages', 'ui.router', 'ui.grid', 'ngMaterial', 'ngFileUpload', 'ng.deviceDetector', 'ui.grid.exporter', 'ngStorage', 'ngAnimate', '$idle', 'mdo-angular-cryptography'])
23
.run(['$rootScope', '$state', '$stateParams', '$idle', '$http', '$window', function($rootScope, $state, $stateParams, $idle, $http, $window) {
34
$rootScope.$state = $state;
@@ -26,12 +27,31 @@ var nmsReportsApp = angular.module('nmsReports', ['vcRecaptcha','ui.bootstrap',
2627
if(!result.data){
2728
$state.go('login', {});
2829
}
30+
else {
31+
$http.post(backend_root + 'nms/user/currentUser')
32+
.then(function(result){
33+
if(result.data.default){
34+
$state.go('changePassword', {});
35+
}
36+
});
37+
}
2938
});
3039
}
3140
};
3241
}
3342
])
3443

44+
.factory('httpRequestInterceptor',
45+
function () {
46+
return {
47+
request: function (config) {
48+
config.headers['SameSite'] = 'Lax';
49+
return config;
50+
}
51+
};
52+
}
53+
)
54+
3555
.factory('authorizationRole', ['$http', '$state',
3656
function($http, $state) {
3757
return {
@@ -350,6 +370,11 @@ var nmsReportsApp = angular.module('nmsReports', ['vcRecaptcha','ui.bootstrap',
350370
$idleProvider.interrupt('keydown mousedown touchstart touchmove');
351371
$idleProvider.setIdleTime(1800);
352372
}])
373+
374+
.config(function ($httpProvider) {
375+
$httpProvider.interceptors.push('httpRequestInterceptor');
376+
})
377+
353378
.config(['$cryptoProvider', function($cryptoProvider) {
354379
$cryptoProvider.setCryptographyKey('ABCD123');
355380
}]);

app/scripts/controllers/bulkUser.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@
3737
//We can send anything in name parameter,
3838
//it is hard coded to abc as it is irrelavant in this case.
3939
var uploadUrl = backend_root + "nms/admin/uploadFile";
40+
var token = 'dhty'+UserFormFactory.getCurrentUser().userId+'alkihkf';
4041
$http.post(uploadUrl, fd, {
4142
transformRequest: angular.identity,
42-
headers: {'Content-Type': undefined}
43+
headers: {'Content-Type': undefined, 'csrfToken': token}
4344
})
4445
.then(function(result){
4546
$scope.listErrors(result.data)

app/scripts/controllers/changePassword.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,12 @@
4343
//"cipherTextHexOld": encryptedOld.ciphertext.toString(),
4444
//"saltHexOld":newPassword encryptedOld.salt.toString()
4545
};
46+
var token = 'dhty'+UserFormFactory.getCurrentUser().userId+'alkihkf';
4647
$http({
4748
method: 'POST',
4849
url: backend_root + 'nms/user/resetPassword',
4950
data: JSON.stringify(data),
50-
headers: {'Content-Type': 'application/json'}
51+
headers: {'Content-Type': 'application/json', 'csrfToken': token}
5152
}).then(function(result){
5253
// $http({
5354
// method : 'POST',

app/scripts/controllers/contactUs.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,13 @@
202202
"subject" : $scope.email.subject,
203203
"phoneNo" : $scope.email.phoneNo
204204
};
205+
var token = 'dhty'+UserFormFactory.getCurrentUser().userId+'alkihkf';
206+
205207
$http({
206208
method : 'POST',
207209
url : backend_root + 'nms/mail/sendEmailForContactUs',
208210
data : JSON.stringify(data), //forms user object
209-
headers : {'Content-Type': 'application/json'}
211+
headers : {'Content-Type': 'application/json', 'csrfToken': token}
210212
}).then(function(){
211213
if(UserFormFactory.isInternetExplorer()){
212214
alert('Contact-us form submitted successfully')

app/scripts/controllers/createUser.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,12 @@
106106
$scope.createUserSubmit = function() {
107107
if ($scope.createUserForm.$valid) {
108108
delete $scope.newUser.$$hashKey;
109+
var token = 'dhty'+UserFormFactory.getCurrentUser().userId+'alkihkf';
109110
$http({
110111
method : 'post',
111112
url : backend_root + 'nms/user/createUser',
112113
data : $scope.newUser, //forms user object
113-
headers : {'Content-Type': 'application/json'}
114+
headers : {'Content-Type': 'application/json', 'csrfToken': token}
114115
}).then(function(result){
115116
if(UserFormFactory.isInternetExplorer()){
116117
alert(result.data['0'])

0 commit comments

Comments
 (0)