Skip to content

SPARK-843107: Remediate 5 low security findings across widget-demo, token-input, and widget-meet - #1469

Draft
mkesavan13 wants to merge 1 commit into
masterfrom
SPARK-843107/secscan-react-widgets-low-remediate-5-unique-security-findings
Draft

SPARK-843107: Remediate 5 low security findings across widget-demo, token-input, and widget-meet#1469
mkesavan13 wants to merge 1 commit into
masterfrom
SPARK-843107/secscan-react-widgets-low-remediate-5-unique-security-findings

Conversation

@mkesavan13

Copy link
Copy Markdown
Contributor

COMPLETES SPARK-843107

This pull request addresses

[SecScan][react-widgets][Low] Remediate 5 unique security findings.

Five confirmed Low security findings in this repository's own workspace source
under packages/node_modules/@webex/*:

  • Unbounded guest JWT input reaching the Identity Broker with no client-side
    size/shape check.
  • A dev-only window.ciscoSparkEvents buffer that grew without bound and
    captured raw event details (including identity/message fields), initialized
    unconditionally (including in production) via index.html.
  • The token-input developer portal link used plaintext http:// with no safe
    rel/target attributes.
  • Raw bearer accessToken/accessTokenType values persisted to
    weakly-configured browser cookies (no Secure/SameSite/expiry/cleanup).
  • The call-placement path logged the meeting SIP/webLink destination and the
    raw call id via console.log.

by making the following changes

  • widget-demo/src/components/demo-widget/sdk.js — added a
    MAX_GUEST_JWT_LENGTH (8192-char) bound plus non-empty/string checks in
    createSDKGuestInstance; the accepted-input path is unchanged so the
    Identity Broker remains authoritative for JWT validation.
  • widget-demo/src/components/demo-widget/index.js — added a shared,
    development-only captureDemoEvent helper (no-op when
    process.env.NODE_ENV === 'production', capped at 50 entries, strips
    identity/message-shaped keys from detail) and routed both onEvent push
    sites through it; removed the raw accessToken/accessTokenType
    cookies.set writes and the corresponding constructor cookies.get reads
    (all non-token preference cookies are untouched).
  • widget-demo/src/index.html — removed the unconditional
    window.ciscoSparkEvents = [] init script (the dev-mode helper lazily
    creates the array; no production global buffer exists).
  • private-react-component-token-input/src/index.js — switched the
    developer portal anchor to https://developer.webex.com with
    target="_blank" rel="noopener noreferrer".
  • widget-meet/src/enhancers/withCallHandlers.js — removed the two
    console.log statements that disclosed the meeting SIP/webLink destination
    and the placed-call id; call placement and storeMeetDetails({callId}) are
    preserved. Exported handleCall (previously module-private) so it is
    directly unit-testable.
  • Added four new co-located *.test.js suites (9 tests total) covering all
    five findings — see Testing below.

Change Type

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Tooling change
  • Internal code refactor

The following scenarios were tested

  • The testing is done with the amplify link

New targeted unit tests were run during implementation (RED → GREEN → targeted
regression per task) with a final combined run of all four new test files: 4
suites, 9 tests, all passing at the time of the Fix step. This delivery step
does not rerun those tests; see ## Testing below for the recorded evidence
and gate status.

The GAI Coding Policy And Copyright Annotation Best Practices

  • GAI was not used (or, no additional notation is required)
  • Code was generated entirely by GAI
  • GAI was used to create a draft that was subsequently customized or modified
  • Coder created a draft manually that was non-substantively modified by GAI (e.g., refactoring was performed by GAI on manually written code)
  • Tool used for AI assistance (GitHub Copilot / Other - specify)
    • Github Copilot
    • Other - Please Specify: Claude (Anthropic) via the JiraToPr automation
  • This PR is related to
    • Feature
    • Defect fix
    • Tech Debt
    • Automation

Checklist before merging

  • I have not skipped any automated checks
  • All existing and new tests passed
  • I have updated the testing document

Testing

  • Tests added: 9 (across 4 new co-located *.test.js files: sdk.test.js 3,
    demo-widget/index.test.js 4, token-input/index.test.js 1,
    withCallHandlers.test.js 1).
  • Gate 1 verification: SKIPPED — skipped-missing-command — Gate 1 was not run because no applicable manifest declares commands.compile.
  • Gate 2 verification: SKIPPED — skipped-missing-command — Gate 2 was not run because no applicable manifest declares commands.unit-test.
  • Gate 3 verification: not run.
  • Draft warning: Gate 1 and Gate 2 were both skipped (skipped-missing-command); this PR has not been verified by the repository's compile/unit-test gates and must not be merged without independent human verification of the recorded test evidence below.
  • Coverage outcome: skipped because role coverage-check is absent.

Recorded evidence from the earlier Fix step (targeted per-task RED/GREEN/regression
runs via npx jest --config jest.config.json <file>, not rerun during delivery):

Task Test file Result
TASK-1 (AC-1) sdk.test.js 3/3 passing
TASK-2 (AC-2) index.test.js (ciscoSparkEvents capture) 2/2 passing
TASK-3 (AC-3) private-react-component-token-input/src/index.test.js 1/1 passing
TASK-4 (AC-4) index.test.js (token cookie storage) 2/2 passing
TASK-5 (AC-5) withCallHandlers.test.js 1/1 passing

Acceptance Criteria

ID Criterion Source JiraToPr status Evidence
AC-1 Guest JWT input is rejected cleanly when it exceeds a documented client-side size bound, while valid input still authenticates through the Identity Broker (server-side validation remains authoritative). Jira description: Acceptance Criteria Not validated — Gate 2 skipped sdk.test.js 3/3 passing (recorded Fix-step evidence; Gate 2 not run: skipped-missing-command)
AC-2 Production bundles retain no global window.ciscoSparkEvents buffer; any event capture is development-only, bounded, and redacted of message/identity metadata. Jira description: Acceptance Criteria Not validated — Gate 2 skipped index.test.js (ciscoSparkEvents capture) 2/2 passing (recorded Fix-step evidence; Gate 2 not run: skipped-missing-command)
AC-3 The token-input developer portal link uses the canonical HTTPS URL with safe external-link attributes and no plaintext developer portal link remains. Jira description: Acceptance Criteria Not validated — Gate 2 skipped private-react-component-token-input/src/index.test.js 1/1 passing (recorded Fix-step evidence; Gate 2 not run: skipped-missing-command)
AC-4 Raw bearer tokens are not persisted in weakly configured cookies; either token cookies are removed, or approved demo-only storage sets Secure and SameSite, minimizes lifetime/scope, and cleans up. Jira description: Acceptance Criteria Not validated — Gate 2 skipped; external validation required index.test.js (token cookie storage) 2/2 passing (recorded Fix-step evidence; Gate 2 not run: skipped-missing-command). Demo-storage owner sign-off is still pending — see External Validation Required below.
AC-5 Production logs contain no meeting destination (SIP URI/webLink) or raw call identifier values from the meet call handlers. Jira description: Acceptance Criteria Not validated — Gate 2 skipped withCallHandlers.test.js 1/1 passing (recorded Fix-step evidence; Gate 2 not run: skipped-missing-command)

External Validation Required

  • AC-4 — Raw bearer tokens are not persisted in weakly configured cookies.
    • Reason: owner-sign-off
    • Details: This boundary change (removing the raw accessToken/accessTokenType cookie writes and reads in demo-widget/index.js, at what were lines 101–102 and 127–128 pre-fix) changes how demo user browser storage persists bearer tokens. The code-level removal is implemented and unit-tested (index.test.jstoken cookie storage), but per the implementation plan's boundary-impact-4 note, the demo-storage owner must externally confirm this token-persistence removal is acceptable before delivery. If external validation instead prefers retaining demo-only storage, the equivalent remediation is to set Secure + SameSite, a minimized expiry, and explicit cleanup on those cookies.
    • Source: Triage boundary requirements (data | user: demo user browser storage)

External validation for AC-4 remains explicitly unrun by JiraToPr; unit evidence
is reported above while the demo-storage owner's sign-off remains pending for
human review.

Contract Discovery Warnings

  • No repository rule documents were discovered.
  • No repository contract document was discovered.
  • No .sdd/manifest.json, AGENTS.md, or spec index governs the affected demo/widget files; target/affected-package-manifests.json lists no package manifests for these paths. Planning relied on repository-inference from the affected files.

AI Assistance

  • Code was generated entirely by GAI / GAI-assisted / Manual
  • Tool: Claude (Anthropic) via the JiraToPr automation

Jira: https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-843107

…token-input, and widget-meet

Bounds guest JWT input before the Identity Broker, guards/bounds/redacts the
dev-only ciscoSparkEvents buffer, switches the developer portal link to HTTPS
with safe rel attributes, removes raw bearer-token cookie persistence, and
stops logging call destinations/ids on the call-placement path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mkesavan13 mkesavan13 added the jira-to-pr Automated Jira-to-PR delivery label Sep 4, 2026
@aws-amplify-us-east-2

Copy link
Copy Markdown

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-1469.d1l3lxgizk4iez.amplifyapp.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira-to-pr Automated Jira-to-PR delivery

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant