Created
July 21, 2023 08:50
-
-
Save SuperOleg39/54474af9f9b22b34439b2abb41c74975 to your computer and use it in GitHub Desktop.
Old version of safe-strings
This file contains hidden or 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
| /** | |
| * High performance encoding of the specified characters in the string | |
| * | |
| * source https://github.com/preactjs/preact-render-to-string/blob/60075a5a7389d638d535c85f3706739e9ba932bc/src/util.js | |
| * perf https://esbench.com/bench/5f88af6cb4632100a7dcd414 | |
| */ | |
| export function encode(str: string, entities: RegExp, encodeMap: Record<number, string>) { | |
| // Skip all work for strings with no entities needing encoding: | |
| if (str.length === 0 || entities.test(str) === false) { | |
| return str; | |
| } | |
| let last = 0; | |
| let i = 0; | |
| let out = ''; | |
| let ch = ''; | |
| // Seek forward in str until the next entity char: | |
| for (; i < str.length; i++) { | |
| const charCode = str.charCodeAt(i); | |
| if (charCode in encodeMap) { | |
| ch = encodeMap[charCode]; | |
| } else { | |
| continue; | |
| } | |
| // Append skipped/buffered characters and the encoded entity: | |
| if (i !== last) { | |
| out += str.slice(last, i); | |
| } | |
| out += ch; | |
| // Start the next seek/buffer after the entity's offset: | |
| last = i + 1; | |
| } | |
| if (i !== last) { | |
| out += str.slice(last, i); | |
| } | |
| return out; | |
| } |
This file contains hidden or 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
| import { encode } from './encode'; | |
| const ENTITIES = /[&<>"']/; | |
| // references: | |
| // - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-for-html-contexts | |
| // - https://github.com/preactjs/preact-render-to-string/blob/master/src/util.js#L6 | |
| // - https://github.com/OWASP/owasp-java-encoder/blob/main/core/src/main/java/org/owasp/encoder/HTMLEncoder.java#L53 | |
| const ENCODE_MAP = { | |
| 38: '&', // & | |
| 60: '<', // < | |
| 62: '>', // > | |
| 34: '"', // " | |
| 39: ''', // ' | |
| }; | |
| /** | |
| * Encode possible XSS in string for insertion into HTML | |
| */ | |
| export function encodeForHTMLContext(str = ''): string { | |
| return encode(str, ENTITIES, ENCODE_MAP); | |
| } |
This file contains hidden or 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
| import { encode } from './encode'; | |
| const ENTITIES = /[<\u2028\u2029]/; | |
| // references: | |
| // - https://github.com/yahoo/serialize-javascript/blob/main/index.js#L25 | |
| // - https://github.com/sveltejs/kit/blob/master/packages/kit/src/runtime/server/page/serialize_data.js#L22 | |
| // - https://github.com/vercel/next.js/blob/canary/packages/next/src/server/htmlescape.ts#L4 | |
| // - https://github.com/OWASP/owasp-java-encoder/blob/main/core/src/main/java/org/owasp/encoder/JavaScriptEncoder.java#L128 | |
| const ENCODE_MAP = { | |
| 60: '\\u003C', // < | |
| 8232: '\\u2028', // line separator | |
| 8233: '\\u2029', // paragraph separator | |
| }; | |
| /** | |
| * Encode possible XSS and breaking code symbols in string for insertion into script tag | |
| */ | |
| export function encodeForJSContext(str = ''): string { | |
| return encode(str, ENTITIES, ENCODE_MAP); | |
| } |
This file contains hidden or 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
| import { encodeForJSContext } from './encodeForJSContext'; | |
| /** | |
| * Stringify object and encode possible XSS and breaking code symbols for insertion result into script tag | |
| */ | |
| export const safeStringify = (json: Record<string, any>): string => { | |
| return encodeForJSContext(JSON.stringify(json)); | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment