Skip to content

Commit 06c01e9

Browse files
author
Kanishka
committed
fix(plg): validate alternateDomain with isValidDomain before isSafeDomain
isSafeDomain documents that isValidDomain must have already accepted the input, but the alternateDomain path skipped that precondition. A value like https://evil.com/path would pass isSafeDomain since split('/')[0] returns https:, matching none of the blocked patterns. Also removes http://domain.com from the invalid-domains test fixture now that stripScheme normalises scheme-prefixed inputs before validation.
1 parent 2d4223b commit 06c01e9

2 files changed

Lines changed: 12 additions & 6 deletions

File tree

src/controllers/plg/plg-onboarding.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ async function postPlgOnboardingNotification(onboarding, context, hints = {}) {
239239
// AEM CS author URL pattern: https://author-p{programId}-e{environmentId}[-suffix].adobeaemcloud.com
240240
const AEM_CS_AUTHOR_URL_PATTERN = /^https?:\/\/author-p(\d+)-e(\d+)(?:-[^.]+)?\.adobeaemcloud\.(?:com|net)/i;
241241

242+
// Strip http:// or https:// scheme so callers can pass full URLs or bare hostnames interchangeably.
243+
const stripScheme = (s) => s.replace(/^https?:\/\//i, '');
244+
242245
// RFC 1123 hostname optionally followed by a URL path; no scheme, port, query, or fragment.
243246
// Hostname: max 253 chars, labels 1-63 alphanumeric/hyphen separated by dots.
244247
// Path segments: alphanumeric/hyphens/underscores with optional internal dots (e.g. v1.0).
@@ -656,8 +659,9 @@ async function createOrFindProject(baseURL, organizationId, context) {
656659
* @returns {Promise<object>} PlgOnboarding record
657660
*/
658661
async function performAsoPlgOnboarding({
659-
domain, imsOrgId, presetDeliveryType, presetAuthorUrl, presetProgramId,
662+
domain: rawDomain, imsOrgId, presetDeliveryType, presetAuthorUrl, presetProgramId,
660663
}, context) {
664+
const domain = stripScheme(rawDomain);
661665
const { dataAccess, env, log } = context;
662666
const callerIdentity = getReviewerIdentity(context);
663667
const {
@@ -1445,12 +1449,14 @@ function PlgOnboardingController(ctx) {
14451449
return badRequest('Request body is required');
14461450
}
14471451

1448-
const { domain, imsOrgId: requestedImsOrgId } = data;
1452+
const { domain: rawDomain, imsOrgId: requestedImsOrgId } = data;
14491453

1450-
if (!hasText(domain)) {
1454+
if (!hasText(rawDomain)) {
14511455
return badRequest('domain is required');
14521456
}
14531457

1458+
const domain = stripScheme(rawDomain);
1459+
14541460
const { authInfo } = attributes;
14551461

14561462
if (!authInfo) {
@@ -1894,8 +1900,9 @@ function PlgOnboardingController(ctx) {
18941900

18951901
// Handle alternateDomain: retire current domain, onboard a new domain under current org
18961902
if (hasText(siteConfig?.alternateDomain)) {
1897-
if (!isSafeDomain(siteConfig.alternateDomain)) {
1898-
return badRequest(`Invalid alternate domain: ${siteConfig.alternateDomain}`);
1903+
const altDomain = siteConfig.alternateDomain;
1904+
if (!isValidDomain(altDomain) || !isSafeDomain(altDomain)) {
1905+
return badRequest(`Invalid alternate domain: ${altDomain}`);
18991906
}
19001907
onboarding.setStatus(STATUSES.OUTDATED);
19011908
onboarding.setWaitlistReason(null);

test/controllers/plg/plg-onboarding.test.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,6 @@ describe('PlgOnboardingController', function describePlgOnboarding() {
698698
const invalidDomains = [
699699
'../../etc/passwd',
700700
'domain.com:8080',
701-
'http://domain.com',
702701
'-invalid.com',
703702
`${'a'.repeat(254)}.com`,
704703
'domain..com',

0 commit comments

Comments
 (0)