|
/** |
|
* PoC #2: Incorrect Access Control in @digitalocean/do-markdownit |
|
* Type: Web Demo Application (Express) |
|
* Author: Ali Firas - thesmartshadow |
|
* Date: 2025-09-04 |
|
*/ |
|
|
|
const express = require("express"); |
|
const bodyParser = require("body-parser"); |
|
const MarkdownIt = require("markdown-it"); |
|
const doMD = require("@digitalocean/do-markdownit"); |
|
|
|
const app = express(); |
|
app.use(bodyParser.urlencoded({ extended: false })); |
|
|
|
// Misconfigured allow-lists (strings instead of arrays) |
|
const md = MarkdownIt().use(doMD, { |
|
callout: { allowedClasses: "admin,info" }, |
|
fence_environment: { allowedEnvironments: "production,test" } |
|
}); |
|
|
|
// Fake admin panels (for demonstration only) |
|
let adminMessages = []; |
|
let environmentLogs = []; |
|
let posts = []; |
|
|
|
// Input page |
|
app.get("/", (req, res) => { |
|
res.send(` |
|
<h2>Markdown Editor (User Role)</h2> |
|
<form method="POST"> |
|
<textarea name="markdown" rows="8" cols="70"></textarea><br> |
|
<button type="submit">Publish</button> |
|
</form> |
|
<hr> |
|
<h3>Published Posts:</h3> |
|
${posts.map(p => `<div>${p}</div><hr>`).join("")} |
|
|
|
<h3>Admin Messages:</h3> |
|
<ul>${adminMessages.map(msg => `<li>${msg}</li>`).join("")}</ul> |
|
|
|
<h3>Environment Logs:</h3> |
|
<ul>${environmentLogs.map(log => `<li>${log}</li>`).join("")}</ul> |
|
`); |
|
}); |
|
|
|
// Handle Markdown input |
|
app.post("/", (req, res) => { |
|
const input = req.body.markdown || ""; |
|
|
|
// Naive protection: explicitly block "[admin]" and "[environment production]" |
|
if (input.includes("[admin]") || input.includes("[environment production]")) { |
|
return res.status(403).send("❌ You are not allowed to use admin or production."); |
|
} |
|
|
|
// Render Markdown |
|
const output = md.render(input); |
|
posts.push(output); |
|
|
|
// Detect bypassed usage |
|
if (input.includes("[in]")) { |
|
adminMessages.push("⚠️ Admin privileges triggered (via bypass)!"); |
|
} |
|
if (input.includes("[environment pro]")) { |
|
environmentLogs.push("⚠️ Production environment accessed (via bypass)!"); |
|
} |
|
|
|
res.redirect("/"); |
|
}); |
|
|
|
// Run server |
|
app.listen(3000, () => { |
|
console.log("PoC #2 running on http://localhost:3000"); |
|
console.log("Open http://localhost:3000 in your browser"); |
|
}); |