contrib.nodejsscan.ssrf_playwright.playwright_ssrf

Author
99
Download Count*
License
If unverified user data can reach the puppeteer
methods it can result in Server-Side Request Forgery vulnerabilities.
Run Locally
Run in CI
Defintion
rules:
- id: playwright_ssrf
patterns:
- pattern-inside: |
require('playwright');
...
- pattern-either:
- pattern-inside: function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: $X = function $FUNC($REQ, $RES, ...) {...}
- pattern-inside: var $X = function $FUNC($REQ, $RES, ...) {...};
- pattern-inside: $APP.$METHOD(..., function $FUNC($REQ, $RES, ...) {...})
- pattern-either:
- pattern: $PAGE.goto(<... $REQ.$QUERY.$FOO ...>, ...)
- pattern: $PAGE.goto(<... $REQ.$BODY ...>, ...)
- pattern: $PAGE.setContent(<... $REQ.$QUERY.$FOO ...>, ...)
- pattern: $PAGE.setContent(<... $REQ.$BODY ...>, ...)
- pattern: $PAGE.evaluate(<... $REQ.$QUERY.$FOO ...>, ...)
- pattern: $PAGE.evaluate(<... $REQ.$BODY ...>, ...)
- pattern: $PAGE.evaluate($CODE,..., <... $REQ.$QUERY.$FOO ...>, ...)
- pattern: $PAGE.evaluate($CODE,..., <... $REQ.$BODY ...>, ...)
- pattern: $PAGE.evaluateHandle(<... $REQ.$QUERY.$FOO ...>, ...)
- pattern: $PAGE.evaluateHandle(<... $REQ.$BODY ...>, ...)
- pattern: $PAGE.evaluateHandle($CODE,..., <... $REQ.$QUERY.$FOO ...>, ...)
- pattern: $PAGE.evaluateHandle($CODE,..., <... $REQ.$BODY ...>, ...)
- pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$BODY ...>, ...)
- pattern: $PAGE.evaluateOnNewDocument(<... $REQ.$BODY.$FOO ...>, ...)
- pattern: $CONTEXT.addInitScript(<... $REQ.$BODY ...>,...)
- pattern: $CONTEXT.addInitScript(<... $REQ.$BODY.$FOO ...>,...)
- pattern: |
$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.goto(<... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.goto(<... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.setContent(<... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.setContent(<... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluate($CODE,..., <... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluate($CODE,..., <... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluate(<... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluate(<... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluateHandle(<... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluateHandle(<... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluateHandle($CODE,..., <... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluateHandle($CODE,..., <... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$QUERY.$FOO ...>;
...
$PAGE.evaluateOnNewDocument(<... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$BODY ...>;
...
$PAGE.evaluateOnNewDocument(<... $INPUT ...>,...);
- pattern: |
$INPUT = <... $REQ.$BODY ...>;
...
$CONTEXT.addInitScript($INPUT,...);
message: If unverified user data can reach the `puppeteer` methods it can result
in Server-Side Request Forgery vulnerabilities.
metadata:
owasp: A01:2017 - Injection
cwe: "CWE-918: Server-Side Request Forgery (SSRF)"
category: security
technology:
- node.js
- express
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
severity: ERROR
languages:
- javascript
Examples
ssrf_playwright.js
const { chromium } = require('playwright');
const express = require('express')
const app = express()
const port = 3000
app.post('/goto', async (req, res) => {
const browser = await chromium.launch();
const page = await browser.newPage();
let url = 'https://hardcoded.url.com'
// ruleid:playwright_ssrf
await page.goto(req.foo);
// ruleid:playwright_ssrf
const newUrl = req.foo.bar;
await page.goto(newUrl);
await page.screenshot({ path: 'example.png' });
await browser.close();
})
app.post('/setContent', async (req, res) => {
const browser = await chromium.launch();
const page = await browser.newPage();
// ruleid:playwright_ssrf
await page.setContent(req.foo['bar']);
await page.screenshot({ path: 'example.png' });
await browser.close();
})
app.post('/evaluate', async (req, res) => {
const browser = await chromium.launch();
const page = await browser.newPage();
// ruleid:playwright_ssrf
await page.evaluate(`fetch(${req.foo})`);
await page.screenshot({ path: 'example.png' });
await browser.close();
})
app.post('/evaluate', async (req, res) => {
const browser = await chromium.launch();
const page = await browser.newPage();
// ruleid:playwright_ssrf
await page.evaluate(x => fetch(x), req.foo.bar);
await page.screenshot({ path: 'example.png' });
await browser.close();
})
Short Link: https://sg.run/zv3P