File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 77 "path/filepath"
88 "regexp"
99 "strings"
10+ "unicode"
1011
1112 "github.com/compozy/releasepr/internal/logger"
1213 "github.com/go-git/go-git/v5"
@@ -209,18 +210,16 @@ func (c *Config) ValidateForGitHubOperations() error {
209210 return c .Validate ()
210211}
211212
212- // ValidateGitHubToken validates GitHub token format (exported for reuse) .
213+ // ValidateGitHubToken validates that an opaque GitHub token is safe to pass to clients .
213214func ValidateGitHubToken (token string ) error {
214- token = strings .TrimSpace (token )
215- classicPAT := regexp .MustCompile (`^[a-fA-F0-9]{40}$` )
216- fineGrainedPAT := regexp .MustCompile (`^github_pat_[a-zA-Z0-9_]{82}$` )
217- appToken := regexp .MustCompile (`^ghs_[a-zA-Z0-9]{36}$` )
218- oauthToken := regexp .MustCompile (`^gho_[a-zA-Z0-9]{36}$` )
219- if ! classicPAT .MatchString (token ) &&
220- ! fineGrainedPAT .MatchString (token ) &&
221- ! appToken .MatchString (token ) &&
222- ! oauthToken .MatchString (token ) {
223- return fmt .Errorf ("invalid token format" )
215+ if strings .TrimSpace (token ) == "" {
216+ return fmt .Errorf ("token cannot be empty" )
217+ }
218+ containsUnsafeCharacter := strings .IndexFunc (token , func (character rune ) bool {
219+ return unicode .IsSpace (character ) || unicode .IsControl (character )
220+ }) >= 0
221+ if containsUnsafeCharacter {
222+ return fmt .Errorf ("token contains whitespace or control characters" )
224223 }
225224 return nil
226225}
Original file line number Diff line number Diff line change @@ -119,3 +119,27 @@ func TestConfigValidateReleaseArtifacts(t *testing.T) {
119119 require .Contains (t , err .Error (), "command must be one of" )
120120 })
121121}
122+
123+ func TestValidateGitHubToken (t * testing.T ) {
124+ t .Run ("Should accept opaque token values" , func (t * testing.T ) {
125+ tokens := []string {
126+ "ghs_1234567890_header.payload.signature" ,
127+ "github-enterprise-token-value" ,
128+ }
129+ for _ , token := range tokens {
130+ require .NoError (t , ValidateGitHubToken (token ))
131+ }
132+ })
133+
134+ t .Run ("Should reject empty tokens" , func (t * testing.T ) {
135+ require .ErrorContains (t , ValidateGitHubToken ("" ), "token cannot be empty" )
136+ require .ErrorContains (t , ValidateGitHubToken (" " ), "token cannot be empty" )
137+ })
138+
139+ t .Run ("Should reject whitespace and control characters" , func (t * testing.T ) {
140+ tokens := []string {"token with space" , "token\n value" , "token\x00 value" }
141+ for _ , token := range tokens {
142+ require .ErrorContains (t , ValidateGitHubToken (token ), "whitespace or control characters" )
143+ }
144+ })
145+ }
You can’t perform that action at this time.
0 commit comments