5

Sometimes Linux users need to to download a source code to be compiled then executed (the root privileges is granted).

Is it possible for a source code to hide malicious code as a part of it? And how does one verify that the source code is safe before compiling?

1
  • 1
    Some commercial security-focused static analysis tools have rulepacks to detect the insider threat, e.g., malicious logic, such as a backdoor, inserted into a codebase or built into it from the start (intentionally). Is that what you are looking for? Remember that often, many people have access to code repos (and they are not protected well). Some code generators will obfuscate the code, but with integrity-checking. Then there is the app "last-mile" problem of secure release and distribution.
    – atdre
    Commented Apr 17, 2016 at 16:42

5 Answers 5

6

Short of reading and understanding every line of code and how it all fits together, you realistically can't. The best you can really do is to download it as a package from a reputable source who vet the packages in advance, to minimise the risk for the user.

However, there are times when even full blown operating systems are hacked (such as Mint Linux earlier this year) so you can't really be sure what you're getting is safe.

As with most things I've found when thinking about security, a lot of it comes down to balancing trust and common sense.

2
  • 1
    As far as I know, this is also one of the reasons why one needs to know something about programming before executing an exploit. Even if the exploit code works, there is no way to know that the exploit can be safely used without reading and understanding the source code.
    – A. Darwin
    Commented Apr 15, 2016 at 18:41
  • The Mint example is interesting. Though, I think it was the ISO that was hacked, not the source code. How long do you think it would take you to read through the Mint source code and understand it? I believe one can strongly say that it is impossible to verify code. Commented Apr 17, 2016 at 14:31
4

No. It is not possible to verify code.

The mathematical analogue to this question is called the "program Verification" problem. Program verification is known to be impossible to decide. This means there is no algorithm that can check your computer code for correctness. Closely related, the halting problem is not decidable, meaning there is no algorithm that can tell you if your code will ever stop running. This was all proven back in the 1950-1960s, and everyone who gets a bachelor's degree in computer science should be taught about these results. It is mathematically impossible to verify code.

Even when reading through the code, it is not possible to verify it. In some cases, very short codes or algorithms can be proven correct using mathematical logic. Proofs only work for core algorithms, such as the sorting algorithms and graph traversal algorithms. For any large sized code-base, such as an operating system, there is no way to prove correctness.

Some static analysis and some formal methods tools exist, and all these tools attempt to do some limited form of verification. These tools try to prove what can be easily proven about the code. Static analysis tries to define provable properties of the dynamic behavior of the code when it executes. Some systems use asserts while others use loop invariants. However, in all cases, static analysis cannot perform full program verification.

If you decide to run a code you are implicitly trusting the authors of the code. You are trusting their intent to write code that works and that respects typical security policies, such as access authorization, permissions, etc. Tools such as mdsums can help you decide if you downloaded the version of the code that the authors made available, but they cannot help you verify the design of the code.

1

Yes, if one blindly downloads and compiles source code, that code could contain an exploit that, if run, could harm one's system. What's more, the resulting binary may not need to be explicitly run. In his 1984 classic Reflections On Trusting Trust, Ken Thompson demonstrated how one might go about creating C code that, when compiled, exploited the compiler and backdoored the system upon which that compiler resides.

There are some ways to defend against this. In 2006, Bruce Schneier blogged a pretty good breakdown of a paper by David A. Wheeler on defending against Thompson's specific example. The paper itself is still paywalled as of this time, to the best of my knowledge.

The Wheeler paper is very interesting, but it is focused on the bowels of compiler design, and this question seems more focused on end-user precautions than compiler design or even systems programming. There are generally two ways we understand the risk involved with compiling a specific piece of code:

  1. Authenticating the code as a true, untampered-with piece of code written by someone whom we have chosen to trust.
  2. Closely examining the content of the code itself, and thoroughly understanding what it does.

The second case--a thorough code audit--is a huge, long, resource-intensive task. It almost never really happens for codebases of nontrivial size, because it is simply too costly. Much more often, we are looking at the first case: trusting the coder, and validating that the code hasn't been tampered with between the coder and the consumer.

In 2015, I did an article for LinuxJournal on how code typically gets from the developer to the Linux user. Chain of Custody has since been republished by my employer outside the LinuxJournal paywall. It's heavily focused on the path that goes through package management, but if you read carefully, you'll realize that the parts applicable to a package maintainer compiling code obtained somewhere on the internet are also applicable to an end user doing so.

Of course, in the end, as others have pointed out, these integrity checks only do one any good if the developers' infrastructure hasn't been compromised, if the developer was coding well, and so on.

0

I think what you are asking for is "static analysis" (as opposed to "dynamic analysis" which analyzes running code).

The web security group OWASP has a page talking about static source code security analysis in broad terms. If you simply google for "static source code security analysis" you will find many product available (some payware, some free).

The part of the answer that you're not going to like is: typically these analyzers are looking for vulnerabilities in the form of buffer overflows, use-after-free, and stuff like that. It's almost impossible for a program to decide what counts as "malicious behaviour", for example the program may read all your files and upload them to a server. This is perfectly fine if the program is a cloud sync tool like Dropbox, but less fine if it's a solitaire game. Bottom line: there's no substitute for reading through the source code yourself.

Personally, I look at the reputation of the site I got the source code from. If it's on github or similar, who are the main contributors? If I google them, do they seem legitimate? The code itself was downloaded by HTTPS or SSH, right? I might look up some reviews of this software to make sure no bloggers have raised red flags about it, etc. (Final note: the risks of stuff like this is much lower if you're installing the software as a package through your distro's package manager, so always prefer this if possible.)

0

As others have mentioned, actually verifying that code has no malicious behavior is neigh impossible. There are a handful of special cases, where code was written to be verifiable, such as the seL4 kernel, but the general case is easily demonstrated as unsolvable.

In practical situations there are steps you can take to decrease the likelihood of an issue:

  • Download from a reputable source. If you can, stick to products which provide a signature you can check (and, of course, get that signature from a reputable source). This doesn't verify that the code is safe, but it does verify that when you think you got "gcc 4.4.2," that you actually got the code that everyone else calls "gcc 4.4.2" This is useful for the next step.
  • Check some of the major security sites to see if there are any known issues with the named product. For example, you can search the US government's National Vulnerability Database to see if there are known issues with that particular named product. Feel free to use other database as well if you do not trust the US gov't with your security.
  • Download as little as you can. This may be obvious, but it's worth mentioning
  • Don't be dependent on having trustable source code. Any good security should be security in depth. Obvious you should ensure your source code is as trustworthy as you reasonably can, but don't forget to have network tools watching for malicious behavior that might have escaped the first screen.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .