FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
SecurityShepherd/src/main/java/utils/Validate.java at dev · OWASP/SecurityShepherd · GitHub
OWASP
/
SecurityShepherd
Public
Notifications
You must be signed in to change notification settings
Fork
515
Star
1.5k
Code
Issues
137
Pull requests
21
Discussions
Actions
Projects
Wiki
Security and quality
0
Insights
Additional navigation options
Code
Issues
Pull requests
Discussions
Actions
Projects
Wiki
Security and quality
Insights
Expand file tree
Breadcrumbs
SecurityShepherd
/
src
/
main
/
java
/
utils
/
Validate.java
Copy path
More file actions
More file actions
Latest commit
History
History
History
516 lines (484 loc) · 17 KB
Breadcrumbs
SecurityShepherd
/
src
/
main
/
java
/
utils
/
Validate.java
Copy path
File metadata and controls
516 lines (484 loc) · 17 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
package
utils
;
import
java
.
math
.
BigInteger
;
import
javax
.
mail
.
internet
.
AddressException
;
import
javax
.
mail
.
internet
.
InternetAddress
;
import
javax
.
servlet
.
http
.
Cookie
;
import
javax
.
servlet
.
http
.
HttpSession
;
import
org
.
apache
.
logging
.
log4j
.
LogManager
;
import
org
.
apache
.
logging
.
log4j
.
Logger
;
/**
* Class is used to validate various inputs <br>
* <br>
* This file is part of the Security Shepherd Project.
*
* <p>The Security Shepherd project is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.<br>
*
* <p>The Security Shepherd project is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.<br>
*
* <p>You should have received a copy of the GNU General Public License along with the Security
* Shepherd project. If not, see <http://www.gnu.org/licenses/>.
*
* @author Mark Denihan
*/
public
class
Validate
{
private
static
final
Logger
log
=
LogManager
.
getLogger
(
Validate
.
class
);
/**
* Finds JSession token from user's cookies[], validates and returns.
*
* @param userCookies Cookies from users browser
* @return JSession Id
*/
public
static
Cookie
getSessionId
(
Cookie
[]
userCookies
) {
int
i
=
0
;
Cookie
theSessionId
=
null
;
for
(
i
=
0
;
i
<
userCookies
.
length
;
i
++) {
if
(
userCookies
[
i
].
getName
().
compareTo
(
"JSESSIONID"
) ==
0
) {
theSessionId
=
userCookies
[
i
];
break
;
// End Loop, because we found the theSessionId
}
}
return
theSessionId
;
}
/**
* Finds CSRF token from user's cookies[], validates.
*
* @param userCookies All of the user's cookies from their browser
* @return csrfCookie
*/
public
static
Cookie
getToken
(
Cookie
[]
userCookies
) {
int
i
=
0
;
Cookie
theToken
=
null
;
for
(
i
=
0
;
i
<
userCookies
.
length
;
i
++) {
if
(
userCookies
[
i
].
getName
().
compareTo
(
"token"
) ==
0
) {
theToken
=
userCookies
[
i
];
break
;
// End Loop, because we found the token
}
}
if
(
theToken
!=
null
) {
// log.debug("Found Cookie " + theToken.getName() + " with value " +
// theToken.getValue());
// The Token is currently designed to be a random Big Integer. If the Big
// Integer Case does not work, the token has been modified. Potentially in a
// malicious manner
try
{
BigInteger
theTokenCasted
=
new
BigInteger
(
theToken
.
getValue
());
BigInteger
tenGrand
=
new
BigInteger
(
"10000"
);
BigInteger
tenGrandNeg
=
new
BigInteger
(
"-10000"
);
if
(!(
theTokenCasted
.
compareTo
(
tenGrand
) >
0
||
theTokenCasted
.
compareTo
(
tenGrandNeg
) <
0
)) {
log
.
error
(
"CSRF Cookie Token was modified in some manor!"
);
theToken
=
null
;
}
}
catch
(
Exception
e
) {
log
.
error
(
"CSRF Cookie Token was modified in some manor: "
+
e
.
toString
());
theToken
=
null
;
}
}
return
theToken
;
}
/**
* Validates class year when creating classes. Class year should be YY/YY, e.g. 11/12. So the
* first year must be less than the second.
*
* @param classYear Class Year in YY/YY format, e.g. 11/12.
* @return Boolean value stating weather or not these supplied attributes make a valid class year
*/
public
static
boolean
isValidClassYear
(
String
classYear
) {
boolean
result
=
false
;
result
=
classYear
.
length
() ==
4
;
if
(
result
) {
try
{
result
=
Integer
.
parseInt
(
classYear
) >
2010
;
}
catch
(
NumberFormatException
e
) {
log
.
error
(
"Could not parse classYear "
+
classYear
);
result
=
false
;
throw
new
RuntimeException
(
e
);
}
}
return
result
;
}
/**
* Email validation
*
* @param email
* @return Boolean reflect email validity
*/
public
static
boolean
isValidEmailAddress
(
String
email
) {
boolean
result
=
true
;
try
{
log
.
debug
(
"Validating email"
);
InternetAddress
emailAddr
=
new
InternetAddress
(
email
);
log
.
debug
(
"Did we crash"
);
emailAddr
.
validate
();
log
.
debug
(
"Didn't crash"
);
}
catch
(
AddressException
ex
) {
result
=
false
;
}
return
result
;
}
/**
* Invalid password detecter
*
* @param passWord
* @return
*/
public
static
boolean
isValidPassword
(
String
passWord
) {
boolean
result
=
false
;
result
=
passWord
.
length
() >
7
&&
passWord
.
length
() <=
512
;
if
(!
result
) {
log
.
debug
(
"Invalid Password detected"
);
}
return
result
;
}
/**
* Used to validate user creation requests
*
* @param userName User Name
* @param passWord User Password
* @return Boolean value stating weather or not these supplied attributes make a valid user
*/
public
static
boolean
isValidUser
(
String
userName
,
String
passWord
) {
int
userLength
=
userName
.
length
();
int
passLength
=
passWord
.
length
();
boolean
userOK
=
userLength
>
2
&&
userLength
<=
32
;
boolean
passOK
=
passLength
>
7
&&
passLength
<=
512
;
boolean
result
=
userOK
&&
passOK
;
if
(!
result
) {
log
.
debug
(
"Invalid Data detected in Validate.isValidUser()"
);
}
return
result
;
}
/**
* Used to validate user creation requests
*
* @param userName User Name
* @param passWord User Password
* @param userAddress User address
* @return Boolean value stating weather or not these supplied attributes make a valid user
*/
public
static
boolean
isValidUser
(
String
userName
,
String
passWord
,
String
userAddress
) {
boolean
result
=
false
;
result
=
userName
.
length
() >
2
&&
passWord
.
length
() >=
8
&&
userName
.
length
() <=
32
&&
passWord
.
length
() <=
512
&&
userAddress
.
length
() <=
128
;
if
(!
result
) {
log
.
debug
(
"Invalid Data detected in Validate.isValidUser()"
);
}
return
result
;
}
/**
* Quick method to prevent data and javascript URLs
*
* @param theUrl
* @return
*/
public
static
String
makeValidUrl
(
String
theUrl
) {
theUrl
=
theUrl
.
toLowerCase
();
if
(!
theUrl
.
startsWith
(
"http"
)) {
theUrl
=
"http"
+
theUrl
;
log
.
debug
(
"Transformed to: "
+
theUrl
);
}
return
theUrl
;
}
/**
* Session is checked for credentials and ensures that they have not been modified and that they
* are valid for an administrator
*
* @param ses HttpSession from users browser
* @return Boolean value that reflects the validity of the admins session
*/
public
static
boolean
validateAdminSession
(
HttpSession
ses
) {
boolean
result
=
false
;
String
userName
=
new
String
();
if
(
ses
==
null
) {
log
.
debug
(
"No Session Found"
);
}
else
{
if
(
ses
.
getAttribute
(
"logout"
) !=
null
) {
log
.
debug
(
"Logout Attribute Found: Invalidating session..."
);
ses
.
invalidate
();
// make servlet engine forget the session
}
else
{
// log.debug("Active Session Found");
if
(
ses
.
getAttribute
(
"userRole"
) !=
null
&&
ses
.
getAttribute
(
"userName"
) !=
null
) {
try
{
userName
= (
String
)
ses
.
getAttribute
(
"userName"
);
// log.debug("Session holder is " + userName);
String
role
= (
String
)
ses
.
getAttribute
(
"userRole"
);
result
= (
role
.
compareTo
(
"admin"
) ==
0
);
if
(!
result
) {
log
.
fatal
(
"User "
+
userName
+
" Attempting Admin functions! (CSRF Tokens Not Checked)"
);
}
}
catch
(
Exception
e
) {
log
.
fatal
(
"Tampered Parameter Detected!!! Could not parameters"
);
}
}
else
{
log
.
debug
(
"Session has no credentials"
);
}
}
}
return
result
;
}
/**
* Session is checked for credentials and ensures that they have not been modified and that they
* are valid for an administrator. This function also validates CSRF tokens
*
* @param ses HttpSession from users browser
* @return Boolean value that reflects the validity of the admins session
*/
public
static
boolean
validateAdminSession
(
HttpSession
ses
,
Cookie
cookieToken
,
Object
requestToken
) {
boolean
result
=
false
;
String
userName
=
new
String
();
if
(
ses
==
null
) {
log
.
debug
(
"No Session Found"
);
}
else
{
if
(
ses
.
getAttribute
(
"logout"
) !=
null
) {
log
.
debug
(
"Logout Attribute Found: Invalidating session..."
);
ses
.
invalidate
();
// make servlet engine forget the session
}
else
{
// log.debug("Active Session Found");
if
(
ses
.
getAttribute
(
"userRole"
) !=
null
&&
ses
.
getAttribute
(
"userName"
) !=
null
) {
try
{
userName
= (
String
)
ses
.
getAttribute
(
"userName"
);
// log.debug("Session holder is " + userName);
String
role
= (
String
)
ses
.
getAttribute
(
"userRole"
);
result
= (
role
.
compareTo
(
"admin"
) ==
0
);
if
(!
result
) {
// Check CSRF Tokens of User to ensure they are not being CSRF'd into causing
// Unauthorised Access Alert
boolean
validCsrfTokens
=
validateTokens
(
cookieToken
,
requestToken
);
if
(
validCsrfTokens
) {
log
.
fatal
(
"User account "
+
userName
+
" Attempting Admin functions! (With Valid CSRF Tokens)"
);
}
else
{
log
.
error
(
"User account "
+
userName
+
" accessing admin function with bad CSRF Tokens"
);
}
}
}
catch
(
Exception
e
) {
log
.
fatal
(
"Tampered Parameter Detected!!! Could not parameters"
);
}
}
else
{
log
.
debug
(
"Session has no credentials"
);
}
}
}
return
result
;
}
/**
* Takes a String submitted to be used to encrypt and makes it the correct length for an
* encryption key
*
* @param userSalt String to be validated
* @return A Valid Encryption Key based on the input
*/
public
static
String
validateEncryptionKey
(
String
userSalt
) {
String
newKey
=
new
String
();
int
keySize
=
userSalt
.
length
();
if
(
keySize
==
16
) {
// log.debug("Key Already Valid");
newKey
=
userSalt
;
}
else
{
if
(
keySize
>
16
) {
// log.debug("Key too Long...");
newKey
=
userSalt
.
substring
(
0
,
16
);
}
else
// Shorter than 16
{
// log.debug("Key too Short...");
newKey
=
userSalt
;
int
howManyTimes
= (
16
/
keySize
) -
1
;
// log.debug("Repeating String " + howManyTimes + " times");
for
(
int
i
=
0
;
i
<
howManyTimes
;
i
++) {
newKey
+=
userSalt
;
}
keySize
=
newKey
.
length
();
int
toAdd
=
16
-
keySize
;
// log.debug("Adding " + toAdd + " more characters");
newKey
=
newKey
.
concat
(
userSalt
.
substring
(
0
,
toAdd
));
}
}
log
.
debug
(
"Encryption key is '"
+
newKey
+
"'"
);
return
newKey
;
}
/**
* Function that will check if a valid language is set. if not, returns en (English)
*
* @param ses Session Language Parameter
* @return en by default, or the valid setting found in the submitted lang
*/
public
static
String
validateLanguage
(
HttpSession
ses
) {
String
result
=
"en_GB"
;
String
lang
=
new
String
();
try
{
lang
=
ses
.
getAttribute
(
"lang"
).
toString
();
}
catch
(
NullPointerException
e
) {
lang
=
""
;
}
// log.debug("lang submitted: " + lang);
if
(
lang
!=
null
) {
if
(
lang
.
matches
(
".[a-z]{2}-[A-Z]{2}$"
)) {
result
=
lang
;
}
}
// log.debug("lang set to: " + result);
return
result
;
}
/**
* Validates objects received through a function request. Also ensures max length is not too high.
*
* @param input Object to validate
* @param maxLength Maximum length of object
* @return Validated String value or empty string value
*/
public
static
String
validateParameter
(
Object
input
,
int
maxLength
) {
String
result
=
new
String
();
if
(
input
==
null
) {
result
=
new
String
();
}
else
{
result
= (
String
)
input
;
if
(
result
.
length
() >
maxLength
) {
log
.
debug
(
"Parameter Too Long: "
+
result
.
length
() +
" characters"
);
log
.
debug
(
"Parameter Was: "
+
result
);
result
=
new
String
();
}
}
return
result
;
}
/**
* Session is checked for credentials and ensures that they have not been modified and that they
* are valid
*
* @param ses HttpSession from users browser
* @return Boolean value that reflects the validity of the users session
*/
public
static
boolean
validateSession
(
HttpSession
ses
) {
boolean
result
=
false
;
if
(
ses
==
null
) {
log
.
debug
(
"No Session Found"
);
}
else
{
if
(
ses
.
getAttribute
(
"logout"
) !=
null
) {
log
.
debug
(
"Logout Attribute Found: Invalidating session..."
);
ses
.
invalidate
();
// make servlet engine forget the session
}
else
{
// log.debug("Active Session Found");
if
(
ses
.
getAttribute
(
"userRole"
) !=
null
) {
try
{
// log.debug("Session holder is "+ses.getAttribute("userName").toString());
String
role
= (
String
)
ses
.
getAttribute
(
"userRole"
);
result
= (
role
.
compareTo
(
"player"
) ==
0
||
role
.
compareTo
(
"admin"
) ==
0
);
if
(!
result
) {
log
.
fatal
(
"User Role Parameter Tampered. Role = "
+
role
);
}
else
{
String
userName
=
ses
.
getAttribute
(
"userName"
).
toString
();
// Has the user been suspended? Should they be kicked?
if
(
UserKicker
.
shouldKickUser
(
userName
)) {
log
.
debug
(
userName
+
" has been Suspended. Invalidating Session and Reporting Invalid"
+
" Session"
);
ses
.
invalidate
();
// Killing Session
result
=
false
;
// User will not access function they were attempting to call
UserKicker
.
removeFromKicklist
(
userName
);
// Removing from kick list, as they are now
// authenticated, the DB Layer Suspension
// will prevent them from signing in
}
}
}
catch
(
Exception
e
) {
log
.
fatal
(
"Tampered Parameter Detected!!! Could not Decrypt stamp"
);
}
}
else
{
log
.
debug
(
"Session has no credentials"
);
}
}
}
return
result
;
}
/**
* This method compares the two submitted tokens after ensuring they are not null and not empty.
*
* @param cookieToken CSRF cookie Token
* @param requestToken CSRF request Token
* @return A boolean value stating weather or not the tokens are valid
*/
public
static
boolean
validateTokens
(
Cookie
cookieToken
,
Object
requestToken
) {
boolean
result
=
false
;
boolean
cookieNull
= (
cookieToken
==
null
);
boolean
requestNull
= (
requestToken
==
null
);
if
(!
cookieNull
&& !
requestNull
) {
String
theRequest
= (
String
)
requestToken
;
String
theCookie
=
cookieToken
.
getValue
();
boolean
cookieEmpty
=
theCookie
.
isEmpty
();
boolean
requestEmpty
=
theRequest
.
isEmpty
();
if
(!
cookieEmpty
&& !
requestEmpty
) {
result
=
theRequest
.
compareTo
(
theCookie
) ==
0
;
}
else
if
(
cookieEmpty
) {
log
.
error
(
"Cookie Token Empty"
);
}
else
if
(
requestEmpty
) {
log
.
error
(
"Request Token Empty"
);
}
if
(!
result
) {
log
.
error
(
"CSRF Tokens did not match"
);
}
}
else
{
if
(
cookieNull
) {
log
.
error
(
"Cookie Token was Null"
);
}
else
if
(
requestNull
) {
log
.
error
(
"Request Token was Null"
);
}
}
return
result
;
}
/**
* Validates file name attributes to defend against path traversal
*
* @param fileName File name to validate
* @return Boolean value reflecting if valid or not
*/
/*
* public static String validateFileName(String fileName) {
* ShepherdLogManager.logEvent(request.getRemoteAddr(),
* request.getHeader("X-Forwarded-For"), "fileName: " + fileName); fileName =
* fileName.replaceAll(" ", "").replaceAll("\\.", "").replaceAll("/",
* "").replaceAll("\\\\", "").replaceAll("\n", "");
* ShepherdLogManager.logEvent(request.getRemoteAddr(),
* request.getHeader("X-Forwarded-For"), "fileName: " + fileName); return
* fileName; }
*/
public
static
boolean
validHostUrl
(
String
hostUrl
) {
// TODO - Pull other validation steps into this
boolean
result
;
result
=
hostUrl
.
endsWith
(
"/"
);
if
(!
result
) {
log
.
error
(
"URL Doesn't end with a forward slash. Very likely wrong"
);
}
return
result
;
}
/**
* Validates that a port number supplied is a valid port number
*
* @param portNum String to validate
* @return Boolean value reflecting if valid or not
*/
public
static
boolean
isValidPortNumber
(
String
portNum
) {
try
{
Integer
validPort
=
Integer
.
valueOf
(
portNum
);
if
(
validPort
<
1
||
validPort
>
65535
) {
log
.
fatal
(
"Value: "
+
portNum
+
"is not a valid port number"
);
return
false
;
}
}
catch
(
NumberFormatException
e
) {
log
.
fatal
(
"Value: "
+
portNum
+
"is not a valid port number"
);
return
false
;
}
return
true
;
}
}
Back
|
FazBrowse Home
|
New Git URL