@@ -90,7 +90,6 @@ of this software and associated documentation files (the "Software"), to deal
90
90
import java .net .Proxy ;
91
91
import java .security .SecureRandom ;
92
92
import java .util .Arrays ;
93
- import java .util .Base64 ;
94
93
import java .util .HashSet ;
95
94
import java .util .Set ;
96
95
import java .util .logging .Logger ;
@@ -339,7 +338,9 @@ public String getOauthScopes() {
339
338
340
339
public HttpResponse doCommenceLogin (StaplerRequest request , @ QueryParameter String from , @ Header ("Referer" ) final String referer )
341
340
throws IOException {
342
- final String state = getSecureRandomString ();
341
+ // https://tools.ietf.org/html/rfc6749#section-10.10 dictates that probability that an attacker guesses the string
342
+ // SHOULD be less than or equal to 2^(-160) and our Strings consist of 65 chars. (65^27 ~= 2^160)
343
+ final String state = getSecureRandomString (27 );
343
344
String redirectOnFinish ;
344
345
if (from != null && Util .isSafeToRedirectTo (from )) {
345
346
redirectOnFinish = from ;
@@ -479,14 +480,19 @@ private String getAccessToken(@Nonnull String code) throws IOException {
479
480
}
480
481
481
482
/**
482
- * Generates a random 20 byte String that conforms to the <a href="https://tools.ietf.org/html/rfc6749#section-10.10">specification</a>
483
- * requirements
484
- * @return a string that can be used as a state parameter
483
+ * Generates a random URL Safe String of n characters
485
484
*/
486
- private String getSecureRandomString () {
487
- final byte [] bytes = new byte [20 ];
488
- SECURE_RANDOM .nextBytes (bytes );
489
- return BASE64_ENCODER .encodeToString (bytes );
485
+ private String getSecureRandomString (int n ) {
486
+ if (n < 0 ){
487
+ throw new IllegalArgumentException ("Length must be a positive integer" );
488
+ }
489
+ // See RFC3986
490
+ final String urlSafeChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_" ;
491
+ final StringBuilder sb = new StringBuilder ();
492
+ for (int i = 0 ; i < n ; i ++){
493
+ sb .append (urlSafeChars .charAt (SECURE_RANDOM .nextInt (urlSafeChars .length ())));
494
+ }
495
+ return sb .toString ();
490
496
}
491
497
/**
492
498
* Returns the proxy to be used when connecting to the given URI.
@@ -821,8 +827,6 @@ static Jenkins getJenkins() {
821
827
822
828
private static final SecureRandom SECURE_RANDOM = new SecureRandom ();
823
829
824
- private static final Base64 .Encoder BASE64_ENCODER = Base64 .getUrlEncoder ().withoutPadding ();
825
-
826
830
/**
827
831
* Asks for the password.
828
832
*/
0 commit comments