Browse Source
			
			
			Merge pull request #743 from andreasbrett/patch-4
			
				Harden 2FA/TOTP implementation according to rfc6238 (part 2)
			
			
				pull/780/head
			
			
		 
		
			
				
					
						 Louis Lam
					
					4 years ago
						Louis Lam
					
					4 years ago
					
						
							committed by
							
								 GitHub
								GitHub
							
						 
					
				 
				
			 
		 
		
			
				
					
					No known key found for this signature in database
					
						
							GPG Key ID: 4AEE18F83AFDEB23
						
					
				
			
		
		
		
	
		
			
				 3 changed files with 
18 additions and 
4 deletions
			 
			
		 
		
			
				- 
					
					
					 
					db/patch-2fa-invalidate-used-token.sql
				
- 
					
					
					 
					server/database.js
				
- 
					
					
					 
					server/server.js
				
				
				
					
						
							
								
									
	
		
			
				
					|  |  | @ -0,0 +1,7 @@ | 
			
		
	
		
			
				
					|  |  |  | -- You should not modify if this have pushed to Github, unless it does serious wrong with the db. | 
			
		
	
		
			
				
					|  |  |  | BEGIN TRANSACTION; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | ALTER TABLE user | 
			
		
	
		
			
				
					|  |  |  |     ADD twofa_last_token VARCHAR(6); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | COMMIT; | 
			
		
	
								
							
						
					 
					
				 
			 
		
			
			
			
			
			
			
				
				
					
						
							
								
									
	
		
			
				
					|  |  | @ -50,6 +50,7 @@ class Database { | 
			
		
	
		
			
				
					|  |  |  |         "patch-group-table.sql": true, | 
			
		
	
		
			
				
					|  |  |  |         "patch-monitor-push_token.sql": true, | 
			
		
	
		
			
				
					|  |  |  |         "patch-http-monitor-method-body-and-headers.sql": true, | 
			
		
	
		
			
				
					|  |  |  |         "patch-2fa-invalidate-used-token.sql": true, | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     /** | 
			
		
	
	
		
			
				
					|  |  | 
 | 
			
		
	
								
							
						
					 
					
				 
			 
		
			
			
			
			
			
			
				
				
					
						
							
								
									
	
		
			
				
					|  |  | @ -292,7 +292,7 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
			
				
					|  |  |  |             if (user) { | 
			
		
	
		
			
				
					|  |  |  |                 afterLogin(socket, user); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 if (user.twofaStatus == 0) { | 
			
		
	
		
			
				
					|  |  |  |                 if (user.twofa_status == 0) { | 
			
		
	
		
			
				
					|  |  |  |                     callback({ | 
			
		
	
		
			
				
					|  |  |  |                         ok: true, | 
			
		
	
		
			
				
					|  |  |  |                         token: jwt.sign({ | 
			
		
	
	
		
			
				
					|  |  | @ -301,7 +301,7 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
			
				
					|  |  |  |                     }); | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 if (user.twofaStatus == 1 && !data.token) { | 
			
		
	
		
			
				
					|  |  |  |                 if (user.twofa_status == 1 && !data.token) { | 
			
		
	
		
			
				
					|  |  |  |                     callback({ | 
			
		
	
		
			
				
					|  |  |  |                         tokenRequired: true, | 
			
		
	
		
			
				
					|  |  |  |                     }); | 
			
		
	
	
		
			
				
					|  |  | @ -310,7 +310,13 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
			
				
					|  |  |  |                 if (data.token) { | 
			
		
	
		
			
				
					|  |  |  |                     let verify = notp.totp.verify(data.token, user.twofa_secret, twofa_verification_opts); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     if (verify && verify.delta == 0) { | 
			
		
	
		
			
				
					|  |  |  |                     if (user.twofa_last_token !== data.token && verify) { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                         await R.exec("UPDATE `user` SET twofa_last_token = ? WHERE id = ? ", [ | 
			
		
	
		
			
				
					|  |  |  |                             data.token, | 
			
		
	
		
			
				
					|  |  |  |                             socket.userID, | 
			
		
	
		
			
				
					|  |  |  |                         ]); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                         callback({ | 
			
		
	
		
			
				
					|  |  |  |                             ok: true, | 
			
		
	
		
			
				
					|  |  |  |                             token: jwt.sign({ | 
			
		
	
	
		
			
				
					|  |  | @ -428,7 +434,7 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             let verify = notp.totp.verify(token, user.twofa_secret, twofa_verification_opts); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             if (verify && verify.delta == 0) { | 
			
		
	
		
			
				
					|  |  |  |             if (user.twofa_last_token !== token && verify) { | 
			
		
	
		
			
				
					|  |  |  |                 callback({ | 
			
		
	
		
			
				
					|  |  |  |                     ok: true, | 
			
		
	
		
			
				
					|  |  |  |                     valid: true, | 
			
		
	
	
		
			
				
					|  |  | 
 |