-
Notifications
You must be signed in to change notification settings - Fork 0
Add PR_7_js for js #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| const wkhtmltopdf = require('wkhtmltopdf') | ||
| const express = require("express"); | ||
| const app = express(); | ||
|
|
||
|
|
||
| function input() { | ||
| app.get("/add/:userInput", function (req, res) { | ||
| return req.params['userInput'] | ||
| }); | ||
| } | ||
| // {fact rule=server-side-request-forgery@v1.0 defects=1} | ||
| // ruleid: wkhtmltopdf-injection | ||
| wkhtmltopdf(input(), { output: 'vuln.pdf' }) | ||
| // {/fact} | ||
|
|
||
| // {fact rule=server-side-request-forgery@v1.0 defects=1} | ||
| app.get("/add/:userInput", function (req, res) { | ||
| // ruleid: wkhtmltopdf-injection | ||
| return wkhtmltopdf(req.params['userInput'], { output: 'vuln.pdf' }) | ||
| }); | ||
| // {/fact} | ||
|
|
||
| // {fact rule=server-side-request-forgery@v1.0 defects=0} | ||
| // ok: wkhtmltopdf-injection | ||
| wkhtmltopdf('<html><html/>', { output: 'vuln.pdf' }) | ||
| // {/fact} | ||
|
|
||
| // {fact rule=server-side-request-forgery@v1.0 defects=0} | ||
| function okTest(userInput) { | ||
| var html = '<html><html/>'; | ||
| // ok: wkhtmltopdf-injection | ||
| return wkhtmltopdf(html, { output: 'vuln.pdf' }) | ||
| } | ||
| // {/fact} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| const puppeteer = require('puppeteer'); | ||
| const express = require('express') | ||
| const app = express() | ||
|
|
||
| app.get('/user/:userInput', async function (req, res) { | ||
|
|
||
| const browser = await puppeteer.launch(); | ||
| const page = await browser.newPage(); | ||
| // {fact rule=server-side-request-forgery@v1.0 defects=0} | ||
| // ok | ||
| await page.evaluate(x => console.log(x), 5); | ||
| // {/fact} | ||
|
|
||
| // {fact rule=server-side-request-forgery@v1.0 defects=1} | ||
| // ruleid:puppeteer-evaluate-arg-injection | ||
| await page.evaluate(x => fetch(x), req.params.userInput); | ||
| // {/fact} | ||
| await page.screenshot({path: 'example.png'}); | ||
| await browser.close(); | ||
| }); |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,30 @@ | ||||||||||||||||||||||||||||||||
| const puppeteer = require('puppeteer'); | ||||||||||||||||||||||||||||||||
| const express = require("express"); | ||||||||||||||||||||||||||||||||
| const app = express(); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| function unverifiedInput() { | ||||||||||||||||||||||||||||||||
| app.get("/add/:userInput", function (req, res) { | ||||||||||||||||||||||||||||||||
| return req.params['userInput'] | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // {fact rule=server-side-request-forgery@v1.0 defects=0} | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| (async () => { | ||||||||||||||||||||||||||||||||
| const browser = await puppeteer.launch(); | ||||||||||||||||||||||||||||||||
| const page = await browser.newPage(); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // ok | ||||||||||||||||||||||||||||||||
| await page.setContent('<html></html>'); | ||||||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // {fact rule=server-side-request-forgery@v1.0 defects=1} | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // ruleid:puppeteer-setcontent-injection | ||||||||||||||||||||||||||||||||
| await page.setContent(unverifiedInput()); | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Caution Description: Unverified user input is directly used in page.setContent(), potentially leading to XSS attacks. Sanitize or validate the input from unverifiedInput() before passing it to page.setContent(). Severity: Critical There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fix addresses the vulnerability by sanitizing the user input before passing it to page.setContent(). It uses the DOMPurify library to remove potentially malicious content from the input, preventing XSS attacks. The sanitized input is then used in page.setContent(), making the operation safer.
Suggested change
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| await page.screenshot({path: 'example.png'}); | ||||||||||||||||||||||||||||||||
| await browser.close(); | ||||||||||||||||||||||||||||||||
| })(); | ||||||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| const puppeteer = require('puppeteer'); | ||
| const express = require('express') | ||
| const app = express() | ||
|
|
||
| userInput = '' | ||
|
|
||
| app.get('/user/:userInput', async function (req, res) { | ||
| userInput=req.params.userInput | ||
| }); | ||
|
|
||
| function unverifiedInput(){ | ||
| app.get('/user/:userInput', async function (req, res) { | ||
| retrun = req.params.userInput | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| }); | ||
| } | ||
|
|
||
| const testFunc = async (userInput) => { | ||
| const browser = await puppeteer.launch(); | ||
| const page = await browser.newPage(); | ||
| let url = 'https://hardcoded.url.com' | ||
| // {fact rule=server-side-request-forgery@v1.0 defects=0} | ||
| // ok | ||
| await page.goto('https://example.com'); | ||
| // {/fact} | ||
|
|
||
| // {fact rule=server-side-request-forgery@v1.0 defects=0} | ||
| // ok | ||
| await page.goto(url); | ||
| // {/fact} | ||
|
|
||
| // {fact rule=server-side-request-forgery@v1.0 defects=1} | ||
| // ruleid:puppeteer-goto-injection | ||
| await page.goto(unverifiedInput()); | ||
| // {/fact} | ||
|
|
||
| const newUrl = userInput; | ||
| // {fact rule=server-side-request-forgery@v1.0 defects=1} | ||
| // ruleid:puppeteer-goto-injection | ||
| await page.goto(newUrl); | ||
| // {/fact} | ||
| await page.screenshot({path: 'example.png'}); | ||
| await browser.close(); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| const puppeteer = require('puppeteer'); | ||
| const express = require("express"); | ||
| const app = express(); | ||
|
|
||
| async function test2(userInput) { | ||
|
|
||
| const browser = await puppeteer.launch(); | ||
| const page = await browser.newPage(); | ||
| // {fact rule=server-side-request-forgery@v1.0 defects=0} | ||
|
|
||
| // ok:puppeteer-evaluate-code-injection | ||
| await page.evaluate(x => console.log(x), 5); | ||
| // {/fact} | ||
|
|
||
| // {fact rule=server-side-request-forgery@v1.0 defects=1} | ||
|
|
||
| // ruleid:puppeteer-evaluate-code-injection | ||
| await page.evaluate(`fetch(${userInput})`); | ||
| // {/fact} | ||
|
|
||
| await page.screenshot({path: 'example.png'}); | ||
| await browser.close(); | ||
| } | ||
|
|
||
| function call() { | ||
| app.get("/add/:userInput", function (req, res) { | ||
| test2(req.params['userInput']) | ||
| }); | ||
| } | ||
|
|
||
| call() |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,167 @@ | ||||||||||||||||||||||||||||
| const vm = require('vm') | ||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=1} | ||||||||||||||||||||||||||||
| let ctrl1 = function test1(req,res) { | ||||||||||||||||||||||||||||
| var input = req.query.something || '' | ||||||||||||||||||||||||||||
| var sandbox = { | ||||||||||||||||||||||||||||
| foo: input | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| vm.createContext(sandbox) | ||||||||||||||||||||||||||||
| // ruleid:express-vm-injection | ||||||||||||||||||||||||||||
| vm.runInContext('safeEval(orderLinesData)', sandbox, { timeout: 2000 }) | ||||||||||||||||||||||||||||
| res.send('hello world') | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| app.get('/', ctrl1) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=1} | ||||||||||||||||||||||||||||
| app.get('/', (req,res) => { | ||||||||||||||||||||||||||||
| var sandbox = { | ||||||||||||||||||||||||||||
| foo: req.query.userInput | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| vm.createContext(sandbox) | ||||||||||||||||||||||||||||
| // ruleid:express-vm-injection | ||||||||||||||||||||||||||||
| vm.runInContext('safeEval(orderLinesData)', sandbox, { timeout: 2000 }) | ||||||||||||||||||||||||||||
| res.send('hello world') | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=0} | ||||||||||||||||||||||||||||
| // ok:express-vm-injection | ||||||||||||||||||||||||||||
| function testOk1(userInput) { | ||||||||||||||||||||||||||||
| var sandbox = { | ||||||||||||||||||||||||||||
| foo: 1 | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| vm.createContext(sandbox) | ||||||||||||||||||||||||||||
| vm.runInContext('safeEval(orderLinesData)', sandbox, { timeout: 2000 }) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=1} | ||||||||||||||||||||||||||||
| var ctrl2 = null; | ||||||||||||||||||||||||||||
| ctrl2 = function test2(req,res) { | ||||||||||||||||||||||||||||
| var input = req.query.something || '' | ||||||||||||||||||||||||||||
| var sandbox = { | ||||||||||||||||||||||||||||
| foo: input | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| // ruleid:express-vm-injection | ||||||||||||||||||||||||||||
| vm.runInNewContext('safeEval(orderLinesData)', sandbox, { timeout: 2000 }) | ||||||||||||||||||||||||||||
| res.send('hello world') | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| app.get('/', ctrl2) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=1} | ||||||||||||||||||||||||||||
| app.get('/', function (req,res) { | ||||||||||||||||||||||||||||
| var sandbox = { | ||||||||||||||||||||||||||||
| foo: req.query.userInput | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| // ruleid:express-vm-injection | ||||||||||||||||||||||||||||
| vm.runInNewContext('safeEval(orderLinesData)', sandbox, { timeout: 2000 }) | ||||||||||||||||||||||||||||
| res.send('hello world') | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=0} | ||||||||||||||||||||||||||||
| // ok:express-vm-injection | ||||||||||||||||||||||||||||
| app.get('/', function testOk1(userInput) { | ||||||||||||||||||||||||||||
| var sandbox = { | ||||||||||||||||||||||||||||
| foo: 1 | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| vm.runInNewContext('safeEval(orderLinesData)', sandbox, { timeout: 2000 }) | ||||||||||||||||||||||||||||
| res.send('hello world') | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=1} | ||||||||||||||||||||||||||||
| app.get('/', function(req,res) { | ||||||||||||||||||||||||||||
| const code = ` | ||||||||||||||||||||||||||||
| var x = ${req.query.userInput}; | ||||||||||||||||||||||||||||
| ` | ||||||||||||||||||||||||||||
| // ruleid:express-vm-injection | ||||||||||||||||||||||||||||
| vm.runInThisContext(code) | ||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Caution Description: Passing unsanitized user data to Severity: Critical There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fix sanitizes the user input using validator.escape() to prevent code injection, and replaces vm.runInThisContext() with eval() for safer execution of the code string.
Suggested change
|
||||||||||||||||||||||||||||
| res.send('hello world') | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=0} | ||||||||||||||||||||||||||||
| // ok:express-vm-injection | ||||||||||||||||||||||||||||
| app.get('/', function okTest3(req,res) { | ||||||||||||||||||||||||||||
| const code = ` | ||||||||||||||||||||||||||||
| var x = 1; | ||||||||||||||||||||||||||||
| ` | ||||||||||||||||||||||||||||
| vm.runInThisContext(code) | ||||||||||||||||||||||||||||
| res.send('hello world') | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=1} | ||||||||||||||||||||||||||||
| app.get('/', function test4(req,res) { | ||||||||||||||||||||||||||||
| const parsingContext = vm.createContext({name: 'world'}) | ||||||||||||||||||||||||||||
| const code = `return 'hello ' + ${req.query.userInput}` | ||||||||||||||||||||||||||||
| // ruleid:express-vm-injection | ||||||||||||||||||||||||||||
| let fn = vm.compileFunction(code, [], { parsingContext }) | ||||||||||||||||||||||||||||
| res.send('hello world') | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=0} | ||||||||||||||||||||||||||||
| // ok:express-vm-injection | ||||||||||||||||||||||||||||
| app.get('/', function okTest4(req,res) { | ||||||||||||||||||||||||||||
| const parsingContext = vm.createContext({name: 'world'}) | ||||||||||||||||||||||||||||
| const code = `return 'hello ' + name` | ||||||||||||||||||||||||||||
| const fn = vm.compileFunction(code, [], { parsingContext }) | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=1} | ||||||||||||||||||||||||||||
| app.get('/', (req,res) => { | ||||||||||||||||||||||||||||
| const context = vm.createContext({name: req.query.userInput}) | ||||||||||||||||||||||||||||
| let code = `return 'hello ' name` | ||||||||||||||||||||||||||||
| // ruleid:express-vm-injection | ||||||||||||||||||||||||||||
| const fn = vm.compileFunction(code, [], { parsingContext: context }) | ||||||||||||||||||||||||||||
| res.send('hello world') | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=0} | ||||||||||||||||||||||||||||
| // ok:express-vm-injection | ||||||||||||||||||||||||||||
| app.get('/', function okTest5(req, res) { | ||||||||||||||||||||||||||||
| const parsingContext = vm.createContext({name: 'world'}) | ||||||||||||||||||||||||||||
| const code = `return 'hello ' + name` | ||||||||||||||||||||||||||||
| const fn = vm.compileFunction(code, [], { parsingContext }) | ||||||||||||||||||||||||||||
| res.send('hello world') | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=1} | ||||||||||||||||||||||||||||
| app.get('/', function (req,res) { | ||||||||||||||||||||||||||||
| // ruleid:express-vm-injection | ||||||||||||||||||||||||||||
| const script = new vm.Script(` | ||||||||||||||||||||||||||||
| function add(a, b) { | ||||||||||||||||||||||||||||
| return a + ${req.query.userInput}; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const x = add(1, 2); | ||||||||||||||||||||||||||||
| `); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| script.runInThisContext(); | ||||||||||||||||||||||||||||
| res.send('hello world') | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // {fact rule=code-injection@v1.0 defects=0} | ||||||||||||||||||||||||||||
| //ok:express-vm-injection | ||||||||||||||||||||||||||||
| app.get('/', function okTest6(req, res) { | ||||||||||||||||||||||||||||
| const script = new vm.Script(` | ||||||||||||||||||||||||||||
| function add(a, b) { | ||||||||||||||||||||||||||||
| return a + b; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const x = add(1, 2); | ||||||||||||||||||||||||||||
| `); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| script.runInThisContext(); | ||||||||||||||||||||||||||||
| res.send('hello world') | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| // {/fact} | ||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
input()function call on this line will evaluate toundefined. Theinputfunction (defined on lines 6-10) registers an Express route but does not return a value. Therefore,wkhtmltopdfis being called withundefinedas its first argument, which fails to demonstrate the intended security vulnerability.