Rapsssito / react-native-tcp-socket

React Native TCP socket API for Android, iOS & macOS with SSL/TLS support.
MIT License
303 stars 81 forks source link

Nmap port scan crashes the entire app on iOS 16 #173

Closed Kyu closed 1 year ago

Kyu commented 1 year ago

Description

Running a nmap port scan crashes the entire app, for some reason

Steps to reproduce

Steps to reproduce the behavior:

  1. Use the code below.
  2. Run the command nmap -p 5555 IP_HERE
    Also: Using the flags -sA, -sS give no problem, but -sT does, which I believe might be the default
  3. App crashes, with no output

Code:

This is how my server is defined

const options = {
    port: 5555,
    host: '0.0.0.0',
};

let senderSocket: TcpSocket.Socket;

const server = TcpSocket.createServer(function(socket) {
    socket.on('data', (data) => {
        console.log('data'); // Does not fire on nmap
        socket.write('Echo server ' + data);
    });

    socket.on('error', (error) => {
        console.log('An error occurred with client socket ', error);
    });

    socket.on('close', (error) => {
        console.log('Closed connection with ', socket.address(), ` error = ${error}`);
    });

    senderSocket = socket;

}).listen(options, () => {
    console.log(server.address())
});

server.on('error', (error) => {
    console.log('An error occurred with the server', error);
});

server.on('close', () => {
    console.log('Server closed connection');
});

App logs:

Logs for your project will appear below. Press Ctrl+C to exit.
iOS Bundling complete 874ms
 LOG  {"address": "0.0.0.0", "family": "IPv4", "port": 5555}

Nmap logs:

Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-23 00:31 CDT
Nmap scan report for 172.27.194.86
Host is up (0.026s latency).

PORT     STATE SERVICE
5555/tcp open  freeciv

Nmap done: 1 IP address (1 host up) scanned in 0.07 seconds

Current behavior

Crashes on nmap.

Expected behavior

No crash occurs

Screenshots May add video later

Relevant information

Dependencies (I am using expo if that matters):

  "dependencies": {
    "expo": "~48.0.11",
    "expo-network": "~5.2.1",
    "expo-sensors": "~12.1.1",
    "expo-splash-screen": "~0.18.1",
    "expo-status-bar": "~1.4.2",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-native": "0.71.6",
    "react-native-tcp-socket": "^6.0.6"
  },
  "devDependencies": {
    "@babel/core": "^7.20.2",
    "@types/react": "~18.0.24",
    "@types/react-native": "~0.70.6",
    "expo-dev-client": "~2.2.1",
    "metro-hermes-compiler": "^0.76.0",
    "typescript": "^4.8.4"
  },

OS:

OS: macOS 13.3.1 22E261 arm64
Host: MacBookAir10,1
Kernel: 22.4.0
Uptime: 2 days, 6 hours, 29 mins
Packages: 75 (brew)
Shell: zsh 5.9
Resolution: 1440x900
DE: Aqua
WM: Quartz Compositor
WM Theme: Blue (Dark)
Terminal: iTerm2
Terminal Font: Monaco 12
CPU: Apple M1
GPU: Apple M1
Memory: 1546MiB / 8192MiB

Phone:

iPhone 14 Pro
iOS 16.4.1

~(Will test on android later)~
Edit: Does not crash on Android (Galaxy A14 5G, Android 13). But gives useful error. Will investigate

Kyu commented 1 year ago

Further information: First of all, ios crash report

Second of all, the error defined by Android 13 was a "socket is closed" error. The error has no type/class, just Error.

Third, the iOS crash video, and the Android crash video.

Fourth, the offending line was in a function I didn't include. This function is called every ~200ms so that was a big oversight by me.

function writeToSocket(msg: string) {
    if (! senderSocket) {
        return;
    }
    senderSocket.write(`${msg}\n`);
}

A quick 'fix' for Android involves simply adding a try/catch like so, but has no effect on iOS:

function writeToSocket(msg: string) {
    if (! senderSocket) {
        return;
    }
    try {
        senderSocket.write(`${msg}\n`);
    } catch (e) {
        // @ts-ignore
        console.log(e.constructor.name)
    }
}

However, this results in console spam similar to to that in the Android video, e.g

500 above ...
 LOG  Error
 LOG  Error
 LOG  Error
500 below ...

So that suggests that it's attempting to write to the long closed socket forever. Any ideas on how to fix that? I can add a initial handshake message in my client, but i'd rather fix this issue on the server.

Related: #127 Slightly related: #167, #165, #54

github-actions[bot] commented 1 year ago

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community attention? This issue may be closed if no further activity occurs.