curl / Mailing Lists / curl-users / Single Mail
Buy commercial curl support from WolfSSL. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder himself.

Re: curl-users Digest, Vol 182, Issue 2

From: Timothe Litt <litt_at_acm.org>
Date: Sat, 3 Oct 2020 07:23:29 -0400

On 03-Oct-20 06:00, curl-users-request_at_cool.haxx.se wrote:
> Message: 3 Date: Fri, 2 Oct 2020 17:48:32 +0200 From: Emil Engler
> <emilenglercurl_at_firemail.cc> To: curl-users_at_cool.haxx.se Subject: Re:
> Securing curl with syscalls Message-ID:
> <6d7a9193-f723-421a-45a7-637c8c103894_at_firemail.cc> Content-Type:
> text/plain; charset=utf-8 Is your plan to make this a libcurl feature?
> Mine is not that's why I am posting it on curl-users =) Libraries
> should not use such syscalls because it could lead to many SIGKILLS if
> users put it into their application. But maybe I am also understanding
> you wrong, please correct me then. Cheers, Emil On 10/2/20 5:33 PM,
> Daniel Stenberg via curl-users wrote:
>> On Fri, 2 Oct 2020, Emil Engler via curl-users wrote:
>>
>>> My idea would be to write our own wrapper which will have a struct (or
>>> alternatively a bitmask) that has fields that are booleans with names
>>> like "access", "inet", "stdio". Then we would need a function which is
>>> being compiled differently from OS to OS. It interprets the struct and
>>> then executes the required syscall.
>> I would imagine the function won't even need very much flexibility since
>> it'll invoke libcurl so it needs to let libcurl do what it needs to do -
>> but not more.
>>
>> I figure just diving in and experimenting with this is what's needed
>> here to get a feel for what can work and what will not...

seccomp() and friends are useful tools in more constrained
applications.  E.g. where a JIT (such as BPF) is generating code in a
restricted environment and knows exactly what calls it can make.  See
the man page for seccomp for some useful examples  -- and many caveats. 
They are not the right tool for hardening curl. 

Observations:

You would NOT want to activate this in libcurl.  Nor should it go
entirely in curl.

Assuming you want the function (and you probably don't), it should be
available to any process that uses libcurl.

But you don't want every program that uses libcurl to know the list of
syscalls - this may be fairly stable, but is guaranteed to change over
time.  Especially since libcurl has many dependencies.

You probably want a libcurl API to return the list of syscall names
(which is portable).  A calling program can merge it with its own list
and possibly a list from other libraries or programs it fork/execs, then
call the appropriate function.  Or it can trap syscalls and make sure
that only those come from libcurl's address space - if it wants to pay
the cost in overhead.  Or a test environment can log discrepancies to
help keep the list up-to-date.  This will be non-trivial - it's not just
curl/libcurl.  It's everything they touch - e.g. libssl, libcrypto,
libz, libbrotli, libnghttp2, libssh2, libldap, libresolv, libsasl2, ...
And every version of those libraries that libcurl might be linked
against.  With whatever configuration options each library might have. 

Note that curl runs on operating systems, such as VMS, where syscalls
may have different (non-POSIX) names, as well as a different
trapping/restriction mechanism.  So stick with names rather than
assuming a struct or bitmask will do.

That said, I doubt that the benefits are worth the complexity and
execution time cost.  Especially when you include programs that use
other libraries or fork programs.  It might be useful for debugging or
verification. 

I think you'll likely do better to setup a SeLinux/AppArmor (or
equivalent) wrapper for whatever environment a program is used in.  That
wrapper can constrain what files are written, resources accessed, etc in
a way that's sensitive to the specific use case.  Once the program is
labeled appropriately, its accesses will be mediated by the access
policy.  I don't think you can do this for curl in the general case -
because curl is such a general tool.  But you can easily have many
wrappers for curl that are constrained for specific use cases.  Plus
labeling the resources means that they can be protected from other
applications - not just curl.

Trying to control syscalls is too granular (the dependencies problem)
and also too non-specific to accomplish what you want.  Context
matters.  There's nothing wrong with curl executing a write() call to
stdout - unless it happens to be to /etc/passwd (probably - unless
you're recovering or synchronizing a cluster).  ioctl() By the time you
permit all the syscalls that any library might use, you won't have much
protection.  In any case, it's what they act on rather than the syscall
per-se that matters.

Using access controls protects the resources that can be
exploited/damaged.  Which is what you want.


Timothe Litt
ACM Distinguished Engineer
--------------------------
This communication may not represent the ACM or my employer's views,
if any, on the matters discussed.




-----------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-users
Etiquette: https://curl.haxx.se/mail/etiquette.html
Received on 2020-10-03