-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5325774
commit 3b2543e
Showing
7 changed files
with
791 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
const t = require("tap"); | ||
const { spawn } = require("child_process"); | ||
const { resolve } = require("path"); | ||
const timeout = require("../timeout"); | ||
|
||
const pathToApp = resolve( | ||
__dirname, | ||
"../../sample-apps/fastify-clickhouse", | ||
"app.js" | ||
); | ||
|
||
t.test("it blocks in blocking mode", (t) => { | ||
const server = spawn(`node`, [pathToApp, "4000"], { | ||
env: { ...process.env, AIKIDO_DEBUG: "true", AIKIDO_BLOCKING: "true" }, | ||
}); | ||
|
||
server.on("close", () => { | ||
t.end(); | ||
}); | ||
|
||
server.on("error", (err) => { | ||
t.fail(err.message); | ||
}); | ||
|
||
let stdout = ""; | ||
server.stdout.on("data", (data) => { | ||
stdout += data.toString(); | ||
}); | ||
|
||
let stderr = ""; | ||
server.stderr.on("data", (data) => { | ||
stderr += data.toString(); | ||
}); | ||
|
||
// Wait for the server to start | ||
timeout(4000) | ||
.then(() => { | ||
return Promise.all([ | ||
fetch( | ||
`http://127.0.0.1:4000/?petname=${encodeURIComponent("Njuska'), (null, 'Kitty")}`, | ||
{ | ||
signal: AbortSignal.timeout(5000), | ||
} | ||
), | ||
fetch("http://127.0.0.1:4000/?petname=Njuska", { | ||
signal: AbortSignal.timeout(5000), | ||
}), | ||
fetch("http://127.0.0.1:4000/context", { | ||
signal: AbortSignal.timeout(5000), | ||
}), | ||
]); | ||
}) | ||
.then(([sqlInjection, normalSearch]) => { | ||
t.equal(sqlInjection.status, 500); | ||
t.equal(normalSearch.status, 200); | ||
t.match(stdout, /Starting agent/); | ||
t.match(stdout, /Zen has blocked an SQL injection/); | ||
}) | ||
.catch((error) => { | ||
t.fail(error.message); | ||
}) | ||
.finally(() => { | ||
server.kill(); | ||
}); | ||
}); | ||
|
||
t.test("it does not block in dry mode", (t) => { | ||
const server = spawn(`node`, [pathToApp, "4001"], { | ||
env: { ...process.env, AIKIDO_DEBUG: "true" }, | ||
}); | ||
|
||
server.on("close", () => { | ||
t.end(); | ||
}); | ||
|
||
let stdout = ""; | ||
server.stdout.on("data", (data) => { | ||
stdout += data.toString(); | ||
}); | ||
|
||
let stderr = ""; | ||
server.stderr.on("data", (data) => { | ||
stderr += data.toString(); | ||
}); | ||
|
||
// Wait for the server to start | ||
timeout(4000) | ||
.then(() => | ||
Promise.all([ | ||
fetch( | ||
`http://127.0.0.1:4001/?petname=${encodeURIComponent("Njuska'), (null, 'Kitty")}`, | ||
{ | ||
signal: AbortSignal.timeout(5000), | ||
} | ||
), | ||
fetch("http://127.0.0.1:4001/?petname=Njuska", { | ||
signal: AbortSignal.timeout(5000), | ||
}), | ||
]) | ||
) | ||
.then(([sqlInjection, normalSearch]) => { | ||
t.equal(sqlInjection.status, 200); | ||
t.equal(normalSearch.status, 200); | ||
t.match(stdout, /Starting agent/); | ||
t.notMatch(stdout, /Zen has blocked an SQL injection/); | ||
}) | ||
.catch((error) => { | ||
t.fail(error.message); | ||
}) | ||
.finally(() => { | ||
server.kill(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# fastify-clickhouse | ||
|
||
WARNING: This application contains security issues and should not be used in production (or taken as an example of how to write secure code). | ||
|
||
In the root directory run `make fastify-clickhouse` to start the server. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Import Aikido Firewall | ||
const Zen = require("@aikidosec/firewall"); | ||
const db = require("./db"); | ||
|
||
const fastify = require("fastify"); | ||
|
||
// Prevent Prototype Pollution | ||
require("@aikidosec/firewall/nopp"); | ||
|
||
/** | ||
* Get the HTML body of the root page | ||
*/ | ||
function getHTMLBody(cats) { | ||
return ` | ||
<html lang="en"> | ||
<bod> | ||
<p>All cats : ${cats.map((cat) => cat.petname).join(", ")}</p> | ||
<form action="/" method="GET"> | ||
<label for="search">Add a new cat</label> | ||
<input type="text" name="petname"> | ||
<input type="submit" value="Add" /> | ||
</form> | ||
<a href="http://localhost:4000/?petname=Kitty'); DELETE FROM cats;-- H">Test injection</a> / <a href="http://localhost:4000/clear">Clear table</a> | ||
</body> | ||
</html>`; | ||
} | ||
|
||
// Async main function that starts the Fastify server | ||
(async () => { | ||
await db.createConnection(); | ||
|
||
const app = fastify({ | ||
logger: true, | ||
}); | ||
|
||
Zen.addFastifyHook(app); | ||
|
||
// Handle GET requests to the root URL | ||
app.get("/", async (request, reply) => { | ||
if (request.query["petname"]) { | ||
await db.addCat(request.query["petname"]); | ||
} | ||
const html = getHTMLBody(await db.getAllCats()); | ||
reply.header("Content-Type", "text/html").send(html); | ||
}); | ||
|
||
app.route({ | ||
method: "GET", | ||
url: "/cats", | ||
handler: async (request, reply) => { | ||
reply.send(await db.getAllCats()); | ||
}, | ||
}); | ||
|
||
// Handle GET requests to /clear | ||
app.get("/clear", async (request, reply) => { | ||
await db.clearCats(); | ||
reply.redirect("/"); | ||
}); | ||
|
||
// Start the server | ||
try { | ||
await app.listen({ port: getPort() }); | ||
} catch (err) { | ||
app.log.error(err); | ||
process.exit(1); | ||
} | ||
})(); | ||
|
||
function getPort() { | ||
const port = parseInt(process.argv[2], 10) || 4000; | ||
|
||
if (isNaN(port)) { | ||
console.error("Invalid port"); | ||
process.exit(1); | ||
} | ||
|
||
return port; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
const { createClient } = require("@clickhouse/client"); | ||
|
||
let client; | ||
|
||
async function createConnection() { | ||
client = createClient({ | ||
url: "http://localhost:27019", | ||
username: "clickhouse", | ||
password: "clickhouse", | ||
database: "main_db", | ||
}); | ||
|
||
await client.exec({ | ||
query: `CREATE TABLE IF NOT EXISTS cats_table ( | ||
id UUID DEFAULT generateUUIDv4() PRIMARY KEY, | ||
petname String | ||
); | ||
`, | ||
}); | ||
|
||
return client; | ||
} | ||
|
||
async function getAllCats() { | ||
const resultSet = await client.query({ | ||
query: `SELECT * FROM cats_table;`, | ||
format: "JSONEachRow", | ||
}); | ||
return resultSet.json(); | ||
} | ||
|
||
function addCat(name) { | ||
console.log(`INSERT INTO cats_table (id, petname) VALUES (null, '${name}');`); | ||
return client.exec({ | ||
query: `INSERT INTO cats_table (id, petname) VALUES (null, '${name}');`, | ||
}); | ||
} | ||
|
||
function clearCats() { | ||
return client.exec({ | ||
query: `DELETE FROM cats_table WHERE 1;`, | ||
}); | ||
} | ||
|
||
module.exports = { | ||
createConnection, | ||
getAllCats, | ||
addCat, | ||
clearCats, | ||
}; |
Oops, something went wrong.