# Unable to detect nghttp2, brotli, and sqlite components in a container image SBOM

**URL:** <https://anchorecommunity.discourse.group/t/unable-to-detect-nghttp2-brotli-and-sqlite-components-in-a-container-image-sbom/304>\
**Category:** Syft\
**Created:** [January 11, 2025, 11:43am UTC](https://anchorecommunity.discourse.group/t/unable-to-detect-nghttp2-brotli-and-sqlite-components-in-a-container-image-sbom/304 "2025-01-11T11:43:24Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![vijayan](https://yyz2.discourse-cdn.com/free1/user_avatar/anchorecommunity.discourse.group/vijayan/32/226_2.png) [@vijayan](https://anchorecommunity.discourse.group/u/vijayan)\
**Post date:** [January 11, 2025, 11:43am UTC](https://anchorecommunity.discourse.group/t/unable-to-detect-nghttp2-brotli-and-sqlite-components-in-a-container-image-sbom/304/1 "2025-01-11T11:43:24Z")

</div>

**Summary:**  
Syft does not detect certain components (`nghttp2`, `brotli`, and `sqlite`) in a container image created with an Ubuntu base. The components are expected to appear in the SBOM but are missing.

### Steps to Reproduce:

1. Create a container image using the following setup:

- Base image: Ubuntu.
- Custom application libraries (`nghttp2`, `brotli`, `sqlite`) added.

1. Use Syft to generate the SBOM for the container image:

```auto
syft <container-image>

```

1. Check the generated SBOM for the presence of `nghttp2`, `brotli`, and `sqlite`.

### Expected Behavior:

Syft should detect and list the `nghttp2`, `brotli`, and `sqlite` components in the generated SBOM.

### Observed Behavior:

The SBOM does not include `nghttp2`, `brotli`, and `sqlite`, even though these libraries are present in the container image.

---

<div class="post-metadata">

**Author:** ![willmurphy](https://yyz2.discourse-cdn.com/free1/user_avatar/anchorecommunity.discourse.group/willmurphy/32/12_2.png) [@willmurphy](https://anchorecommunity.discourse.group/u/willmurphy)\
**Post date:** [January 13, 2025, 2:01pm UTC](https://anchorecommunity.discourse.group/t/unable-to-detect-nghttp2-brotli-and-sqlite-components-in-a-container-image-sbom/304/2 "2025-01-13T14:01:51Z")

</div>

Hi @vijayan,

Can you share a Dockerfile/Containerfile as part of your steps to reproduce? “Custom application libraries” doesn’t tell me about what exactly was installed or how. Did you use `apt`? `snap`? `curl`?

It will be much easier for us to investigate if you could share a specific Dockerfile.

Thanks!

---

<div class="post-metadata">

**Author:** ![vijayan](https://yyz2.discourse-cdn.com/free1/user_avatar/anchorecommunity.discourse.group/vijayan/32/226_2.png) [@vijayan](https://anchorecommunity.discourse.group/u/vijayan)\
**Post date:** [January 13, 2025, 3:38pm UTC](https://anchorecommunity.discourse.group/t/unable-to-detect-nghttp2-brotli-and-sqlite-components-in-a-container-image-sbom/304/3 "2025-01-13T15:38:20Z")

</div>

Hello @willmurphy ,

Yes please find the contents of the Dockerfile and all the application related libraries(like `libsqlite3.so.0, libsqlite3.so.0.8.6, libnghttp2.so.14, libbrotlicommon.so.1, libbrotlidec.so.1, libbrotlienc.so.1`) are present locally which are later copied through the Dockerfile.

> From ubuntu:18.04  
> RUN apt-get update  
> RUN mkdir newtest  
> COPY _._ ./newtest

Thanks,  
Vijayan

---

<div class="post-metadata">

**Author:** ![willmurphy](https://yyz2.discourse-cdn.com/free1/user_avatar/anchorecommunity.discourse.group/willmurphy/32/12_2.png) [@willmurphy](https://anchorecommunity.discourse.group/u/willmurphy)\
**Post date:** [January 14, 2025, 2:32pm UTC](https://anchorecommunity.discourse.group/t/unable-to-detect-nghttp2-brotli-and-sqlite-components-in-a-container-image-sbom/304/4 "2025-01-14T14:32:28Z")

</div>

> [@vijayan](#):
>
> and all the application related libraries(like `libsqlite3.so.0, libsqlite3.so.0.8.6, libnghttp2.so.14, libbrotlicommon.so.1, libbrotlidec.so.1, libbrotlienc.so.1`) are present locally which are later copied through the Dockerfile.

Copying binaries directly into the image means that no package manager has knowledge of those binaries. For example, if you did an `apt install libsqlite` or whatever the package is called, then `apt` would have an entry in its state that was evidence of that installation, and Syft would find that.

For binaries that are just copied into the file system and not managed by any package manager, Syft has two strategies for categorizing them: binary classifiers and ELF metadata.

### Binary classifier cataloger

The binary classifier cataloger attempts to identify binary files by inspecting their contents (sort of a slightly-more-sophisticated `strings my-binary | grep` approach). For many common binaries, Syft has regular expressions designed to match these binaries and their versions:

You can see these classifiers here: [syft/syft/pkg/cataloger/binary/classifiers.go at b4e7b64d5ce04b6636b46ffe4b900936a51a4ddd · anchore/syft · GitHub](https://github.com/anchore/syft/blob/b4e7b64d5ce04b6636b46ffe4b900936a51a4ddd/syft/pkg/cataloger/binary/classifiers.go#L8)

Each of those objects is essentially a file glob and a regex that attempts to identify files matching that glob as particular versions of a particular binary.

### ELF metadata cataloger

This cataloger, defined at [syft/syft/pkg/cataloger/binary/elf\_package\_cataloger.go at main · anchore/syft · GitHub](https://github.com/anchore/syft/blob/main/syft/pkg/cataloger/binary/elf_package_cataloger.go#L57), asks Syft for all files with certain mime types, (including `application/x-sharedlib`, which is how an ELF .so file should be classified), and uses a process analogous to `readelf` to get the `notes` section out of the ELF, to see whether someone has added notes identifying the ELF file.

### Why your packages aren’t detected

If Syft has an ELF file that has no notes identifying it and doesn’t regex match to some well-known binary, and it wasn’t installed by any package manager, then Syft isn’t able to make a package, because it doesn’t have a way to determine the version, and the minimal information we report in a package is name and version.

### What Syft still finds

Although Syft isn’t able to find a package version in this setup, it _is_ able to find a file. If you invoke syft like this: `SYFT_FILE_METADATA_SELECTION=all syft -o json my-image`, then Syft will put a files section in the SBOM with information like mode, digest, and mimetype for every file in the image. Then you could independently note the digests of the .so files you’re mounting into the image and keep track that way. (Note that this can also take a while and make a really large SBOM.)

### Options

These are some things you could do to make it so Syft finds your .so files:

1. Get the `.so` files by installing it in your Dockerfile, e.g. `RUN apt-get install -y libsqlite3-0`
2. If you are building these shared libraries, consider adding notes to the ELF metadata that identify the packages
3. If these packages are from well-known, official distributions (e.g. you’re downloading libsqlite from an official release page or something) consider adding a binary classifier to Syft that will match these.
4. Use the `files` section of the SBOM instead of the `artifacts` section for these packages, as described above.

I hope this has answered your question. Let me know if you’d like more information about one of these options.
