Skip to content

Premature end of ClamAV socket stream behind telepresence proxy #101

@martijnvanderwoud

Description

@martijnvanderwoud

Hello and thanks for providing this library!

I have an issue that is NOT very problematic per se, but still it might be useful to report it, because maybe it could help uncover a subtle (timing?) issue with the ClamAV socket connection

When I use the scanStream method like this ...:

isInfected: async (contents: Buffer): Promise<void> => {
    let chunk: Buffer | null = contents
    const inputStream = new Readable()
    inputStream._read = () => {
        inputStream.push(chunk)
        chunk = null
    }

    const result = await clamscan.scanStream(inputStream)
    console.log(result)
}

... the scan fails with an empty response when I am behind a telepresence proxy:

node-clam: Provided stream is readable.
node-clam: Attempting to establish socket/TCP connection for "scanStream"
node-clam: using remote server: 10.96.253.36:3310
node-clam: Received final data from stream.
node-clam: The input stream has dried up.
node-clam: ClamAV is done scanning.
node-clam: Raw Response:   
node-clam: Error Response:  
node-clam: File may be INFECTED!
{
  isInfected: null,
  viruses: [],
  file: null,
  resultString: '',
  timeout: false
}
node-clam: Socket/Host connection closed.
node-clam: ClamAV socket has been closed! false

When running the samen within my minikube cluster, without the telepresence proxy, the scan works just fine:

node-clam: Provided stream is readable.
node-clam: Attempting to establish socket/TCP connection for "scanStream"
node-clam: using remote server: 10.96.253.36:3310
node-clam: Received final data from stream.
node-clam: The input stream has dried up.
node-clam: Received output from ClamAV Socket.
node-clam: ClamAV is done scanning.
node-clam: Raw Response:  stream: OK
node-clam: File is OK!
{
  isInfected: false,
  viruses: [],
  file: null,
  resultString: 'stream: OK\x00',
  timeout: false
}
node-clam: Socket/Host connection closed.
node-clam: ClamAV socket has been closed! false

What is also interesting is that the scan does complete successfully behind the telepresence proxy when I put a breakpoint on the chunk = null statement and let the debugger proceed step-by-step, which lets me think a timing issue might be the cause of a premature end of the ClamAV socket stream.

The behaviour is the same when I write the Buffer to a temporary file and then call the clamscan.isInfected method

I also tried using the passthrough method ...:

isInfected: (contents: Buffer) =>
    new Promise<boolean>((resolve, reject) => {
        let chunk: Buffer | null = contents
        const inputStream = new Readable()
        inputStream._read = () => {
            inputStream.push(chunk)
            chunk = null
        }
        const clamAVStream = clamscan.passthrough();
        inputStream.pipe(clamAVStream)
        clamAVStream
            .on("scan-complete", (result) => {
                const infected = result.isInfected;
                if (infected !== null) {
                    logger.debug(`Scan complete; contents infected: ${infected}`)
                    resolve(infected)
                }
            })
            .on('error', (error) => {
                reject(error)
            })
            .on('timeout', (error) => {
                const timeoutError = error || new Error("Scan timed out")
                reject(timeoutError)
            })
    })

... and found that it consistently succeeds, both behind the telepresence proxy, and running within minikube without the proxy:

node-clam: Attempting to establish socket/TCP connection for "passthrough"
node-clam: using remote server: 10.96.253.36:3310
node-clam: ClamAV Socket Initialized...
node-clam: Doing initial transform!
node-clam: Done with the full pipeline.
node-clam: Got result! stream: OK
node-clam: File is OK!
node-clam: Processed Result:  {
  isInfected: false,
  viruses: [],
  file: null,
  resultString: 'stream: OK\x00',
  timeout: false
} stream: OK
node-clam: ClamAV socket has received the last chunk!
node-clam: File is OK!
node-clam: Result of scan: {
  isInfected: false,
  viruses: [],
  file: null,
  resultString: 'stream: OK\x00',
  timeout: false
}
node-clam: It took 0 seconds to scan the file(s).
node-clam: Socket/Host connection closed.
node-clam: ClamAV socket has been closed! Because of Error: false

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugedge caseWhen there may be a bug but its in a rare or hard-to-replicate edge case.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions