@@ -4,9 +4,12 @@ import * as path from 'path';
44import { PUBLIC_KEY } from './licensePublicKey' ;
55
66interface LicenseData {
7- sub ?: string ;
8- iat ?: number ;
7+ sub ?: string ; // Subject (email for whom the license is issued)
8+ iat ?: number ; // Issued at timestamp
99 exp : number ; // Required: expiration timestamp
10+ plan ?: string ; // Optional: license plan (e.g., "free", "paid")
11+ issued_by ?: string ; // Optional: who issued the license
12+ // Allow additional fields
1013 [ key : string ] : any ;
1114}
1215
@@ -114,6 +117,10 @@ function loadAndDecodeLicense(): LicenseData {
114117 const licenseString = loadLicenseString ( ) ;
115118
116119 const decoded = jwt . verify ( licenseString , PUBLIC_KEY , {
120+ // Enforce RS256 algorithm only to prevent "alg=none" and downgrade attacks.
121+ // Adding other algorithms to the whitelist (e.g., ['RS256', 'HS256']) can introduce vulnerabilities:
122+ // If the public key is mistakenly used as a secret for HMAC algorithms (like HS256), attackers could forge tokens.
123+ // Always carefully review algorithm changes to avoid signature bypass risks.
117124 algorithms : [ 'RS256' ] ,
118125 // Disable automatic expiration verification so we can handle it manually with custom logic
119126 ignoreExpiration : true ,
@@ -168,8 +175,7 @@ function handleInvalidLicense(message: string): never {
168175 * @private
169176 */
170177function logLicenseInfo ( license : LicenseData ) : void {
171- const plan = ( license as any ) . plan ;
172- const issuedBy = ( license as any ) . issued_by ;
178+ const { plan, issued_by : issuedBy } = license ;
173179
174180 if ( plan ) {
175181 console . log ( `[React on Rails Pro] License plan: ${ plan } ` ) ;
0 commit comments