mirror of
https://github.com/yusufipk/OpenFrame.git
synced 2026-09-11 17:46:06 +00:00
fix(subtitles): escape a rejected cue tag instead of deleting it
Deleting a tag whole is what lets a filter like this be reassembled around: strip the `<b>` out of `<scr<b>ipt>` and the two halves close up into a tag nobody wrote. The leftovers are escaped one character at a time instead, which also covers `-->` in cue text without a second multi-character replacement. Both are what CodeQL flagged on the branch, js/incomplete-multi-character-sanitization and js/bad-tag-filter. Neither was reachable as an injection, because the file is served as text/vtt and a cue is parsed by the WebVTT cue-text parser rather than as HTML, but a sanitiser that cannot be reassembled around is the cheaper thing to own.
This commit is contained in:
@@ -144,6 +144,16 @@ describe('parseSubtitleCues', () => {
|
||||
expect(cues[0].text).toBe('<i>tilt</i>alert(1)');
|
||||
});
|
||||
|
||||
it('escapes the leftovers of a rejected tag so it cannot be reassembled', () => {
|
||||
// Deleting `<b>` out of the middle would close the two halves into a `<script>` that
|
||||
// was never written. Escaping what is left over is what stops that.
|
||||
const cues = parseSubtitleCues(
|
||||
['00:00:01,000 --> 00:00:02,000', '<scr<b>ipt>alert(1)', ''].join('\n')
|
||||
);
|
||||
expect(cues[0].text).toBe('<scr<b>ipt>alert(1)');
|
||||
expect(cues[0].text).not.toContain('<script');
|
||||
});
|
||||
|
||||
it('neutralises an arrow in cue text so the file cannot be re-split', () => {
|
||||
const cues = parseSubtitleCues(['00:00:01,000 --> 00:00:02,000', 'a --> b', ''].join('\n'));
|
||||
expect(cues[0].text).toBe('a --> b');
|
||||
|
||||
Reference in New Issue
Block a user