Should the backspace character be escaped?

Over at MarkupSafe, there’s an open ticket about escaping the invisible ASCII backspace and delete characters in addition to the normal HTML syntax characters.

The reasoning is that these characters render as invisible in HTML, but when copied into a terminal, they actually affect the input and can change the meaning of a command. It’s not XSS, but it feels like it’s in the same space. import y\bose\bm\bi\bt\be\b renders as import yosemite in HTML but executes import os in the Python console.

I’m undecided on whether to implement this. On the one hand, it is an issue, and the escape function seems like the best place to address it. Introducing a separate function or a flag to control it seems ineffective, as users would need to know to use it, and most don’t even know they’re using MarkupSafe to begin with.

On the other hand, this introduces a non-reversible behavior to escape. Right now, it’s true that unescape(escape(value)) == value. But if backspace is escaped to \\b, there’s no way for unescape to know whether that’s due to escaping or if it was already escaped in the original and shouldn’t change. And it’s not clear that you’d even want to unescape those characters, as there doesn’t seem like an obvious legitimate use for them in this context.

Also, some browsers and terminals are getting smart and warning about these characters on copy and paste, no changes required.

I figured the Django devs might have some interesting input on this discussion, since Django also provides escaping and might want to implement this if we do.

Hi @davidism

Welcome to the forum!

I think this is outside the scope of escape/MarkupSafe since, as you say, it’s not XSS or HTML related. If the character were something else that could lead to injection in yet another context, say a weird character in YAML, there’d be no question that it it’s outside the scope. I think the same applies here.

I think it’s more up to browsers, operating systems, and terminals to handle displaying, copying, and pasting backspace/delete characters better.

Thanks,

Adam

Hm, this is a tricky one. I honestly can’t see any reason for backspaces or escape characters to be in HTML text at all, so in that sense, I would say escaping them might be very reasonable. That said, losing the reversibility could be problematic, and there’s some backwards-compatibility considerations. Not quite as sure as Adam is on this.

I read up more on code copy paste attacks, and backspace isn’t nearly the only issue. Newlines can cause multi-line commands to execute, control characters like ^C might still get interpreted, Vim might see the tab or escape sequence and do something, etc. And of course there’s plenty of other ways to craft seemingly innocuous commands that do something unintended.

For now, I’m going to close the issue. Markupsafe is concerned with the immediate issue of executing JavaScript in the browser. Terminals and terminal programs are in a better position to mitigate copy paste issues.

Yes - I would argue a terminal program should probably not be accepting pasted backspace characters or similar. That said, it’s likely worth at least spreading knowledge of this kind of attack around so people are aware of the possibility, even if we can’t reasonably address it in the frameworks/templates.

Good idea. We have a page in the Flask docs about various security issues: https://flask.palletsprojects.com/en/1.1.x/security/. I opened a ticket to add a new section about copying and pasting to terminals: https://github.com/pallets/flask/issues/3612.

@davidism do you have your sources at hand on copy-paste attacks?

Django could maybe do with a documentation section too.

I’m also guessing from the variety of attacks you described, you don’t believe a general template filter is possible.