fix: Improve validation of Bot Tokens (#1206)
* improve bot token validation by trying to decode user id from token Try to decode the user id from the supplied bot token as a way of validating the token. If this should fail, indicate that the token is invalid. * Update the tokenutils tests to pass the new validation checks * Add test case for CheckBotTokenValidity method * lint: clean up whitespace * Add check for null or whitespace string, lint whitespace * fix userid conversion * Add hint to user to check that token is not an oauth client secret * Catch exception that can be thrown by GetString * Refactor token conversion logic into it's own testable method
This commit is contained in:
committed by
Christopher F
parent
91e0f03bfd
commit
f4b1a5f25b
@@ -76,9 +76,7 @@ namespace Discord
|
||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKW")]
|
||||
// 59 char token
|
||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs")]
|
||||
[InlineData("This appears to be completely invalid, however the current validation rules are not very strict.")]
|
||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWss")]
|
||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWsMTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs")]
|
||||
public void TestBotTokenDoesNotThrowExceptions(string token)
|
||||
{
|
||||
// This example token is pulled from the Discord Docs
|
||||
@@ -99,6 +97,9 @@ namespace Discord
|
||||
[InlineData("937it3ow87i4ery69876wqire")]
|
||||
// 57 char bot token
|
||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kK")]
|
||||
[InlineData("This is an invalid token, but it passes the check for string length.")]
|
||||
// valid token, but passed in twice
|
||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWsMTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs")]
|
||||
public void TestBotTokenInvalidThrowsArgumentException(string token)
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => TokenUtils.ValidateToken(TokenType.Bot, token));
|
||||
@@ -124,5 +125,44 @@ namespace Discord
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
TokenUtils.ValidateToken((TokenType)type, "MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks the <see cref="TokenUtils.CheckBotTokenValidity(string)"/> method for expected output.
|
||||
/// </summary>
|
||||
/// <param name="token"> The Bot Token to test.</param>
|
||||
/// <param name="expected"> The expected result. </param>
|
||||
[Theory]
|
||||
// this method only checks the first part of the JWT
|
||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4..", true)]
|
||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kK", true)]
|
||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4. this part is invalid. this part is also invalid", true)]
|
||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.", false)]
|
||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4", false)]
|
||||
[InlineData("NDI4NDc3OTQ0MDA5MTk1NTIw.xxxx.xxxxx", true)]
|
||||
// should not throw an unexpected exception
|
||||
[InlineData("", false)]
|
||||
[InlineData(null, false)]
|
||||
public void TestCheckBotTokenValidity(string token, bool expected)
|
||||
{
|
||||
Assert.Equal(expected, TokenUtils.CheckBotTokenValidity(token));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
// cannot pass a ulong? as a param in InlineData, so have to have a separate param
|
||||
// indicating if a value is null
|
||||
[InlineData("NDI4NDc3OTQ0MDA5MTk1NTIw", false, 428477944009195520)]
|
||||
// should return null w/o throwing other exceptions
|
||||
[InlineData("", true, 0)]
|
||||
[InlineData(" ", true, 0)]
|
||||
[InlineData(null, true, 0)]
|
||||
[InlineData("these chars aren't allowed @U#)*@#!)*", true, 0)]
|
||||
public void TestDecodeBase64UserId(string encodedUserId, bool isNull, ulong expectedUserId)
|
||||
{
|
||||
var result = TokenUtils.DecodeBase64UserId(encodedUserId);
|
||||
if (isNull)
|
||||
Assert.Null(result);
|
||||
else
|
||||
Assert.Equal(expectedUserId, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user