How to sanitize user input in Deno? - sanitize

I don't know much about security when it comes to Backend-JavaScript.
The only way I can imagine sanitizing the input is to use regex and replace all the unwanted characters, or split the whole string and filter/map the unwanted characters out, then join back together.
I'm also using the Oak module for Deno.

You can try out this https://deno.land/x/html_entities
According to lib documentation:
HTML validity and XSS attack prevention you can achieve from XmlEntities module.
import { XmlEntities } from "https://deno.land/x/html_entities#v1.0/mod.js";
XmlEntities.encode('<>"\'&©®'); // <>"&apos;&©®
XmlEntities.encodeNonUTF('<>"\'&©®'); // <>"&apos;&©®
XmlEntities.encodeNonASCII('<>"\'&©®'); // <>"\'&©®
XmlEntities.decode('<>"&apos;&©®∆'); // <>"'&©®∆

you can reuse the sanitize npm package:
npm i -g sanitize
And then you can use it like:
import { createRequire } from "https://deno.land/std/node/module.ts";
const require = createRequire(import.meta.url);
const sanitizer = require("sanitizer");
name = sanitizer.value(name, "string");
surname = sanitizer.value(surname, "string");
or you can replace this library with another sanitization library
and you run your deno script with: deno run --allow-read --unstable script.ts

Related

How to write an npm package that uses crypto in browser but falls back to node:crypto on server

I maintain a package called react-querybuilder that generates unique identifiers using crypto.getRandomValues().
When used in the browser, this is not a problem as crypto is available pretty much everywhere now. But react-querybuilder can be used on the server for query processing (including generating IDs) as well as server-side rendering, which means the crypto package must either be polyfilled with crypto-browserify or loaded manually (something like globalThis.crypto = require('node:crypto')).
Some build setups require the polyfill even if they don't do SSR, e.g. Create React App v5 since it uses Webpack v5 (which doesn't automatically include polyfills like v4 did). CRA v4 doesn't have the issue.
How can I write the package to use window.crypto when running in the browser, but load node:crypto and use that instead when running on the server? Ideally the setup would avoid requiring anything extra of the end user (polyfills, config, etc.).
This is the current implementation at time of writing (comments removed):
let cryptoModule = globalThis.crypto;
if (!cryptoModule && typeof require === "function") {
cryptoModule = require("crypto").webcrypto;
}
const template = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
const position19vals = ["8", "9", "a", "b"];
const re = /[xy]/g;
const container = new Uint32Array(32);
export const generateID = () => {
cryptoModule.getRandomValues(container);
let i = -1;
return template.replaceAll(re, (char) => {
i++;
return char === "y"
? position19vals[container[i] % 4]
: (container[i] % 16).toString(16);
});
};
FWIW, I'm not opposed to having separate builds for client and server if that makes it easier to implement (for me and the end user, but mostly the end user).

Best way to write markdown content in Node.js

I have to write some markdown text in my Node.js script which will be rendered on UI with respective formatting.
Here are the two options I have explored so far:
Option 1:
module.exports = {
status: "ENABLED"
remediation: "**Adding markdown remediation here** ",
}
Option 2:
const remediation = "## this is another way which seems a bit better"
module.exports = {
status: "ENABLED"
remediation,
}
The second option renders a bit better but I am still struggling with a few things like defining new lines, adding code body etc.
Wanted to check if there can be a better way to include markdown text in the script.
I would suggest that instead of creating your own wheels, please check markdown-it.
npm install markdown-it --save
// node.js, "classic" way:
var MarkdownIt = require('markdown-it'),
md = new MarkdownIt();
var result = md.render('# markdown-it rulezz!');
// node.js, the same, but with sugar:
var md = require('markdown-it')();
var result = md.render('# markdown-it rulezz!');
// browser without AMD, added to "window" on script load
// Note, there is no dash in "markdownit".
var md = window.markdownit();
var result = md.render('# markdown-it rulezz!');

How to console.log without a newline in Deno?

How do I print a new line to the terminal without a newline in Deno? In node.js I used to do:
process.stdout.write('hello, deno!')
Is this possible in Deno? Deno does not have the process module, and I could not find an equivalent option in https://doc.deno.land/builtin/stable.
I figured it out. Deno does not have node.js's process module but it has different functionality to replicate it. I was able to print to the terminal without a new line with:
const text = new TextEncoder().encode('Hello, deno!')
// asynchronously
await Deno.writeAll(Deno.stdout, text)
// or, sychronously
Deno.writeAllSync(Deno.stdout, text)
Documentation link: https://doc.deno.land/builtin/stable#Deno.writeAll
import { writeAllSync } from "https://deno.land/std/streams/conversion.ts";
const text = new TextEncoder().encode('Hello')
writeAllSync(Deno.stdout, text)
Deno.writeAllSync and Deno.writeAll are deprecated, it's recommended to use the package above instead.

Unable to use variables in fs functions when using brfs

I use browserify in order to be able to use require. To use fs functions with browserify i need to transform it with brfs but as far as I understood this results in only being able to input static strings as parameters inside my fs function. I want to be able to use variables for this.
I want to search for xml files in a specific directory and read them. Either by searching via text field or showing all of their data at once. In order to do this I need fs and browserify in order to require it.
const FS = require('fs')
function lookForRoom() {
let files = getFileNames()
findSearchedRoom(files)
}
function getFileNames() {
return FS.readdirSync('../data/')
}
function findSearchedRoom(files) {
const SEARCH_FIELD_ID = 'room'
let searchText = document.getElementById(SEARCH_FIELD_ID).value
files.forEach((file) => {
const SEARCHTEXT_FOUND = file.includes(searchText.toLowerCase())
if (SEARCHTEXT_FOUND) loadXML(file)
})
}
function loadXML(file) {
const XML2JS = require('xml2js')
let parser = new XML2JS.Parser()
let data = FS.readFile('../data/' + file)
console.dir(data);
}
module.exports = { lookForRoom: lookForRoom }
I want to be able to read contents out of a directory containing xml files.
Current status is that I can only do so when I provide a constant string to the fs function
The brfs README contains this gotcha:
Since brfs evaluates your source code statically, you can't use dynamic expressions that need to be evaluated at run time.
So, basically, you can't use brfs in the way you were hoping.
I want to be able to read contents out of a directory containing xml files
If by "a directory" you mean "any random directory, the name of which is determined by some form input", then that's not going to work. Browsers don't have direct access to directory contents, either locally or on a server.
You're not saying where that directory exists. If it's local (on the machine the browser is running on): I don't think there are standardized API's to do that, at all.
If it's on the server, then you need to implement an HTTP server that will accept a directory-/filename from some clientside code, and retrieve the file contents that way.

Using an emscripten compiled C library from node.js

After following instructions on the emscripten wiki I have managed to compile a small C library. This resulted in an a.out.js file.
I was assuming that to use functions from this library (within node.js) something like this would have worked:
var lib = require("./a.out.js");
lib.myFunction('test');
However this fails. Can anyone help or point me to some basic tutorial related to this?
Actually, all the functions are already exported. Generated JavaScript contains following lines:
var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
// …
if (ENVIRONMENT_IS_NODE) {
// …
module['exports'] = Module;
}
If you got a function called my_fun in your C code, then you'll have Module._my_fun defined.
There are some problems with this approach, though.
Optimizer may remove or rename some functions, so always specify them passing -s EXPORTED_FUNCTIONS="['_main','_fun_one','_fun_two']". Function signatures in C++ are bit mangled, so it's wise to extern "C" { … } the ones which you want to export.
Furthermore, such a direct approach requires JS to C type conversions. You may want to hide it by adding yet another API layer in file added attached with --pre-js option:
var Module = {
my_fun: function(some_arg) {
javascript to c conversion goes here;
Module._my_fun(converted_arg) // or with Module.ccall
}
}
Module object will be later enhanced by all the Emscripten-generated goodies, so don't worry that it's defined here, not modified.
Finally, you will surely want to consider Embind which is a mechanism for exposing nice JavaScript APIs provided by Emscripten. (Requires disabling newest fastcomp backend.)
The problem here is that your a.out.js file is going to look like this
function myFunction() {
...
}
Not like this
function myFunction() {
...
}
exports.myFunction = myFunction;
You need to write a build script that lists the tokens you want to publically export from each C program and appends exports.<token> = <token>;\n to the end of your file for each token.

Resources