New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-37640: Fix telnetlib crash in Python3 while receiving un-printable characters from server #22814
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution! Referring to the original pull request, you may need to write new tests to ensure the error doesn't happen again (probably test against an integer value not found in the utf-8/utf-16 range that would cause the old code to error but not the new one). To find out how to run/write the tests, you can check out https://devguide.python.org/runtests/. I'm guessing the tests should go into Lib/test/test_telnetlib.py.
Edit: I also have one worry - dumping the bytes to the terminal seems like it might have security problems, you might need to convert it to a string representation first.
Misc/NEWS.d/next/Library/2020-10-20-13-31-32.bpo-37640.JfvXk-.rst
Outdated
Show resolved
Hide resolved
Thank you for this first review!
Can you tell me more about this security problems? (any documentation is also appreciated). Based on your comments, the available data are written to stdout as string by decoding these data as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, the new code doesn't seem to have that problem anymore, I was just worried that sys.stdout.buffer.write(text) # text is bytes object
would allow writing bytes directly to the terminal. A quick search leads to this useful post on why that isn't that great https://superuser.com/questions/1520750/can-binary-strings-in-a-terminal-do-anything-dangerous.
I think the current fixes might not fix the scenario give in the bug report. The tests also don't seem to be testing for that case too. The main issue lies with text.decode()
, rather than telnetlib
per se. From cursory searching, /dev/urandom
can produce bytes that either
- do not contain correct start bytes for unicode or
- are out of range for ascii
For example here's some code that also raises a similar UnicodeDecodeError
:
import struct
import ctypes
# create a 16 byte buffer
data = ctypes.create_string_buffer(16)
struct.pack_into(">l", data, 1, 0xFFFFFFF)
# will throw an error
bytes(data).decode('ascii')
# will throw an error
bytes(data).decode('utf-8')
# will probably throw an error too
bytes(data).decode(sys.stdout.encoding)
The problem is, I don't know what's the right way forward for this - technically writing the bytes directly to sys.stdout.buffer
would fix the problems. However, I don't know if the responsibility lies on Python to prevent the security issues mentioned above, or that it's on the user to be more cautious.
Edit: I think a triage member or core dev should be added to the issue's nosy list, however I have no clue who to ping since https://devguide.python.org/experts/ 's telnetlib
entry is empty.
Thanks for the link about binary strings in terminal.
I think it's up to the user to be careful or the designer of the terminals to add security. Terminal supports ANSI/VT escape sequences that's why it can lead to a security problem. Anyway, it is already possible from file: $ cat -v script.sh#!/bin/sh
echo "evil!"
exit 0
^[[2Aecho "Hello World!"
Then, let's print the content in python: with open('script.sh') as fd:
print(fd.read()) The result will be:
As it is a unicode issue, you could ping one of unicodedata expert. By the way, in binary mode and according to the RFC856, Section 5. Description:
With this naive fix, some characters are not interpreted. This is my draft test: @unittest.mock.patch('telnetlib.sys.stdin', new_callable=io.StringIO)
def test_interact_bin(self, stdin):
# [bpo-37640](https://bugs.python.org/issue37640)
encoding = 'utf-8'
want = [bytes(range(256))]
f = io.TextIOWrapper(io.BytesIO(), encoding)
telnet = test_telnet(want)
with contextlib.redirect_stdout(f):
telnet.interact()
diff = set(want[0]).difference(f.buffer.getvalue())
self.assertEqual(
f.buffer.getvalue(),
want[0],
msg=str(diff)
) These bytes are not supported:
We should implement the binary transmission at another time. |
I think you accidentally removed the |
…com/Sh3idan/cpython into bpo-37640-telnetlib-unpritable-char
Co-authored-by: kj <28750310+Fidget-Spinner@users.noreply.github.com>
I added the previous code without the
No worries ;) |
Misc/NEWS.d/next/Library/2020-10-20-13-31-32.bpo-37640.JfvXk-.rst
Outdated
Show resolved
Hide resolved
Co-authored-by: kj <28750310+Fidget-Spinner@users.noreply.github.com>
As the function is implemented differently depending on the OS, I have distinguished the tests for Windows and the others. On Windows, |
This PR is stale because it has been open for 30 days with no activity. Remove stale label or comment or this will be closed in 5 days |
Note the telnetlib module is deprecated in 3.11 and set for removal in 3.13. See PEP 594 – Removing dead batteries from the standard library and #91217. |
@Fidget-Spinner, given that this is already reviewed and approved and has no merge conflicts, would you like to merge this one? If not, it should perhaps be closed due to the deprecation. |
@AlexWaygood I approved this way back - before I was even a triager. Unfortunately, Alex and Hugo are right. Since |
Oh, I had no idea! I hope you don't mind the throwback 🙂
Agreed. I'm sorry that this was open for so long without being either merged or rejected, @Sh3idan. We appreciate the contribution — I hope that this does not dissuade you from contributing to CPython in the future 🙂 |
Hi,
This pull request is based on the bpo-37640, this closed pull request #14877 and the pseudocode of sys.displayhook.
This fix doesn't break the current telnetlib tests:
If you have any suggestions for adding tests, let me know.
As requested in #14877, I added an entry in Misc/NEWS.
This fix should be backported by creating a pull request for each version above or equal to 3.6. Are you agree?
https://bugs.python.org/issue37640