@@ -278,6 +278,11 @@ function _isAccountId(principal) {
278278 return ( principal . length === 12 && / ^ \d + $ / . test ( principal ) ) ;
279279}
280280
281+ /**
282+ * Checks if the ARN represents a root user account
283+ * @param {string } arn - The ARN to check
284+ * @returns {boolean } True if root user, false otherwise
285+ */
281286function _isRootUser ( arn ) {
282287 if ( ! arn ) {
283288 return false ;
@@ -286,7 +291,11 @@ function _isRootUser(arn) {
286291 // Vault returns the following arn when the account makes requests 'arn:aws:iam::295412255825:/master/',
287292 // with an empty resource type ('user/' prefix missing).
288293 const arns = arn . split ( ':' ) ;
289- const resource = arns . at ( - 1 ) ;
294+ if ( arns . length < 6 ) {
295+ return false
296+ }
297+
298+ const resource = arns [ arns . length - 1 ] ;
290299
291300 // If we start with '/' is because we have a empty resource type so we know it is a root account.
292301 if ( resource . startsWith ( '/' ) ) {
@@ -303,6 +312,8 @@ function _isRootUser(arn) {
303312 * @return {checkPrincipalResult } OK if it is not cross-account, CROSS_ACCOUNT_OK otherwise.
304313 */
305314function _checkCrossAccount ( requesterARN , requesterCanonicalID , bucketOwnerCanonicalID ) {
315+ // Vault returns ARNs like 'arn:aws:iam::123456789012:/master/' for root accounts
316+ // with an empty resource type (missing 'user/' prefix)
306317 if ( ! _isRootUser ( requesterARN ) ) {
307318 return bucketOwnerCanonicalID === requesterCanonicalID ?
308319 checkPrincipalResult . OK : checkPrincipalResult . CROSS_ACCOUNT_OK ;
0 commit comments