npm install body-fingerprint
const express = require("express");
const app = express();
const { bodyFingerprint, jsonFingerprint } = require("body-fingerprint");
app.use(bodyFingerprint);
app.use(jsonFingerprint);
app.get("/", (_, res) =>
res.send(`
<script>
body = new FormData();
body.set('a', 'b');
body.set('c', 'd');
body.set('e', new File([], ''))
fetch('/', {
method: 'post',
body})
.then((res) => res.text())
.then((res) => document.body.insertAdjacentHTML(
'beforebegin',
'<span style="white-space: pre-line">' + res + '</span>'
));
fetch('/', {
method: 'post',
headers: {'content-type': 'application/json'},
body: JSON.stringify({
a: 'b',
c: 'd',
e: {
f: 'g'
}
})
})
.then((res) => res.text())
.then((res) => document.body.insertAdjacentHTML(
'beforebegin',
'<span style="white-space: pre-line">' + res + '</span>'
))
</script>
`)
);
app.post("/", (req, res) => {
res.send([req.multipart.fingerprint, req.json.fingerprint]);
});
app.listen(3000);
Request:
POST /multipart HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary1234567890123456
------WebKitFormBoundary1234567890123456
Content-Disposition: form-data; name="a"
b
------WebKitFormBoundary1234567890123456
Content-Disposition: form-data; name="c"
d
------WebKitFormBoundary1234567890123456
Content-Disposition: form-data; name="e"; filename=""
Content-Type: application/octet-stream
------WebKitFormBoundary1234567890123456--
Generated req.multipart
object:
{
"parts": [
{
"attributes": {
"order": ["name"]
},
"headers": {
"order": ["Content-Disposition"]
}
},
{
"attributes": {
"order": ["name"]
},
"headers": {
"order": ["Content-Disposition"]
}
},
{
"attributes": {
"order": ["name", "filename"]
},
"headers": {
"order": ["Content-Disposition", "Content-Type"]
}
}
]
}
Request:
POST /json HTTP/1.1
Host: example.com
Content-Type: application/json
{
a: 1,
b: {
c: 2,
d: 3,
}
}
Generated req.json
object:
{
"fingerprint": "a,b,c,d",
"order": ["a", "b", "c", "d"],
"spaces": [" ", "\r", " \r", ... "\r"] // spaces fingerprint of json structure
}
depthFirstOrder
- traverses keys using depth-first search
{
a: 1,
b: {
c: 2,
d: 3,
}
}
produces a,c,d,b
if depthFirstOrder
is true
. false
by default
A property value representing Shannon entropy. null
by default
-
For multipart access through
req.multipart.entropy
-
For JSON access through
req.json.entropy
npm test