unidoc / unipdf

Golang PDF library for creating and processing PDF files (pure go)
https://unidoc.io
Other
2.46k stars 250 forks source link

[BUG] Writing to buffer with nonroot user #532

Closed ricardogama closed 8 months ago

ricardogama commented 9 months ago

Description

We run our applications on Kubernetes, with images built in Docker.

For compliance and security reasons, the user on the Dockerfile must not have root permissions, and the Kubernetes needs to run on a read only filesystem.

When using the library to write the PDF content to a buffer, an error occurs where there seems to be an attempt to write to disc, or more specifically a mkdir operation:

panic: mkdir /home/nonroot: permission denied

goroutine 1 [running]:
main.main()
    /src/main.go:36 +0x228

Expected Behavior

Seems strange that the creator.Write(io.Writer) function requires a filesystem operation, since that seems to be a detail of the io.Writer interface implementation, which in this case is bytes.Buffer and there's no filesystem operation required.

Actual Behavior

Steps to reproduce the behavior:

  1. Replace ENV UNIDOC_KEY foobar with a valid license on the Dockerfile
  2. Build the Docker image : docker build -t uni .
  3. Run the Docker image: docker run uni
  4. See error displayed above

Attachments

Dockerfile

FROM golang:1.21.1 AS builder

WORKDIR /src

ADD . /src

RUN go build main.go

FROM ubuntu:jammy AS base

RUN apt update \
    && apt install -y --no-install-recommends \
    ca-certificates openssl

RUN groupadd -r nonroot && useradd -r -g nonroot nonroot

USER nonroot

COPY --from=builder \
    /src/main /app/

ENV UNIDOC_KEY foobar

CMD ["/app/main"]

main.go


package main

import (
    "bytes"
    "fmt"
    "os"

    "github.com/unidoc/unipdf/v3/common/license"
    "github.com/unidoc/unipdf/v3/creator"
    "github.com/unidoc/unipdf/v3/model"
)

var (
    regularFont *model.PdfFont
)

func main() {
    if err := license.SetMeteredKey(os.Getenv("UNIDOC_KEY")); err != nil {
        panic(err)
    }

    var err error
    regularFont, err = model.NewStandard14Font("Helvetica")
    if err != nil {
        panic(err)
    }

    c := creator.New()
    c.SetPageMargins(30, 30, 30, 30)

    p := newParagraph(c, regularFont, creator.ColorBlack, "test")
    c.Draw(p)

    var content bytes.Buffer
    if err := c.Write(&content); err != nil {
        panic(err)
    }

    fmt.Println("ok")
}

func newParagraph(c *creator.Creator, font *model.PdfFont, color creator.Color, text string) *creator.StyledParagraph {
    p := c.NewStyledParagraph()
    p.SetMargins(2, 2, 5, 5)
    chunk := p.Append(text)
    chunk.Style.Font = font
    chunk.Style.Color = color
    return p
}
sampila commented 9 months ago

Hi @ricardogama,

Yes, the API Key license requires to wrote a file that contains the usages of the API Key, the full information regarding that available here https://help.unidoc.io/article/141-metered-license-api-key

We do offer the offline licenses that can works on closed and private environment.

ricardogama commented 9 months ago

Thanks @sampila, this will be an issue since we do run our images with a read only security context.

Where can I find more information about offline licenses? Or is this something that needs to be enabled on your side, let's say with the sales or customer success team?

sampila commented 9 months ago

The information regarding our licenses can be seen here https://unidoc.io/pricing.

ricardogama commented 9 months ago

@sampila Which one of these features contains offline licenses?

Screenshot 2023-10-02 at 3 56 06 PM
sampila commented 9 months ago

@sampila Which one of these features contains offline licenses?

Screenshot 2023-10-02 at 3 56 06 PM

Yes, that's one of our offline licenses, the API Key license is belong to our Pay-As-You-Go product, except that, it is offline licenses.

sampila commented 8 months ago

Hi @ricardogama,

We released new version of UniPDF https://github.com/unidoc/unipdf/releases/tag/v3.51.0, which is now support the env variable for "UNIDOC_LICENSE_DIR" to set the path location of metered API Key license states.

Hope this can solve your issue.

Closing this issue for now, you can re-open this issue if you are still facing this issue.

Best regards, Alip