
Strumento di analisi statica e dinamica che verifica i pacchetti open-source per attributi dannosi, vulnerabili e rischiosi, con installazione in sandbox per prevenire attacchi alla supply chain.
Packj (pronunciato "package") è uno strumento per aiutare a mitigare gli attacchi alla supply chain del software. Può rilevare pacchetti dannosi, vulnerabili, abbandonati, typo-squatting e altri pacchetti "rischiosi" dai registry di pacchetti open-source più popolari, come NPM, RubyGems e PyPI. Può essere facilmente personalizzato per ridurre al minimo il rumore. Packj è nato come progetto di ricerca di dottorato e attualmente è sviluppato nell'ambito di vari finanziamenti governativi.
Nota Il server web Packj self-hostato e diverse integrazioni arriveranno entro la fine di questo mese 👊 Seguite questo repository per rimanere aggiornati.

Supportiamo molteplici modelli di deployment:
Usa Packj per eseguire audit delle dipendenze nelle pull request.```yaml
Visualizza su GitHub [marketplace](https://github.com/marketplace/actions/packj-security-audit). Esempio di [esecuzione PR](https://github.com/ossillate-inc/packj-github-action-demo/pull/3#issuecomment-1274797138).
### 2. Immagine Docker (consigliata)
Il modo più rapido per provare/testare Packj è utilizzare Docker. Podman è anche supportato per esecuzioni containerizzate (isolate).```
docker run -v /tmp:/tmp/packj -it ossillate/packj:latest --help
Clona questo repository,``` git clone https://github.com/ossillate-inc/packj.git && cd packj
Installa le dipendenze```
bundle install && pip3 install -r requirements.txt
Inizia con aiuto:``` python3 main.py --help
# Ecosistemi supportati #
Packj può verificare i pacchetti pubblicati dai registri NPM, PyPI, Rust, PHP e Rubygems. Il supporto per Rust e PHP è WIP. Stiamo aggiungendo attivamente supporto per altri registri. Supporta anche la verifica di pacchetti NPM e PyPI locali (non pubblicati).
| Registro | Ecosistema | Supportato |
| --------- | ---------- | ------------------ |
| NPM | JavaScript | :white_check_mark: |
| PyPI | Python | :white_check_mark: |
| Cargo | Rust | :white_check_mark: |
| Rubygems | Ruby | :white_check_mark: |
| Packagist | PHP | :white_check_mark: |
| Docker | Docker | :x: |
| Nuget | .NET | :white_check_mark: |
| Maven | Java | :white_check_mark: |
| Cocoapods | Swift | :x: |
# Funzionalità #
Packj offre i seguenti strumenti:
* [Verifica](#auditing-a-package) - per verificare un pacchetto per attributi "rischiosi".
* [Sandbox](#sandboxed-package-installation) - per l'installazione sicura di un pacchetto.
## Verifica di un pacchetto ##
Packj verifica i pacchetti software open-source per attributi "rischiosi" che li rendono vulnerabili ad attacchi alla supply chain. Ad esempio, i pacchetti con domini email scaduti (mancanza di 2FA), grande intervallo di tempo tra le release, API sensibili o permessi di accesso, ecc. vengono segnalati come rischiosi.
La verifica supporta:
- più pacchetti: `python3 main.py audit -p pypi:requests rubygems:overcommit`
- file di dipendenze: `python3 main.py audit -f npm:package.json pypi:requirements.txt`
Per impostazione predefinita, `audit` esegue solo analisi statica del codice per rilevare codice rischioso. Puoi passare il flag `-t` o `--trace` per eseguire anche l'analisi dinamica, che installerà tutti i pacchetti richiesti sotto strace e monitorerà il comportamento durante l'installazione. Vedi l'esempio di output qui sotto.
<details>
<summary><h4>Mostra esempio di esecuzione/output</h4></summary>
$ docker run -v /tmp:/tmp/packj -it ossillate/packj:latest audit --trace -p npm:browserify
[+] Fetching 'browserify' from npm..........PASS [ver 17.0.0]
[+] Checking package description.........PASS [browser-side require() the node way]
[+] Checking release history.............PASS [484 version(s)]
[+] Checking version........................RISK [702 days old]
[+] Checking release time gap............PASS [68 days since last release]
[+] Checking author.........................PASS [[email protected]]
[+] Checking email/domain validity.......RISK [expired author email domain]
[+] Checking readme.........................PASS [26838 bytes]
[+] Checking homepage.......................PASS [https://github.com/browserify/browserify#readme]
[+] Checking downloads......................PASS [2M weekly]
[+] Checking repo URL.......................PASS [https://github.com/browserify/browserify]
[+] Checking repo data...................PASS [stars: 14189, forks: 1244]
[+] Checking if repo is a forked copy....PASS [original, not forked]
[+] Checking repo description............PASS [browser-side require() the node.js way]
[+] Checking repo activity...............PASS [commits: 2290, contributors: 207, tags: 413]
[+] Checking for CVEs.......................PASS [none found]
[+] Checking dependencies...................RISK [48 found]
[+] Downloading package from npm............PASS [163.83 KB]
[+] Analyzing code..........................RISK [needs 3 perm(s): decode,codegen,file]
[+] Checking files/funcs....................PASS [429 files (383 .js), 744 funcs, LoC: 9.7K]
[+] Installing package and tracing code.....PASS [found 5 process,1130 files,22 network syscalls]
=============================================
[+] 5 risk(s) found, package is undesirable!
=> Complete report: /tmp/packj_54rbjhgm/report_npm-browserify-17.0.0_hlr1rhcz.json
{
"undesirable": [
"old package: 702 days old",
"invalid or no author email: expired author email domain",
"generates new code at runtime",
"reads files and dirs",
"forks or exits OS processes",
]
}
</details>
> ATTENZIONE: poiché i pacchetti potrebbero eseguire codice malevolo durante l'installazione, si raccomanda di usare `-t` o `--trace` SOLO quando si esegue all'interno di un container Docker o una Macchina Virtuale.
L'audit può essere eseguito anche in container Docker/Podman. Trova dettagli sugli attributi rischiosi e su come usarlo in [Audit README](https://github.com/ossillate-inc/packj/blob/main/packj/audit/README.md).
## Installazione del pacchetto in sandbox ##
Packj offre un sandboxing leggero per l'`installazione sicura` di un pacchetto. In particolare, impedisce ai pacchetti malevoli di esfiltrare dati sensibili, accedere a file sensibili (es. chiavi SSH) e persistere malware.
Mette in sandbox gli script di installazione, inclusa qualsiasi compilazione nativa. Usa **strace** (cioè **NON** richiede VM/Container).
Trova dettagli sul meccanismo di sandboxing e su come usarlo in [Sandbox README](https://github.com/ossillate-inc/packj/blob/main/packj/sandbox/README.md).
<details>
<summary><h4>Mostra esempio di esecuzione/output</h4></summary>
$ python3 main.py sandbox gem install overcommit
Fetching: overcommit-0.59.1.gem (100%)
Install hooks by running `overcommit --install` in your Git repository
Successfully installed overcommit-0.59.1
Parsing documentation for overcommit-0.59.1
Installing ri documentation for overcommit-0.59.1
#############################
# Review summarized activity
#############################
[+] Network connections
[+] DNS (1 IPv4 addresses) at port 53 [rule: ALLOW]
[+] rubygems.org (4 IPv6 addresses) at port 443 [rule: IPv6 rules not supported]
[+] rubygems.org (4 IPv4 addresses) at port 443 [rule: ALLOW]
[+] Filesystem changes
/
└── home
└── ubuntu
└── .ruby
├── gems
│ ├── iniparse-1.5.0 [new: DIR, 15 files, 46.6K bytes]
│ ├── rexml-3.2.5 [new: DIR, 77 files, 455.6K bytes]
│ ├── overcommit-0.59.1 [new: DIR, 252 files, 432.7K bytes]
│ └── childprocess-4.1.0 [new: DIR, 57 files, 141.2K bytes]
├── cache
│ ├── iniparse-1.5.0.gem [new: FILE, 16.4K bytes]
│ ├── rexml-3.2.5.gem [new: FILE, 93.2K bytes]
│ ├── childprocess-4.1.0.gem [new: FILE, 34.3K bytes]
│ └── overcommit-0.59.1.gem [new: FILE, 84K bytes]
├── specifications
│ ├── rexml-3.2.5.gemspec [new: FILE, 2.7K bytes]
│ ├── overcommit-0.59.1.gemspec [new: FILE, 1.7K bytes]
│ ├── childprocess-4.1.0.gemspec [new: FILE, 1.8K bytes]
│ └── iniparse-1.5.0.gemspec [new: FILE, 1.3K bytes]
├── bin
│ └── overcommit [new: FILE, 622 bytes]
└── doc
├── iniparse-1.5.0
│ └── ri [new: DIR, 119 files, 131.7K bytes]
├── rexml-3.2.5
│ └── ri [new: DIR, 836 files, 841K bytes]
├── overcommit-0.59.1
│ └── ri [new: DIR, 1046 files, 1.5M bytes]
└── childprocess-4.1.0
└── ri [new: DIR, 272 files, 297.8K bytes]
[C]ommit all changes, [Q|q]uit & discard changes, [L|l]ist details:
</details>
# La nostra storia
**TL;DR** Packj è nato come progetto di ricerca di dottorato. È supportato da vari finanziamenti governativi.
<details>
<summary><h4>Mostra risposta lunga</h4></summary>
Packj è nato come progetto di ricerca accademico. Nello specifico, le tecniche di analisi statica del codice utilizzate da Packj si basano su ricerche all'avanguardia in Cybersecurity: il progetto [MalOSS](https://github.com/osssanitizer/maloss) del nostro [gruppo](http://cyfi.ece.gatech.edu) di ricerca al Georgia Tech.
<a href="https://arxiv.org/pdf/2002.01139v1.pdf" target="_blank">
<img src="https://assets.kitploit.com/production/public/readmes/5562/c4061028051de04a9aebaf4188c08fdd1bcdb47efa8a818e959d3b3fc7bc5dc7.png" width="300" alt="academic paper">
</a>
Packj è supportato da generosi finanziamenti da [NSF](https://www.sbir.gov/node/2083473), [GRA](https://gra.org/company/227/OSSPolice.html) e [ALInnovate](https://innovatealabama.org).
</details>
# Perché Packj
**TL;DR** Gli scanner di vulnerabilità allo stato dell'arte assumono che il codice open-source di terze parti sia BENIGNO. Pertanto, tutti questi strumenti affrontano SOLO le minacce derivanti da bug di programmazione accidentali nel codice benigno (cioè CVE come Log4J). NON proteggono dagli attacchi moderni alla supply chain software come quelli di Solarwinds, provenienti da codice deliberatamente malevolo (maligno) propagato da attori malintenzionati che sfruttano nuove vulnerabilità nel canale di fornitura, tra cui dependency confusion, typo-squatting, protestware (sabotaggio), account hijacking e social engineering. Un esempio recente (Dic'22) è il pacchetto PyTorch che è stato compromesso utilizzando una vulnerabilità di dependency confusion (nessun CVE assegnato).
Packj non solo verifica per CVE, ma esegue anche un'analisi approfondita statica+dinamica del codice e controlli sui metadati per rilevare comportamenti e attributi "rischiosi", come l'avvio di una shell, l'uso di chiavi SSH, la mancata corrispondenza tra il codice GitHub e il codice pacchettizzato (provenienza), la mancanza di 2FA e molti altri. Tali attributi insicuri non sono qualificabili come CVE, motivo per cui nessuno degli strumenti esistenti può segnalarli. Packj può segnalare dipendenze malevole, typo-squatting, abbandonate, vulnerabili e altre dipendenze insicure (anelli deboli) nella tua supply chain software.
<details>
<summary><h4>Mostra risposta lunga</h4></summary>
L'attuale modello di minaccia della supply chain software **presume** che il codice open-source di terze parti sia benigno, e pertanto le vulnerabilità di sicurezza sono tracciate solo per bug di programmazione accidentali (cioè CVE). Di conseguenza, tutti gli scanner di vulnerabilità open-source esistenti **riportano SOLO** CVE pubblicamente noti e affrontano minacce da bug accidentali in codice benigno.
Un tipico esempio di bug accidentale è la mancanza di controllo dei limiti sull'input utente, che rende il codice vulnerabile ad attacchi di buffer overflow. Esempi popolari reali includono Log4J e HeartBleed. Gli aggressori devono sviluppare un exploit per attivare i CVE (ad esempio, un pacchetto TCP/IP appositamente creato nel caso di HeartBleed o un input numericamente elevato per causare buffer overflow). I CVE possono essere risolti applicando patch o aggiornando a una versione più recente della libreria (ad esempio, una versione più recente di Log4J risolve il CVE).
Il panorama delle minacce moderne della supply chain software è **cambiato** dopo l'attacco Solarwinds. I malintenzionati hanno trovato nuove vulnerabilità, ma questa volta nel canale di fornitura, non nel codice. Queste nuove vulnerabilità come dependency confusion, typo-squatting, protestware (sabotaggio), account hijacking e social engineering vengono sfruttate per propagare malware. Migliaia di pacchetti NPM/PyPI/Ruby compromessi sono stati segnalati.
A differenza dei CVE, il malware è codice deliberatamente malevolo (maligno). Inoltre, il malware stesso è un exploit e non può essere corretto o risolto aggiornando a una versione più recente. Ad esempio, [l'attacco di dependency confusion](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610) era intenzionalmente malevolo; non sfruttava alcun bug accidentale nel codice. Allo stesso modo, un autore di un pacchetto popolare che sabota il proprio codice per [protestare](https://en.wikipedia.org/wiki/Peacenotwar) contro la guerra è molto intenzionale e non sfrutta alcun CVE. Il typo-squatting è un altro vettore di attacco utilizzato dai malintenzionati per propagare malware nei registri di pacchetti open-source popolari: sfrutta [errori di battitura e inesperienza degli sviluppatori](https://discuss.python.org/t/improving-risks-and-consequences-against-typosquatting-on-pypi/5090), non bug accidentali o CVE nel codice.
Gli scanner esistenti **FALLISCONO** nel rilevare questi attacchi moderni alla supply chain software simili a Solarwinds da codice deliberatamente vulnerabile (maligno). Questi strumenti si limitano a scansionare il codice sorgente per le dipendenze open-source, compilano un elenco di tutte le dipendenze utilizzate e cercano ogni <nome-dipendenza, versione-dipendenza> in un database (es. NVD) per segnalare le versioni dei pacchetti affette (es. versione vulnerabile di Log4J, versione di LibSSL affetta da HeartBleed).
Packj non solo verifica per CVE, ma esegue anche un'analisi approfondita statica+dinamica del codice e controlli sui metadati per rilevare comportamenti e attributi "rischiosi", come l'avvio di una shell, l'uso di chiavi SSH, la mancata corrispondenza tra il codice GitHub e il codice pacchettizzato (provenienza), la mancanza di 2FA e molti altri. Tali attributi insicuri non sono qualificabili come CVE, motivo per cui nessuno degli strumenti esistenti può segnalarli. Packj può segnalare dipendenze malevole, typo-squatting, abbandonate, vulnerabili e altre dipendenze insicure (anelli deboli) nella tua supply chain software. Per maggiori informazioni, leggi [Audit README](https://github.com/ossillate-inc/packj/blob/main/packj/audit/README.md#faq)
</details>
# Personalizzazione #
Packj può essere facilmente personalizzato (zero rumore) in base al tuo modello di minaccia. Basta aggiungere un file [.packj.yaml](https://github.com/ossillate-inc/packj/blob/main/.packj.yaml) nella directory principale del tuo repository/progetto e ridurre l'affaticamento delle notifiche commentando gli attributi indesiderati.
# Malware trovati #
Abbiamo trovato oltre 40 pacchetti malevoli su PyPI e oltre 20 su Rubygems utilizzando questo strumento. Molti sono stati rimossi. Consulta un esempio qui sotto:
<details>
<summary><h4>Mostra esempio di malware</h4></summary>
$ python3 main.py audit pypi:krisqian
[+] Fetching 'krisqian' from pypi...OK [ver 0.0.7]
[+] Checking version...OK [256 days old]
[+] Checking release history...OK [7 version(s)]
[+] Checking release time gap...OK [1 days since last release]
[+] Checking author...OK [[email protected]]
[+] Checking email/domain validity...OK [[email protected]]
[+] Checking readme...ALERT [no readme]
[+] Checking homepage...OK [https://www.bilibili.com/bangumi/media/md140632]
[+] Checking downloads...OK [13 weekly]
[+] Checking repo_url URL...OK [None]
[+] Checking for CVEs...OK [none found]
[+] Checking dependencies...OK [none found]
[+] Downloading package 'KrisQian' (ver 0.0.7) from pypi...OK [1.94 KB]
[+] Analyzing code...ALERT [needs 3 perms: process,network,file]
[+] Checking files/funcs...OK [9 files (2 .py), 6 funcs, LoC: 184]
=============================================
[+] 6 risk(s) found, package is undesirable!
{
"undesirable": [
"no readme",
"only 45 weekly downloads",
"no source repo found",
"generates new code at runtime",
"fetches data over the network: ['KrisQian-0.0.7/setup.py:40', 'KrisQian-0.0.7/setup.py:50']",
"reads files and dirs: ['KrisQian-0.0.7/setup.py:59', 'KrisQian-0.0.7/setup.py:70']"
]
}
=> Complete report: pypi-KrisQian-0.0.7.json
=> View pre-vetted package report at https://packj.dev/package/PyPi/KrisQian/0.0.7
</details>
Packj ha segnalato KrisQian (v0.0.7) come sospetto a causa dell'assenza di un repository sorgente e dell'uso di API sensibili (rete, generazione di codice) durante l'installazione (in setup.py). Abbiamo deciso di approfondire e abbiamo scoperto che il pacchetto era malevolo. Trova la nostra analisi dettagliata su [https://packj.dev/malware/krisqian](https://packj.dev/malware/krisqian).
Altri esempi di malware trovati sono elencati su [https://packj.dev/malware](https://packj.dev/malware). Contattaci a [[email protected]](mailto:[email protected]) per la lista completa.
# Risorse #
Per saperne di più sullo strumento Packj o sugli attacchi alla supply chain software open-source, consulta le nostre
[](https://www.youtube.com/watch?v=Rcuqn56uCDk)
[](https://www.youtube.com/watch?v=a7BfDGeW_jY)
- [Talk](https://www.youtube.com/watch?v=Rcuqn56uCDk) e [slide](https://speakerdeck.com/ashishbijlani/pyconus22-slides) di PyConUS'22.
- Presentazione al BlackHAT Asia'22 Arsenal [Mitigating Open-Source Software Supply Chain Attacks](https://www.blackhat.com/asia-22/arsenal/schedule/#mitigating-open-source-software-supply-chain-attacks-26241)
- [Talk](https://www.youtube.com/watch?v=PHfN-NrUCoo) e [slide](https://speakerdeck.com/ashishbijlani/mitigating-open-source-software-supply-chain-attacks) di PackagingCon'21
- Talk al BlackHat USA'22 Arsenal [Detecting typo-squatting, backdoored, abandoned, and other "risky" open-source packages using Packj](https://www.blackhat.com/us-22/arsenal/schedule/#detecting-typo-squatting-backdoored-abandoned-and-other-risky-open-source-packages-using-packj-28075)
- [Dissertazione](https://cyfi.ece.gatech.edu/publications/DUAN-DISSERTATION-2019.pdf) accademica sulla sicurezza del software open-source e il [paper](https://www.ndss-symposium.org/wp-content/uploads/ndss2021_1B-1_23055_paper.pdf) del nostro gruppo al Georgia Tech che ha avviato questa ricerca.
- Open Source Summit, Europe'22 talk [Scoring dependencies to detect “weak links” in your open-source software supply chain](https://osseu2022.sched.com/overview/type/SupplyChainSecurityCon) - video della presentazione su [YouTube](https://www.youtube.com/watch?v=a7BfDGeW_jY)
- [Video](https://www.youtube.com/watch?v=PgvlSjl-mrY) e [slide](https://drive.google.com/file/d/1qLXIXzsIhRlS0mo8nwWI9KmD12CImZY9/view?usp=sharing) della presentazione a NullCon'22 [Unearthing Malicious And Other “Risky” Open-Source Packages Using Packj](https://archive.nullcon.net/website/goa-2022/speakers/unearthing-malicious-and-other-risky-open-source-packages-using-packj.php)
# Roadmap delle funzionalità #
* Aggiunta analizzatore Rust. Rust è in fase di sviluppo [ETA: Feb '24].
* Aggiunta funzionalità per rilevare diversi (TODO) codici "rischiosi" e attributi dei metadati [ETA: Feb '24].
* Webserver Packj self-hosted e diverse integrazioni utili (es. Gitlab runner) [ETA: Apr'24].
Osserva :eyes: questo repo per rimanere aggiornato.
Hai una richiesta di funzionalità o supporto? Visita la nostra [pagina di discussione su GitHub](https://github.com/ossillate-inc/packj/discussions/) o unisciti alla nostra [community Discord](https://discord.gg/qFcqaV2wYa) per discussioni e richieste.
# Team e contributori #
Packj è stato sviluppato da ricercatori di Cybersecurity presso [Ossillate Inc.](https://packj.dev/team) e collaboratori esterni per aiutare gli sviluppatori a mitigare i rischi di attacchi alla supply chain quando utilizzano dipendenze software open-source di terze parti non fidate. Ringraziamo i nostri sviluppatori e collaboratori. Mostra il tuo apprezzamento dandoci una :star: se ti piace il nostro lavoro.
Membri fondatori:
* Ashish Bijlani
* Devdutt Patnaik
* Ajinkya Rajput
Accogliamo con entusiasmo i contributi di codice. Vedi le linee guida [CONTRIBUTING.md](https://github.com/ossillate-inc/packj/blob/main/CONTRIBUTING.md). Hai trovato un bug? Apri un issue. Fai riferimento alle nostre linee guida [SECURITY.md](https://github.com/ossillate-inc/packj/blob/main/SECURITY.md) per segnalare un problema di sicurezza.
# FAQ #
<details>
<summary><b>Quali gestori di pacchetti (registri) sono supportati?</b></summary>
Packj può attualmente verificare i pacchetti NPM, PyPI e RubyGems per attributi "rischiosi". Stiamo aggiungendo supporto per Rust.
</details>
<details>
<summary><b>Quali tecniche utilizza Packj per rilevare pacchetti rischiosi/maliziosi?</b></summary>
Packj utilizza analisi statica del codice, tracciamento dinamico e analisi dei metadati per un audit completo. L'analisi statica da sola non è sufficiente per segnalare malware sofisticati che possono nascondersi meglio usando l'offuscamento del codice. L'analisi dinamica viene eseguita installando il pacchetto sotto `strace` e monitorando il suo comportamento a runtime. Per maggiori informazioni, leggi [Audit README](https://github.com/ossillate-inc/packj/blob/main/packj/audit/README.md).
</details>
<details>
<summary><b>Funziona su chiamate offuscate? Ad esempio, una stringa crittografata in base64 che viene decifrata e poi passata a una shell?</b></summary>Questo è un comportamento malevolo molto comune. Packj rileva l'offuscamento del codice così come l'esecuzione di comandi shell (chiamata di sistema exec). Ad esempio, Packj può segnalare l'uso delle API `getattr()` e `eval()` in quanto indicano "generazione di codice a runtime"; uno sviluppatore può quindi approfondire. Vedi [main.py](https://github.com/ossillate-inc/packj/blob/main/packj/audit/main.py#L512) per i dettagli.
</details>