Skip to main content

Check for malicious files

Check your cloud app for malicious files using File Scan

The code samples below were created using the Pangea sample apps.

If you are interested joining in, make sure to dive into the Pangea sample apps on GitHub. To do so, click on your preferred supported language and navigate to File Scan for further exploration.

Create a token

Expand for details

Create a token so that you can access the File Scan endpoints:

  1. Go to the Pangea Console and click File Scan in the left-hand navigation menu. The File Scan Overview page will appear.
  2. On the File Scan Overview page, you'll see a notification asking you to set a service token. Click Create new token toward the bottom right side of your screen.

Add a token

  1. You’ll be prompted to create a token. Enter a Token name and select an Expiration Date. You may also create a token for all Intel services, if you wish.

Create a token

  1. Once configured, the token is available in the Tokens section of the File Scan Overview page.

Location of tokens

Select your provider

Expand for details

Default providers can be selected in the Pangea Console . Setting a default provider in the Pangea Console means your API request calls will use this provider, unless another provider is specified as part of your API request.

To select a default provider for an API:

  1. Go to the Pangea Console .
  2. On the left-hand navigation menu, select File Scan.
  3. On the left-hand navigation menu, select Settings.
  4. On the right-hand side, select the default provider.

Set provider as default

Configure your app for communication with Pangea

For your app to communicate with the Pangea service, you will need to know the token and domain from the File Scan Configuration Details. The examples in this documentation use the PANGEA_DOMAIN and PANGEA_FILE_SCAN_TOKEN environment variables for this purpose.

The token and domain Configuration Details are created when you enable File Scan and can be found in the Overview section under File Scan.

Required environment variables

Set environment variables

Set the PANGEA_DOMAIN and PANGEA_FILE_SCAN_TOKEN environment variables containing the token and domain information so that copied and pasted documentation examples will work for you.

In the examples below, replace "yourServiceDomain" with domain and "yourAccessToken" with token from your Configuration Details.

export PANGEA_DOMAIN="yourServiceDomain"
export PANGEA_FILE_SCAN_TOKEN="yourAccessToken"
curl -sSLX POST 'https://file-scan.'"$PANGEA_DOMAIN"'/v1/scan' \
-H 'Authorization: Bearer '"$PANGEA_FILE_SCAN_TOKEN" \
-H 'Content-Type: multipart/form-data' \
-F 'request={"provider":"crowdstrike"};type=application/json' \
-F 'upload=@path-to-my-file.ext;type=application/octet-stream'

The File Scan API is generally asynchronous. A successful call will normally return an HTTP 202 status code and response that includes a request_id. When CrowdStrike is the provider, the File Scan API can return an HTTP 200 status code when the verdict is determined by a reputation lookup.

In the example below, the returned request_id is prq_j4xxpqqtbfmpgbydefct7xglytxe5xie:

{
"request_id": "prq_j4xxpqqtbfmpgbydefct7xglytxe5xie",
"request_time": "2023-09-21T03:13:07.995895Z",
"response_time": "2023-09-21T03:13:09.224183Z",
"status": "Accepted",
"summary": "Your request is in progress. Please check(GET https://file-scan.aws.pangea.cloud/request/prq_j4xxpqqtbfmpgbydefct7xglytxe5xie) for status of the request later.",
"result": {
"ttl_mins": 7200,
"retry_counter": 0,
"location": "https://file-scan.aws.pangea.cloud/request/prq_j4xxpqqtbfmpgbydefct7xglytxe5xie"
}
}

To fetch the final response, you must poll using a GET request with the request_id from the File Scan API call above until you get an HTTP 200 status code.

For example:

curl -sSLX GET 'https://file-scan..'"$PANGEA_DOMAIN"'/request/prq_j4xxpqqtbfmpgbydefct7xglytxe5xie' \
-H 'Authorization: Bearer '"$PANGEA_FILE_SCAN_TOKEN" \
-H 'Content-Type: application/json'

An example final response would be:

{
"request_id": "prq_j4xxpqqtbfmpgbydefct7xglytxe5xie",
"request_time": "2023-09-21T03:13:07.995895Z",
"response_time": "2023-09-21T03:13:57.435935Z",
"status": "Success",
"summary": "File was scanned",
"result": {
"data": {
"category": [
"win/malicious_confidence_100"
],
"score": 100,
"verdict": "malicious"
},
"raw_data": {
"reputation": {},
"scan": {
"ArchiveInfo": {
"clean_files": 0,
"dirty_files": 0,
"errors": 0,
"files_scanned": 0,
"potentially_unwanted_files": 0
},
"confidence": "high",
"detection_name": "win/malicious_confidence_100",
"prediction": "malicious"
}
}
}
}

Synchronous requests to File Scan

POST/v1/file-scan
"""
Synchronous requests to File Scan
https://github.com/pangeacyber/pangea-python/tree/main/examples/file_scan
"""

import os

import pangea.exceptions as pe
from pangea.config import PangeaConfig
from pangea.services import FileScan

token = os.getenv("PANGEA_FILE_SCAN_TOKEN")
domain = os.getenv("PANGEA_DOMAIN")
# For synchronous operation, it's required to enable queue_retry_enable to true and establish an appropriate timeout.
# If the timeout is set too low, the service won't complete and will still result in an AcceptedRequestException.
config = PangeaConfig(domain=domain, queued_retry_enabled=True, poll_result_timeout=120)
detect = FileScan(token, config=config)

FILEPATH = "./testdata/testfile.pdf"


def main():
    print("Checking file...")

    try:
        with open(FILEPATH, "rb") as f:
            response = detect.file_scan(file=f, verbose=True, provider="crowdstrike")
            print(f"Response: {response.result}")
    except pe.PangeaAPIException as e:
        print(f"Request Error: {e.response.summary}")
        for err in e.errors:
            print(f"\t{err.detail} \n")


if __name__ == "__main__":
    main()

Asynchronous requests to File Scan

POST/v1/file-scan
"""
Asynchronous requests to File Scan
https://github.com/pangeacyber/pangea-python/tree/main/examples/file_scan
"""

import os
import time

import pangea.exceptions as pe
from pangea.config import PangeaConfig
from pangea.services import FileScan

token = os.getenv("PANGEA_FILE_SCAN_TOKEN")
domain = os.getenv("PANGEA_DOMAIN")

# To function asynchronously, it's necessary to configure queue_retry_enable as False.
# Upon using the .scan() function, if the server responds with a 202 status, it will immediately lead to an AcceptedRequestException.
config = PangeaConfig(domain=domain, queued_retry_enabled=False)
detect = FileScan(token, config=config)

FILEPATH = "./testdata/testfile.pdf"


def main():
    print("Checking file...")
    exception = None
    try:
        with open(FILEPATH, "rb") as f:
            response = detect.file_scan(file=f, verbose=True, provider="crowdstrike")
    except pe.AcceptedRequestException as e:
        # Save exception value to request result later
        exception = e
        print("This is a excepted exception")
        print(f"Request Error: {e.response.summary}")
        for err in e.errors:
            print(f"\t{err.detail} \n")
    except pe.PangeaAPIException as e:
        print("This is a unexcepted exception")
        print(f"Request Error: {e.response.summary}")
        for err in e.errors:
            print(f"\t{err.detail} \n")
        return

    print("We are going to sleep some time before we poll result...")
    # wait some time to get result ready and poll it
    time.sleep(20)

    try:
        # poll result, hopefully this should be ready
        response = detect.poll_result(exception)
        print("Got result successfully...")
        print(f"Response: {response.result}")
    except pe.PangeaAPIException as e:
        print(f"Request Error: {e.response.summary}")
        for err in e.errors:
            print(f"\t{err.detail} \n")


if __name__ == "__main__":
    main()

File Scan API sends a response

After your app submits a file to the File Scan service, you will receive the JSON response below.

note

If you get a 202 from /v1/scan endpoint then you must poll /requests/<request id> until you get a non-202 response to get the actual result.

In this instance:

  • The verdict returned as malicious
  • Additional raw_data (from the provider specified in the API request) was returned because the raw parameter was set to true
Sample File Scan raw results
{
"result": {
"data": {
"category": ["Text.Format.EICAR"],
"score": 100,
"verdict": "malicious"
},
"parameters": {
"verbose": true,
"raw": true,
"provider": "reversinglabs"
},
"raw_data": {
"info": {
"statistics": {
"file_stats": [
{
"type": "Text",
"subtype": "None",
"count": 1,
"identifications": [
{
"count": 1,
"name": "EICAR:Generic"
}
]
}
]
},
"file": {
"file_type": "Text",
"file_subtype": "None",
"size": 69,
"entropy": 4.910999957023231,
"hashes": [
{
"name": "md5",
"value": "69630e4574ec6798239b091cda43dca0"
},
{
"name": "rha0",
"value": "cf8bd9dfddff007f75adf4c2be48005cea317c62"
},
{
"name": "sha1",
"value": "cf8bd9dfddff007f75adf4c2be48005cea317c62"
},
{
"name": "sha256",
"value": "131f95c51cc819465fa1797f6ccacf9d494aaaff46fa3eac73ae63ffbdfd8267"
}
]
},
"identification": {
"success": true,
"name": "EICAR",
"version": "Generic",
"author": "ReversingLabs"
}
},
"classification": {
"propagated": false,
"classification": 3,
"factor": 5,
"result": "Text.Format.EICAR",
"scan_results": [
{
"ignored": false,
"type": "internal",
"classification": 3,
"factor": 5,
"name": "TitaniumCore Format",
"version": "4.1.0.0",
"result": "Text.Format.EICAR",
"rca_factor": 10
},
{
"ignored": false,
"type": "av",
"classification": 3,
"factor": 1,
"name": "Antivirus (based on the RCA Classify)",
"version": "2.82",
"result": "DOS.Malware.EICAR",
"rca_factor": 6,
"properties": [
{
"name": "scannerCount",
"value": "26"
},
{
"name": "scannerMatch",
"value": "26"
},
{
"name": "vendorCount",
"value": "18"
},
{
"name": "vendorMatch",
"value": "18"
},
{
"name": "firstSeen",
"value": "2011-06-18T08:21:00"
},
{
"name": "lastSeen",
"value": "2023-03-29T20:45:24"
}
]
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "ahnlab",
"result": "[VIRUS] Virus/EICAR_Test_File",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "ffri",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "avast",
"result": "EICAR Test-NOT virus!!!",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "bitdefender",
"result": "EICAR-Test-File (not a virus)",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "carbonblack",
"result": "virus",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "clamav",
"result": "Eicar-Signature",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "crowdstrike",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "crowdstrike_online",
"result": "malware.confidence_100",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "endgame",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "mcafee_beta",
"result": "EICAR test file",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "fireeye_online",
"result": "EICAR-Test-File",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "fortinet",
"result": "EICAR_TEST_FILE",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "gdata",
"result": "EICAR-Test-File (not a virus)",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "ikarus",
"result": "EICAR-Test-File",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "k7computing",
"result": "EICAR_Test_File",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "malwarebytes",
"result": "EICAR-AV-Test",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "mcafee",
"result": "EICAR test file",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "sentinelone_online",
"result": "DFI - Malicious COM",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "microsoft",
"result": "Virus:DOS/EICAR_Test_File",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "mcafee_online",
"result": "EICAR test file",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "microsoft_online",
"result": "Virus:DOS/EICAR_Test_File",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "panda",
"result": "EICAR-AV-TEST-FILE",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "panda_online",
"result": "EICAR-AV-TEST-FILE",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "quickheal",
"result": "EICAR.TestFile",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "rising",
"result": "EICAR-Test-File",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "rising_online",
"result": "EICAR-Test-File",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "antivir",
"result": "detected",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "sonicwall",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "sophos_susi",
"result": "EICAR-AV-Test",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "symantec",
"result": "EICAR Test String",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "symantec_beta",
"result": "EICAR Test String",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "symantec_online",
"result": "EICAR Test String",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "trendmicro",
"result": "Eicar_test_file",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "trendmicro_consumer",
"result": "Eicar_test_file",
"rca_factor": 0
},
{
"ignored": false,
"type": "av",
"classification": 0,
"factor": 0,
"name": "vba32",
"result": "EICAR-Test-File",
"rca_factor": 0
}
],
"rca_factor": 10
},
"story": [
{
"caption": "Description",
"content": "This file (SHA1: cf8bd9dfddff007f75adf4c2be48005cea317c62) is a text file. It was identified as a generic EICAR. There are no extracted files."
},
{
"caption": "Classification",
"content": "The file was classified as malicious, with the name Text.Format.EICAR, using TitaniumCore file format validation. One other scanner confirms the classification."
}
]
}
},
"request_id": "prq_x6fdiizbon6j3bsdvnpmwxsz2aan7fqd",
"request_time": "2022-09-21T17:24:33.105Z",
"response_time": "2022-09-21T17:24:34.007Z",
"status": "success"
}

Understand and review the results

The API response sent by File Scan includes various fields and values; however, the ones listed below give you the most information about the disposition of a file scan. To learn about more response fields, visit the File Scan API Reference.

verdict

The verdict normalized categorization as interpreted by the data returned by the third-party provider. There are four possible verdicts:

  • Benign - Confirmed as non-malicious

  • Suspicious - Associated with actions that are malicious

  • Malicious - Confirmed as malicious

  • Unknown - No data

score

The normalized score as interpreted by the data returned by the third party provider. Scores are associated with the verdict values listed above:

  • 0 = Benign

  • 1 - 99 = Suspicious

  • 100 = Malicious

  • -1 = Unknown

summary

A summary of the various categories associated with a file, which help illustrate why a file received a particular verdict.

category

Indicates the category of file associated with the file (e.g. Adware, Malware). This field may return more than one category and may, at times, not be populated.

raw_data

Raw data returned by the provider you specified in the API request. You can investigate the raw data if its meaningful to your use case or if you want to supply it to your users. You must set the raw parameter to true to receive this data.

Explore file options

You decide how to respond and/or communicate with your users based on the File Scan verdict. Here are some suggestions:

  • If the file is malicious, delete it and display a message to the user.
  • If a file is non-malicious, allow it and save it.

Was this article helpful?

Contact us