Giter Site home page Giter Site logo

safe-marked's Introduction

safe-marked Actions Status: test

Convert Markdown to HTML using marked and DOMPurify.

Motivation

marked does not sanitized by default. Also, marked will remove sanitize option in the future.

We want to get safe and easy library that convert Markdown to HTML.

Features

  • Convert Markdown to HTML using marked
  • Safe by default
  • Type Safe by default
    • This library is written by TypeScript
  • Work on Browser and Node.js

Size

  package           size      minified  gzipped
  safe-marked       90.15 KB  39.36 KB  13.82 KB (browser bundle size)
  [email protected]      45.05 KB  23.87 KB  7.87 KB
  [email protected]  45.21 KB  15.3 KB   5.99 KB
  
  # Other Markdown library  
  [email protected]  325.52 KB  92.69 KB  32.77 KB
  [email protected]     157.28 KB  71.06 KB  23.55 KB

Install

Install with npm:

npm install safe-marked

Usage

import { createMarkdown } from "safe-marked";
const markdown = createMarkdown();
const html = markdown(`# Header

This is [CommonMark](https://commonmark.org/) text.
`);
console.log(html); 
/* <h1 id="header">Header</h1>
   <p>This is <a href="https://commonmark.org/">CommonMark</a> text.</p>
*/

The output is sanitized by default.

import { createMarkdown } from "safe-marked";
const markdown = createMarkdown();
const html = markdown(`<script>alert(1)</script>
<iframe src="https://example.com"></iframe>

This is [XSS](javascript:alert(1))`);
// sanitized by default
assert.strictEqual(html, `

<p>This is <a>XSS</a></p>
`);

Options

You can pass options for these library.

  • marked: See marked's options
    • onInit(marked: Marked): unknown: You can use onInit to customize marked instance.
    • It is useful to add a plugin to marked.
  • dompurify: See DOMPurify's options

An example for options:

import { createMarkdown } from "safe-marked";
import { gfmHeadingId } from "marked-gfm-heading-id";
const markdown = createMarkdown({
    marked: {
        // Add plugin to marked
        onInit(marked) {
            // add plugin
            marked.use(gfmHeadingId());
        },
        // same options for https://marked.js.org/#/USING_ADVANCED.md
        gfm: false
    },
    // same options for https://github.com/cure53/DOMPurify
    dompurify: {
        ADD_TAGS: ["iframe"]
    }
});
const html = markdown(`# Header

<iframe src="https://example.com"></iframe>
This is [CommonMark](https://commonmark.org/) text.
`);
assert.strictEqual(html, `<h1>Header</h1>
<iframe src="https://example.com"></iframe>
This is [CommonMark](https://commonmark.org/) text.
`);

FAQ

Does safe-marked always include jsdom?

No. safe-marked has two type of entry point.

  • Node.js
  • Browser

Browser entrypoint does not includes jsdom. (just use marked + dompurify)

Browser demo: https://stackblitz.com/edit/js-pquqgx?file=index.js,package.json

Changelog

See Releases page.

Running tests

Install devDependencies and Run npm test:

npm test

Contributing

Pull requests and stars are always welcome.

For bugs and feature requests, please create an issue.

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :D

License

MIT © azu

safe-marked's People

Contributors

azu avatar renovate-bot avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

doc22940

safe-marked's Issues

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Repository problems

These problems occurred while renovating this repository. View logs.

  • WARN: Using npm packages for Renovate presets is now deprecated. Please migrate to repository-based presets instead.

Pending Status Checks

These updates await pending status checks. To force their creation now, click the checkbox below.

  • chore(deps): update dependency @types/node to ^20.12.4
  • fix(deps): update dependency dompurify to ^3.1.0

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/test.yml
  • actions/checkout v4@3df4ab11eba7bda6032a0b82a6bb43b11571feac
  • actions/setup-node v4
npm
package.json
  • dompurify ^3.0.11
  • jsdom ^24.0.0
  • marked ^12.0.1
  • @types/dompurify ^3.0.5
  • @types/jsdom ^21.1.6
  • @types/mocha ^10.0.6
  • @types/node ^20.12.3
  • lint-staged ^15.2.2
  • marked-gfm-heading-id ^3.1.3
  • marked-mangle ^1.1.7
  • mocha ^10.4.0
  • tsconfig-to-dual-package ^1.2.0
  • tsimp ^2.0.11
  • yarn 1.22.22

  • Check this box to trigger a request for Renovate to run again on this repository

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

Automatically include jsdom?

Hi @azu
I was intrigued by your comment here:
markedjs/marked#1519 (comment)

@UziTech Yes, I know.

I've tried to use [email protected] and DOMPurify, but this combination has a bit complex context.
Because, DOMPurify does not work on Node.js without jsdom.

  • marked is universal/isomophic library

  • DOMPurify is not universal/isomophic library

    • It require jsdom for Node.js

The browser enviroment does not need jsdom, but Node.js env does need jsdom.
It require a bit complex code.

if(THIS_ENV_IS_NODE){
  return marked + dompurify + jsdom
} else{
  return marked + dompurify
}

So, I've created a wrapper library for optimizing Browser and Node.js.

safe-marked is a wrapper library of marked, DOMPurify, and jsdom.
Also, safe-marked define 'browser' field in package.json for optimizing browser bundle.
The browser entry point does not include jsdom.

This wrapper aim to reduce pacakge size for browser.

  package           size      minified  gzipped
  safe-marked       90.15 KB  39.36 KB  13.82 KB (browser bundle size)
  [email protected]      45.05 KB  23.87 KB  7.87 KB
  [email protected]  45.21 KB  15.3 KB   5.99 KB
  
  # Other Markdown library  
  [email protected]  325.52 KB  92.69 KB  32.77 KB
  [email protected]     157.28 KB  71.06 KB  23.55 KB

Conclusion

The documentation just say following

Marked does not sanitize the output HTML. Please use a sanitize library, like DOMPurify (recommended), sanitize-html or insane on the output HTML! 🚨

Afte using marked + DOMPurify, I feed that it is hard to use marked safety.
I think that we need to improve documentation about the usage of sanitizing.
Or just come back to support sanitize option...

However, The documentation is not fundamental solution.

Thanks.

📝 Note: The size of recommentation libraries :

sanitize-html is too large. insane looks like that is not maintained and have some problem.
So, I've selected DOMPurify. DOMPurify is maintained by security company.

  package               size      minified   gzipped
  [email protected]      45.21 KB  15.3 KB    5.99 KB
  [email protected]  1.02 MB   210.06 KB  64.81 KB
  [email protected]          18.61 KB  4.64 KB    1.9 KB

Also, I love package size of marked ❤️

However, does safe-marked include JSDom by default? If I don't use SSR in an SPA of mine, I might not need JSDom.

Do you have plans to publish current master? (現行のmasterはpublishされますか?)

Hello @azu

I tried to use MarkedOptions.walkTokens, but v4.0.0's deps are referenced older version.

I see current master's deps are already updated. Do you have plans to publish current one?


marked.js 1.1.0で追加されたwalkTokensオプションを使用しようとしたところ、現在publishされているバージョンでは、dependenciesのバージョンが古く、使用できませんでした。

現行のmasterを見たところ、すでに更新済みのようです。このmasterのpublish予定はありますでしょうか?

Move to marked extension

marked@5 deprecated some options.

safe-marked approach is a wrapper of marked.
However, marked limit the this approach.
In the future, safe-marked user can not extends marked.

It is possible to continue using the WRAPPER approach, but it will be dirty code.
// ugly approach
import { createMarkdown } from "safe-marked";
const markdown = createMarkdown({
  marked: (marked) => {
    // extends marked
    marked.use(someExtension);
    return {
      // options
    }
  }
});
const html = markdown(`# Header

This is [CommonMark](https://commonmark.org/) text.
`);
console.log(html); 

So, We need to move this sanitizer function to marked extension like markedSanitizer

e.g.

import { marked } from "marked";
import { markedSanitizer } from "marked-sanitizer";
marked.use(markedSanitizer());

As a result, we will deprecate safe-marked.

TODO

  • create? or find? sanitizer extension for marked
  • deprecated safe-marked and recommened to use the extension
    • As possible, provide migration tool

If you have any opinions, please feel free to write to us.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.