Business Logic Error leading to free subscription upgrades and 12% discounts on hotel bookings.
Target Application Overview
The target was a B2B hotel reservation platform providing hotel bookings and premium subscription services.
The application implemented four subscription tiers:
- Diamond
- Platinum
- Gold
- Silver
Each tier provided loyalty point multipliers and booking discount benefits.
Diamond subscriptions offered:
- 12% booking discount
- 3x loyalty points
- Premium membership benefits
Technology Stack
- Amazon Infrastructure
- Cloudflare WAF
- ReactJS
- REST APIs
Encrypted Application Traffic
Application requests and responses were encrypted using symmetric cryptography.
Both client-side and server-side logic relied on the same shared encryption key.
This required reversing the cryptographic implementation before manipulating requests.
JavaScript Analysis
Analysis of the application's JavaScript bundles revealed that cryptographic operations were centralized through a shared CDN architecture.
The same cryptographic framework was reused across multiple applications operated by the organization.
Extracted CDN Configuration
91622: function (e, t) {
'use strict';
t.Z = {
apiDomain: 'https://api.target.com',
adminDomain: 'https://admin.target.com',
searchApiDomain: 'https://search.target.com',
searchApiDomain: 'https://search.target.com',
preprodApiDomain: 'https://preprod.target.com',
bookingApiDomain: 'https://bookings.target.com',
blogsApiDomain: 'https://secure.target.com',
analyticsDomain: 'https://analytics.target.com',
cdnPath: 'https://cdn.target.com',
s3accessKeyId: 'test-############',
s3secretKey: 'test-############',
s3Region: 'west',
dataHasKey: '###################=',
dataIVKey: 'jm8lgqa3j1d0ajus',
zendesk: '###########################',
giftCardUrl: 'https://join.target.com/gift-card/',
ASSET_CDN_PATH: 'https://assets.target.com',
consoleEnv: 'production',
recaptchaV2Key: '###################-kAQFKNGH-',
SHOPBACK_URL_DYNAMIC: 'https://shopback.target.org/aff_l',
SHOPBACK_MERCHANT_ID: '#########',
encryptionKeys: '["##_analytics_detail||VWlRMVRtTnllWEJVSVRCdUo=","club_membership_detail||RFZEVW1WMEtFQlJKSDA9"]'
}
}
The JavaScript bundles exposed:
- Encryption keys
- Initialization vectors
- API endpoints
- Cryptographic modes
Extracted Encryption Logic
abc.factory('EncryptDecrypt', [
'AppSettings',
function () {
return {
encryptKEY: 'UiQ1TmNyeXBUITBudgwtbynjybJDVDUmV0KEBRJH0=',
setkey: function (t) {
this.encryptKEY = t
},
encrypt: function (t) {
var e = this.encryptKEY,
n = 'jm8lgqa3j1d0ajus',
r = JSON.stringify(t);
return CryptoJS.AES.encrypt(r, CryptoJS.enc.Utf8.parse(e), {
iv: CryptoJS.enc.Utf8.parse(n),
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC
}).toString() + '---' + window.btoa(n)
},
decrypt: function (t) {
var e = t.split('---'),
n = browserCrypto.Buffer.from(e[1], 'base64'),
r = browserCrypto.Buffer.from(e[0], 'base64'),
a = browserCrypto.Buffer.from(this.encryptKEY),
o = browserCrypto.createDecipheriv('aes256', a, n),
i = o._update(r),
s = o.final(),
l = (i = browserCrypto.Buffer.concat([i,
s])).toString();
return JSON.parse(l)
}
}
}
])
The application used:
- AES CBC mode
- Static IV
- Hardcoded encryption keys
- Client-side encryption
Reversing the Encryption
Once the encryption parameters were extracted, encrypted payloads could be decrypted and modified externally.
This enabled inspection of internal API workflows and business logic parameters.
Membership Subscription Flow
The application introduced a newly developed subscription feature with multiple payment workflows.
A parameter named:
"payment_method"
was used internally to identify payment handling logic.
Add Membership Request
PUT /api/v18/add_membership HTTP/2
Host: api.target.com
{
"data":
"EncryptedPayload---Base64IV"
}
The above request initiated a Diamond membership purchase during hotel booking.
The intended workflow granted:
- 12% booking discounts
- 2 months of Diamond membership
- Enhanced loyalty point multipliers
Business Logic Flaw
During analysis it was discovered that modifying the
payment_method value altered the backend
payment processing behavior.
Changing: 26 to 21.
Removed the additional payment amount associated with the Diamond membership subscription.
Payment Request
POST /api/v16/purchase_add_ons HTTP/2
Host: api.target.com
{
"data":
"EncryptedPayload---Base64IV"
}
Despite the manipulated payment flow, the request still contained membership activation parameters.
Membership Parameters
{
"user_club_membership_id": 123456,
"diamond_club": true
}
The backend trusted the membership-related values supplied inside the encrypted request payload.
As a result:
- Diamond membership activated successfully
- No additional payment was required
- Booking discounts were applied
- Loyalty multipliers became active
The backend validated booking completion but failed to verify whether membership payment was actually processed.
Impact
- Free premium subscriptions
- Unauthorized 12% booking discounts
- Loyalty reward abuse
- Payment workflow manipulation
- Revenue loss
- Business logic exploitation
Root Cause
- Improper payment validation
- Trusting client-controlled parameters
- Weak business workflow enforcement
- Hardcoded client-side cryptography
- Improper subscription activation logic
Mitigation
- Validate payment completion server-side
- Remove client-side trust assumptions
- Separate payment and membership workflows
- Use secure cryptographic key management
- Implement transaction integrity checks
Conclusion
Business logic vulnerabilities frequently emerge when new features are integrated into existing transactional systems without holistic workflow validation.
In this case, manipulating payment workflow identifiers allowed premium membership activation without successful payment processing.
Applications handling subscriptions and financial logic must validate transactional integrity server-side rather than relying on client-controlled workflow parameters.
Thank you for reading.