Security Versus Programming Language

AI Thread Summary
The discussion highlights the challenges of writing secure operating systems in C, emphasizing that inherent issues like buffer overflow and pointer validation contribute to insecurity. Participants explore the role of programming language features in enhancing security, questioning whether security implications differ between operating systems and other software. The conversation also touches on the complexity of creating secure languages for OS development, balancing performance and security requirements. Additionally, the importance of hardware-level security measures is noted, with examples of non-von-Neumann architectures that enhance security by separating code and data. Overall, the thread underscores the multifaceted nature of security in programming languages and operating systems.
anorlunda
Staff Emeritus
Science Advisor
Homework Helper
Insights Author
Messages
11,326
Reaction score
8,750
The following quote caught my eye.

http://catless.ncl.ac.uk/Risks/31/40 said:
It seems clear that trying to write secure operating systems in C does not
work. Very smart people have tried for 50 years, and the solution to the
problem is not reduced to practice.

I presume that buffer overflow, heap management, and pointer validation are the shortcomings of C that lead to insecurity. But the broader implications make me curious.

  1. What other features of a programming language directly aid security of the products?
  2. Are the security implications of the language different for OS compared to other software?
  3. My bias leans toward KISS. I suspect compiler/library vulnerabilities in very high level languages that lead to insecurities in the infrastructure. Are there studies that quantify complexity versus security? I mean statistically, not anecdotally. Perhaps DOD studies on Ada.

I realize that clarity and structure influence program quality, and thus indirectly influence security. I am asking about direct factors, not indirect.
 
Last edited:
  • Like
Likes Dale and Klystron
Technology news on Phys.org
One common problem in the early days of the web was form entry fields where the web application would take what is typed and store it. The problem was folks would try crazy stuff like entering strings with backticks which a way shell scripts use to execute commands:

In BASH, the line:

echo date is: 'date'

would first run the date command and stuff its output into the echo statement for it to print.

Curiously, I had to use ' single quote because this editor doesn't allow use of the backtick (its the character on the left most key next to the 1 key on your keyboard (US Keyboard your keyboard may vary)

They call these kinds of attacks injection attacks. Consider now if the entry field is placed in a sql insert statement and with backticking you could run a sql statement inside a sql statement or any valid linux/unix... statement for that matter. Alternatively you could mess with the sql statement itself as shown in the example below.

So now the prudent thing to do is to verify the user input and quote anything that is not alphanumeric.
hence the &gt. codes you see on urls today.

https://www.w3schools.com/sql/sql_injection.asp
One of the most famous examples of hacking was the Cliff Stoll story where a hacker entered a system by hacking a user acct, created a shell script called bin and changed the file separator to a space from /, proceeded to edit a file and then hung up.

The vi editor would try to retain the file for the user thinking the phone line had dropped (a common occurrence with phone modems) and keeping privacy in mind entered superuser mode saved the file to the /tmp directory so that only the user could access it and lastly, launched the /bin/mail command in superuser mode to notify the user of the file save.

With the hacker changing the / to a space the system actually ran the 'bin mail' command meaning it actually ran the hacker's bin command script in superuser mode allowing him to do anything on that system which he did creating a new acct staying as superuser and thus hiding from the normal security scans.

Cliff uncovered the deception when given the assignment to identify a $0.75 billing discrepancy that would pop up from time to time. He saw that one profs acct was accessed when this prof was on sabbatical at another university, hadn't signed on for over a year and that each time the person was on only for seconds and then disappeared.

https://en.wikipedia.org/wiki/The_Cuckoo's_Egg
and the NOVA show from 1990s:

 
  • Like
  • Informative
Likes mfb, Wrichik Basu, QuantumQuest and 1 other person
It might be nitpicking, but I could write a secure function SECURE_TEXT_FIELD to eliminate the injection problem. But then I depend on the programmer to use the function everywhere, and third parties will be forever suspicious that he did not.

A language feature does not depend on the programmer's discipline. For example, automatic garbage collection, or automatic real-time bounds checking.
 
Firstly a correction if I may - the article took a bit of finding as the fragment part of the url is incorrect - should be http://catless.ncl.ac.uk/Risks/31/40#subj6.

IMHO this is an intractable problem (and it seems that the author may agree with this as he refers to some failed alternatives). The fundamental requirement of any language for writing an operating system is that it can do anything with the hardware, and with this comes the possibility of doing bad things. Add the unnecessary but highly desireable requirement that the OS should do everything as quickly as possible makes the situation worse. Abstracting this ability away under a higher level language does not help - the problem then becomes 'how do we create a secure language for creating operating systems' with exactly the same challenges as 'how do we create a secure operating system', only now we have made it even harder to satisfy the performance constraint.

KISS is great, but unfortunately a further requirement for a (general purpose) operating system is to work on a range of hardware, both core and peripheral, and implement the latest standards for communication with other systems.

Hardened OSs turn these requirements upside down, placing security at the top of the pile. They only work on specific hardware, only communicate with other systems under the same level of control and any performance issues are dealt with by throwing $$$ at the problem.
 
anorlunda said:
A language feature does not depend on the programmer's discipline. For example, automatic garbage collection, or automatic real-time bounds checking.
These language features do not generally work well at the OS level - what happens when the automatic garbage collection interrupts a time-critical IO operation?
 
pbuk said:
These language features do not generally work well at the OS level - what happens when the automatic garbage collection interrupts a time-critical IO operation?
Before the job title was denatured, a programming team might consist of a 'systems programmer' working hand-in-glove with groups of application programmers under the general supervision of a software engineer. The systems person worked hard to avoid conflicts and optimize efficient I/O streams freeing application programmers to concentrate on apps. The software engineer conducted periodic software walk-throughs paying special attention to timing and synchronization. Multi-threaded parallel processing enhanced I/O throughput and computation efficiency at the expense of increased complexity.

Later, with network engineers, database engineers and configuration management (CM) build engineers collaborating on large projects; systems programmers might install OS patches and updates, configure browsers and email and perform jobs too technical for MIS (management information specialists) but that rarely required original code.
 
  • Like
Likes QuantumQuest
pbuk said:
Abstracting this ability away under a higher level language does not help - the problem then becomes 'how do we create a secure language for creating operating systems' with exactly the same challenges as 'how do we create a secure operating system', only now we have made it even harder to satisfy the performance constraint.
I think we are in agreement, that we can't blame insecurity on the choice of programming language. The comment referenced in the OP implies that insecurity is the fault of the C language.

Performance is a different subject. The desire for performance is hardly unique to the OS. Also, no matter how much faster CPUs become over the years, speed never seems to provide a cure for bugs or insecurity. That makes me skeptical of the suggestion that security and performance are tightly linked.
 
  • Like
Likes Klystron
Klystron said:
Before the job title was denatured

By being gently heated in a beaker over a Bunsen burner? :wink:
 
  • Like
  • Haha
Likes sysprog, Wrichik Basu and Klystron
Exactly like that, Peter. Systems programmers once worked directly on operating systems -- though I am referring to the time after they had to physically reroute wiring -- coding in assembler and machine specific job control languages. A new device meant writing or modifying a device driver. Like welding on an assembly line, the job has been automated.

definition:: denatured: 1) to deprive (object) of its natural character, properties, status, etc.
 
  • #10
Security begins fundamentally with the hardware.

The Burroughs B6700 architecture set the standard with hardware bounds checking and physical tags on words in hardware managed virtual memory. MCP, the Master Control Program, was the operating system. All languages ran under that, so were all equally secure as the system confined them to managed resources. Burroughs and it's architecture lives on as the secure Unisys ClearPath Libra servers.
https://en.wikipedia.org/wiki/Burroughs_large_systemsAlso see; 1973. Elliott I. Organik. Computer System Organization.
https://archive.org/details/bitsavers_burroughsBkComputerSystemOrganizationTheB5700B6700_10821314

A consortium tried hard to match the B6700 architecture and MCP security in software with Multics, but it never quite made it. Unix grew from the lessons learned. Thence Linux.

Security costs speed and money. Writing the fastest code to run on lowest-cost machines implies significant security weaknesses.
 
  • Informative
  • Like
Likes sysprog, Wrichik Basu, Klystron and 1 other person
  • #11
Baluncore said:
Security begins fundamentally with the hardware.
That's a very good point.

It always seemed to me that the most secure devices were those non-von-Neumann architectures that put all code in ROM in a different address space than data. Altering the code requires physical access and a soldering gun. My beloved TI Speak and Spell toy was a good example. Even if the toy had a net connection, there would be no way to alter the code remotely. Ditto for old-fashioned digital watches.

Alas, modern IOT devices don't seem to follow that, and many of them are claimed to be vulnerable to hijacking.

Modern OSs all seem to require the ability to receive remote security update patches. But the patch distribution mechanism itself can be hijacked and is thus a mandatory built-in threat vector. Stewart Baker claims that in the infamous Apple-FBI fight, that Apple could have forced the phone to accept a IOS update defeating the security.

In a von-Neumann architecture, we compile and link programs to create executable code. That program is data to the compiler and linker. But then we sprinkle it with pixie dust and say that it is now code. Isn't that the mechanism for almost all modern malware?

Why is it that non-von-Neumann architectures are not used more often?
 
  • #12
anorlunda said:
Why is it that non-von-Neumann architectures are not used more often?
Most x86 things in use are basically a flexible Harvard abstraction built on top of a partial Neumann fronted of a Harvard-like execution core...
I admit this description is debatable but still has it basis. I don't think Neumann has any residual responsibility in this mess anymore...
 
  • Love
Likes Klystron
  • #13
anorlunda said:
Why is it that non-von-Neumann architectures are not used more often?
It is because the fundamental von-Neumann bottle-neck is taught first to students in school. It would be different if message passing systems formed the basis for information processing education, then distributed processing would be obvious.
 
  • #14
anorlunda said:
In a von-Neumann architecture, we compile and link programs to create executable code.

This isn't because of the von Neumann architecture, it's because virtually all humans who write programs write them in source code, not machine code. (And those few humans who do write programs in machine code are writing very simple programs--nobody would write the code that runs this forum's website in machine code.)
 
  • Like
Likes QuantumQuest
  • #15
PeterDonis said:
(And those few humans who do write programs in machine code are writing very simple programs--nobody would write the code that runs this forum's website in machine code.)
Secure programs must be written in machine code to eliminate intrusion from below that wedge between the hardware and the system.
When does machine code become macro assembler? and when does that become a high level language like C?
 
  • Informative
Likes Klystron
  • #16
Baluncore said:
Secure programs must be written in machine code

Can you give examples? Or perhaps you are using a very, very strict definition of "secure program". For example, the OpenSSH suite of programs, which I use all the time, is normally considered "secure", but it's written in C. C is not machine code, it's source code.

Baluncore said:
When does machine code become macro assembler? and when does that become a high level language like C?

Machine code is the actual bytes that get executed by the CPU. Anything else requires some sort of translation into those bytes.
 
  • #17
PeterDonis said:
This isn't because of the von Neumann architecture, it's because virtually all humans who write programs write them in source code, not machine code.
I disagree. It has nothing to do with the language. It is a case where there is a block of memory. One instant is is data to the linker. The next instant is is executable code to the OS.

In the speak and spell, to change the executable code, one needs to put it in a ROM chip, then solder the chip into the circuit. No computer program, especially a remote program, can do that.

Think of a common exploit, buffer overflow. One program has a data buffer, it puts too much data into it so that the data goes into other memory. The other memory is where code is supposed to be so the OS allows it to execute. In a non-von-Neumann architecture where code and data have separate address spaces, no such thing can happen.
 
  • #18
anorlunda said:
In the speak and spell, to change the executable code, one needs to put it in a ROM chip

First one needs to write it. How do you write the executable code that goes in the ROM chip in the speak and spell? I'm betting you don't just write the executable bytes by hand, but use some human-readable source language and then compile it.

My point is not that putting the executable code in a ROM chip is no different in terms of protection from malware from having it in RAM in a conventional computer. My point is that none of this has anything to do with whether the executable code itself is compiled. You are focusing on compilation and linking as though that's the problem, but it isn't. The problem is executable code not having protection against being changed to something other than what the user wanted it to be.

Putting the executable code in ROM is one way of giving such protection, but not the only one. On the computer I'm writing this on, I cannot change the executable code of the program I'm using right now, because the user account I'm using doesn't have write access to the file and the memory the code is occupying is marked read-only by the operating system, whose code I also don't have write access to. (I'm running Firefox on Linux.) I won't say this is fully as difficult to beat as putting the code in ROM, but it is pretty difficult. (I have been running Linux for close to 20 years now and have never had a single piece of malware infect any Linux computer.)
 
  • Like
  • Informative
Likes QuantumQuest and Klystron
  • #19
PeterDonis said:
(I have been running Linux for close to 20 years now and have never had a single piece of malware infect any Linux computer.)
That's pretty remarkable.

https://en.wikipedia.org/wiki/Linux_malware
Am I wrong in that many insecure IOT devices run Linux? Things like nanny cams, smart thermostats, intelligent doorbells and the like.
 
  • #20
anorlunda said:
That's pretty remarkable.

I don't think it is for Linux users, actually. But then Linux users generally tend to be more computer savvy than average, since it takes a certain amount of computer savvy to run Linux. Perhaps less now than formerly, since there are at least some companies selling PCs with Linux preinstalled.

However, it is possible that I'm somewhat of an outlier even among Linux users. I am probably more paranoid than the average Linux user (I'm sure I'm more paranoid than the average Windows or Mac user), so I take precautions that others might not (for example, I don't even have a single user account for myself on the PC I'm writing this on--I have multiple accounts for different functions, to keep things more isolated).

anorlunda said:
Am I wrong in that many insecure IOT devices run Linux?

No, you're correct. But, from what I know of such devices, they are different from the Linux PCs I run in two key respects:

(1) Everything runs as root; there are no separate unprivileged user accounts. This is generally due to extremely limited memory and storage.

(2) Software development practices are very sloppy; people aren't paying any attention to security, so the devices are doing things that aren't secure. (For example, I believe there have been cases where the devices were not even using SSH or TLS to connect to servers, so their traffic could be intercepted and MITM'd.)
 
  • Like
Likes QuantumQuest
  • #21
PeterDonis said:
No, you're correct. But, from what I know of such devices, they are different from the Linux PCs I run in two key respects:
I guess the word Linux is too broad. We need to distinguish goodLinux from badLinux.

It makes discussions like this difficult because people use the same words to talk about different things (Copenhagen :-) . Ditto for the word secure. Secure $0.10 products or secure $1 billion dollar products, secure military/secure civilian. A desktop secure against the owner's own mistakes or secure against NSA's best.

It reduces to opinion. My bias is in the direction that "secure software" is an oxymoron. But I am more open to the idea of secure hardware; especially when qualified such as "secure against remote attacks."
 
  • Like
Likes atyy
  • #22
PeterDonis said:
(1) Everything runs as root; there are no separate unprivileged user accounts. This is generally due to extremely limited memory and storage.
Not in our IoT devices. The only way to run in root is to use the physical console connection. And security is a big deal here where I work, and lots of effort and thought goes into security software and practices without IoT devices that we design and deploy... :smile:

EDIT/ADD -- Caveat: I am a hardware designer, so maybe I should not try to say too much about software security.
 
  • Like
Likes atyy and QuantumQuest
  • #23
berkeman said:
Not in our IoT devices.

If that's true, good for you. Lots of IoT device manufacturers are less careful.
 
  • Like
Likes berkeman
  • #24
anorlunda said:
I guess the word Linux is too broad. We need to distinguish goodLinux from badLinux.

Not really, just careful manufacturers and users from less careful ones. The Linux that runs on those IoT devices is perfectly capable of supporting the same security practices as the Linux that runs on my PC; many manufacturers are just not very careful about using them.

anorlunda said:
My bias is in the direction that "secure software" is an oxymoron.

Nothing can be 100% secure, true. But it is certainly possible to write software with widely differing degrees of security. For example, you mentioned buffer overflows; if you explicitly bounds check all memory writes, you can't have buffer overflows. Or, if you don't want to depend on individual developers to remember to do that, you can write software in, say, Rust instead of C, so that buffer overflows are simply not possible to write.
 
  • #25
anorlunda said:
That's pretty remarkable.
https://en.wikipedia.org/wiki/Linux_malware<snip>

I like the Linux dude arguing against the idea that hackers do not write much Linux malware 'cause the market share is so small. <snicker> "Yes, we ARE big enough to hack!"

Even with kernel changes I still think of Solaris and Linux as UNIX; but I also miss VMS, so grain of salt.:cool:
 
  • Like
Likes anorlunda
  • #26
anorlunda said:
Think of a common exploit, buffer overflow. One program has a data buffer, it puts too much data into it so that the data goes into other memory. The other memory is where code is supposed to be so the OS allows it to execute.
There's really more to it than that. It's not really that the buffer gets filled with too much data, causing it to ooze over into code space.
anorlunda said:
In a non-von-Neumann architecture where code and data have separate address spaces, no such thing can happen.
Intel, and most likely AMD (but haven't checked) have a feature called Execute-Disable Bit. Software can detect the presence of this feature using the CPUID instruction. If present, this feature can be enabled for a memory page, so that the page can be used only as data. I.e., it can't be executed. This can go a long way to eliminate threats such as SQL code injection and buffer overflows.

I have a lot of experience with Intel assembly, but I haven't used this feature, not do I know whether OSes such as Windows or Linux use it extensively.
 
  • Like
  • Informative
Likes Wrichik Basu, QuantumQuest, Klystron and 1 other person
  • #27
Mark44 said:
There's really more to it than that. It's not really that the buffer gets filled with too much data, causing it to ooze over into code space.
Sometimes yes, sometimes no. I have read of buffer overflows that do exactly that. They use out of range index values to poke bytes of code directly into the code space. Without checking you can access the entire address range visible to your program. That's why I started in this thread talking about machines with separate address spaces for code and data. IMO that's much stronger defense than a bit saying what privileges you have for a block of memory.
 
  • #28
C was just not made with security in mind. There are features in other languages that can help a programmer to make safe code. A simple example is that the length of a string is not part of the C-language definition of a string. One must take extra care to ensure that string copies will not cause problems. Other languages make it easier. They can make the string length part of the string structure.
 
  • #29
FactChecker said:
C was just not made with security in mind.
Yep. The 'old' c was about providing a basic/minimalist framework for doing anything with the minimal limitations, but still in a readable format.
The actual hardware has many support features for security.
We do know that it is possible to write secure code in C.
If anything is to blame then maybe it'll be about the libraries (just get something for the job, fast - security is secondary) and the limited resources (money and time).
 
  • Like
Likes Klystron
  • #30
I started this thread just to find out if anything new in comp-sci relating to languages and security had been developed.

The question ought to be re-asked every 10 years or so.

Very many PF members to programming and have great interest in software although comp-sci is not their main field, and they don't follow the literature. What would be great would be if someone could write a post (or provide a link) to an annual summary "What was noteworthy in computer science in the past year."
 
  • Like
Likes Asymptotic
  • #31
anorlunda said:
I presume that buffer overflow, heap management, and pointer validation are the shortcomings of C that lead to insecurity. But the broader implications make me curious.

For me, C was not the first programming language I learned but it was by far the most influential and helpful language I've ever met. I have no doubt that the above quoted are shortcomings of C but to be fair the advantages and drawbacks of any programming language is something that can't be studied without reference to a specific period of time, to the specific hardware architectures and systems that it is / was run on - be it an application, a compiler or more importantly an OS and last but not least, the networking and internetworking scene of the time considered. I think that it does no justice to a programming language which has directly and indirectly influenced and in fact has paved the way to develop most modern software like C, to just call it an insecure language - I don't say that the original post does this, I just say it for clarification purposes.

As is widely known, C was originally designed for and implemented on the UNIX operating system on the DEC PDP-ll by Dennis Ritchie and it is a descendant of B which was influenced by BCPL. At the time created, C fulfilled specific goals: a general-purpose programming language which features economy of expression, modern control flow and data structures, and a rich set of operators. As a language near the "bare metal" but with a lot of high level features, it was inevitable that a lot of its power could potentially some day be utilized in innocuously inappropriate but potentially dangerous or purely malicious ways.

This became evident much later but in any case I don't think that it is due to intrinsic weaknesses - at least not so much, as it is due to the way that software was developed including libraries which to be fair they also need an appropriate time - frame, each one, to be judged fairly. There has been a lot of improving by the ANSI standards through years but again, especially for the case of OSes like UNIX and its descendants and Windows, all of which have a form of C "ticking" at their heart, the comlexity of the software itself combined with high demands for speed and flexibility does not leave much room to a programmer to be absolutely strict on security standards and on the other hand, real gurus of C - and C++ for that matter, are at least as far as I know very few - even nowadays, compared to the total number of people who are professional programmers.

The point for me is that C has done a tremendous job in the software industry for decades while hardware technology and networks / communications has, during this same time, improved so much. It is really difficult for me to think of another programming language that could have such a long-standing positive impact for machines and OSes in widespread use.

anorlunda said:
  1. What other features of a programming language directly aid security of the products?
  2. Are the security implications of the language different for OS compared to other software?
  3. My bias leans toward KISS. I suspect compiler/library vulnerabilities in very high level languages that lead to insecurities in the infrastructure. Are there studies that quantify complexity versus security? I mean statistically, not anecdotally. Perhaps DOD studies on Ada.

For the first, I would just say that features that aid security may be at odds with speed and flexibility and simpicity for the programmer, at least when taken to the extreme. There is no silver bullet here in my opinion. Absolute security can only come from hardware - as has already been noted, but this is not a silver bullet either, as we don't talk about dedicated OSes here or software constructs / systems in general, but for general purpose ones.

For the second, I think that the security implications are definitely different for OSes compared to other software, given the operations / tasks that the OS performs regarding hardware, itself and the software applications that run on it.The impact of security holes in an OS is combined and magnified in many cases and as the complexity of the OS increases so does the complexity of even idefintifying a potential hole. On the other hand a security hole in an application is in general and at average, more easily identified.

For the third, I think that KISS is a good general principle but unforunately, it may mean different things to different people at times and in any form, it is not always feasible to be followed. Software vulnerabilities are indeed in my opinion responsible for insecurities but this is inevitable: hardware must be fast and cheap and in many cases non-dedicated - at least for systems in widespread use, so software must do the job under the pressure of fast development, quick and dirty solutions in many cases, flexibility and simplicity. I think that the only think anyone sees at the end of this tunnel is "Welcome to the vulnerabilities realm".

anorlunda said:
In a von-Neumann architecture, we compile and link programs to create executable code. That program is data to the compiler and linker. But then we sprinkle it with pixie dust and say that it is now code. Isn't that the mechanism for almost all modern malware?

It may lead to potential vulnerabilities but with a lot of factors in between. Von Neumann architecture was a real innovation in my opinion, as it solved a whole lot of problems in order for computers to get into widespread use. Now, a whole lot of factors including but not limited to the evolution of hardware itself, programming and (inter)networking, come into play and mediate the final result. It isn't feasible to create cheap and secure hardware for widespread use, as it is not feasible to create ideally secure software for another multitude of reasons nor have complete control of a network and of its potential internetworking. On the other hand, can non - Von Neumann architectures be purely utilized in order to develop systems for widespread use? I think that at least for the form of such systems we have today, there is no such case.
 
Last edited:
  • Like
  • Informative
Likes Mark44 and anorlunda
  • #32
QuantumQuest said:
can non - Von Neumann architectures be purely utilized in order to develop systems for widespread use? I think that at least for the form of such systems we have today, there is no such case.
What about cheap, mass-produced, IOT devices? They may have no user interface at all, neither GUI nor command. They have no login. They have no admin. They have no plans for future updates or patches. But they have been hijacked for ill purposes using their net connection. Smart light bulbs, doorbells, web cams, location tags, smart buttons, swallow-able drug cartridges, the list is endless.

Can we make a case that IOT devices have an architecture such that the code can never be modified via remote action? Would that not go a long way toward making them hard to hijack?

In the coming years, the world may be swamped by trillions of such IOT devices. They are manufactured in many countries, some of which may have concealed intentions. They can be marketed internationally in bulk, perhaps X dollars per ton. If they are all vulnerable to hijacking, we are in big trouble. IMO we desperately need a solution to that problem international in scope and down-scalable to devices costing a fraction of a penny each, but which nevertheless permit innovation.
 
  • #33
anorlunda said:
Can we make a case that IOT devices have an architecture such that the code can never be modified via remote action?
That's a risk in itself what no company would like to take. In normal case for any software bug a patch can be provided, without the need of replacing the hardware itself. Fast and cheap (and inherently insecure indeed).

I don't think there is a solution (apart from keeping all the gizmo 'dumb', what I actually prefer). Keeping all the devices up to date requires far more care than possibly available. At the 'secure' price nobody would buy them.
On the long run the vulnerability of cheap IoT devices is just like the risk catching a cold.
 
Last edited:
  • #34
anorlunda said:
What about cheap, mass-produced, IOT devices? They may have no user interface at all, neither GUI nor command. They have no login. They have no admin. They have no plans for future updates or patches. But they have been hijacked for ill purposes using their net connection. Smart light bulbs, doorbells, web cams, location tags, smart buttons, swallow-able drug cartridges, the list is endless.

Can we make a case that IOT devices have an architecture such that the code can never be modified via remote action? Would that not go a long way toward making them hard to hijack?

In the coming years, the world may be swamped by trillions of such IOT devices. They are manufactured in many countries, some of which may have concealed intentions. They can be marketed internationally in bulk, perhaps X dollars per ton. If they are all vulnerable to hijacking, we are in big trouble. IMO we desperately need a solution to that problem international in scope and down-scalable to devices costing a fraction of a penny each, but which nevertheless permit innovation.

Here we have to make a distinction: IoT devices have no other major component than sensors. So, you're most likely talking about the whole IoT infrastructure. The model of this infrastructure consists of an IoT device, a gateway of some kind - various mediums of communication and transports can be utilized like cellular networks, satellite networks, Bluetooth, wide-area networks (WAN) to name a few, which is utilized in order to transmit data to a cloud server or some cloud infrastructure in general where the processing takes place and finally users get notified via some type of interface e.g. alarms on a mobile phone or email sent to some computer or device etc.

So, there is no non - von Neumann model, at least as I see it. Now, it is true that there is a big number of vulnerability issues that people using / involved in the development, management and use of IoT infrastructure have to face. The most recent ones according to the OWASP Internet of Things Project
are shown here. There are various ways to remedy these vulnerabilities and measures to take but there are of course some intrinsic weaknesses in this infrastructure which will give various kinds of "inspiration" to malicious users and attackers of any sort to invent and develop new vulnerabilities again and again.

And of course, I really have no doubt that as the number of IoT devices / infrastructures increases, concealed intentions from some people or even at a country level may find a fertile ground and at least as I see it, even with countermeasures already put then, it will be rather hard to avoid massive data leaks.
 
Last edited:
  • Informative
Likes Klystron
  • #35
QuantumQuest said:
rather hard to avoid massive data leaks.
That's not the only risk. In fact, the most alarming report I heard was that of IOT devices being hijacked into a bot net and used to help launch a DDOS attack.

When used as a bot, neither the sensors nor the normal communication channels of the device were used. It is just a CPU with a TCP/IP stack and a net connection, no different than a PC or a phone hijacked for bot use. In other words, a loose cannon. Huge numbers of loose cannons.
 
  • Like
Likes QuantumQuest
  • #36
C and C++ are entirely workable languages for creating a secure operating system and secure applications.

Security vulnerabilities are created by bad programming and bad software design. In the majority of cases, they are based on programming mistakes - buffer lengths that are not checked, resource arbitration that is flawed, memory that is used after it is 'free'd, password security or encryption that is not well thought out, functions reentered that are not coded for reentrancy, systems that depend on obscurity for their security. You will never have a secure system so long as you have sloppy design and coding.

Certainly operating systems contribute their share of vulnerabilities. But ultimately the OS needs to allow Adobe, Chrome, your favorite game, etc to operate. Those apps then use third party libraries that can include defects. And once those apps are running, there is nothing the OS can do if the app turns over all of its resources to malicious code.

There is no substitute for consistently good design and programming practices.

I would not promote coding in assembler (or machine language) when it can be avoided. It absolutely does not promote a secure system because that level of detail obscures the basic algorithm and implementation. The point of a programming language is to provide syntax that can be written and reviewed by people (programmers) and readily parsed by a compiler. On the other hand, it certainly pays to know exactly what code the compiler is generating since that is part of your debug environment.
 
  • Like
  • Informative
Likes sysprog, Nugatory, QuantumQuest and 1 other person
  • #37
There's an humongous thread in alt.folklore.computers circa 2005, concerning buffer overruns, that started as a crosspost from sci.crypt . 6k'ish posts. Unfortunately, trying to view it in Google Groups is giving my laptop a headache.

Long story short :

"OMG, how can we avoid 'buffer overruns' ?".
"Hire better programmers".
"But we can't afford that. Why don't we just require that C automatically checks every single array reference for out-of-bounds".
"Are you insane ?"

Doesn't matter, really : make something 'idiotproof' and the universe sees it as a challenge.
 
Last edited:
  • Like
Likes pbuk and FactChecker
  • #38
It's a serious weakness of C. If a language does not have a built-in, protected, size indicator as part of its standard structures, then protecting code from space overruns is a problem.
 
  • #39
FactChecker said:
It's a serious weakness of C. If a language does not have a built-in, protected, size indicator as part of its standard structures, then protecting code from space overruns is a problem.
And C# does. But I would not suggest dropping C and C++ in place of C#. They all have their place.
And, of course, you can borrow or create a memory management library. It won't be built in, but it'll still look good in the code.
 
  • Like
Likes FactChecker
  • #40
FactChecker said:
It's a serious weakness of C. If a language does not have a built-in, protected, size indicator as part of its standard structures, then protecting code from space overruns is a problem.
Hammers has no built-in protection against hitting your fingers - that's what you expect from a hammer.
From a different angle: it is not a weakness, it is a feature...
 
  • Like
Likes anorlunda and .Scott
  • #41
I once wrote a document about security problems. The main document is the property of the firm I was working for at the time, but this excerpt is general (and mostly my own):

3.1.1 The “C” Language
The “C” language is terse, flexible – and quite unsecure. Other languages usually refuse to compile when they meet ambiguous constructions or parameters of the wrong type. “C” compiles everything, at most writing an error message to the console, and even that message can be suppressed.
Therefore it should be mandatory to run all “C” code that is concerned with security through the lint code checker, or even better, the splint (Secure Programming Lint) code checker. While not a substitute for good programming practices, it catches most spurious errors and ambiguities.

3.1.2 The “Buffer Overflow” Vulnerability
A frequent root cause in Microsoft security bulletins, the “Buffer Overflow” vulnerability is usually caused by uncritical use of the standard C string copy function strcpy().
What this function dos, is copying a string into a buffer. What it does not do, is checking whether the string fits inside the buffer. Therefore, strcpy() will happily keep copying the string data on top of whatever data that are adjacent to the buffer. This behavior causes all kinds of problems – from the obscure to the catastrophic.
There are several ways around this vulnerability. You can:
• Check the length of the input string (using strlen()) before copying. If the input string is longer than expected, you can raise an error or allocate a larger buffer.
• Use the safer version of strcpy(), namely strncpy(). Remember that the length parameter in strncpy() should be one less than the size of the buffer, and that the last character in the buffer should be set to ‘\0’ after the copy.
• Use strdup() instead. This function creates a duplicate of the input string and returns a pointer to the copy. Remember to get rid of the copy (free()) when you are finished with it!

3.1.3 The “Null Pointer” Vulnerability
Several “C” library functions (e.g. malloc()) return a NULL pointer to indicate an error. Sloppy coding skips testing the returned pointer for NULL and uses it as if it were a valid pointer. Writing something into location 0x0000 (=NULL) - or close by – usually introduces a catastrophic fault at an unrelated part of the software.
Security experts see unchecked null pointers as the next great vulnerability exploitation.
 
  • Like
Likes FactChecker and .Scott
  • #42
I have coded thousands of strcpy()'s and they all work. Using that routine without considering buffer lengths or the possibility of invalid pointers is barely good enough for one-off code that will never see light of day. It is not good enough for even the lowest impact application that is going to be made public.

Svein said:
“C” compiles everything, at most writing an error message to the console, and even that message can be suppressed.
My last couple of jobs have involved mission-critical and life-critical systems where you buy additional tools to look for additional warnings - which you then resolve. But even with less critical systems (such as video processing) there were software standards.
Allowing any warning to go unaddressed allows new warning messages to get lost in the clutter.

I am astounded that major corporations need to resort to things like C# to hold to coding standards. It suggests that there are armies of programmers who aren't eager to do their full jobs.
 
  • Like
Likes QuantumQuest and Nugatory
  • #43
Svein said:
3.1.2 The “Buffer Overflow” Vulnerability
A frequent root cause in Microsoft security bulletins, the “Buffer Overflow” vulnerability is usually caused by uncritical use of the standard C string copy function strcpy().
Or scanf()...
Svein said:
Use the safer version of strcpy(), namely strncpy().
Several versions of Visual Studio ago, Microsoft introduced s_scanf() and several other input functions in the C standard library, which take an additional parameter when character arrays are to be input. Current VS versions have deprecated the older, unsecure, versions.
 
  • #44
PeterDonis said:
My point is that none of this has anything to do with whether the executable code itself is compiled. You are focusing on compilation and linking as though that's the problem, but it isn't. The problem is executable code not having protection against being changed to something other than what the user wanted it to be.
Compilation and linking is indeed a part of the problem, although it is better described as end-to-end validation of the entire toolchain. A good summary of the issue is Ken Thompson’s 1984 Turing Award lecture: https://www.archive.ece.cmu.edu/~ganger/712.fall02/papers/p761-thompson.pdf (although it does contain some anachronisms: written before any significant uptake of multi-byte character encodings; no discussion of hashing and signing; ...).

Protecting executable code is also only part of the problem, as altering the code is only one way of persuading code at a privilege level other than your own to do something you are not be allowed. SQL injection attacks are a trivial example, but there are many more.

And to return to the subject in the thread title... The idea that one programming language might be more secure than another is a snare and a delusion. One set of development practices may lead to more secure designs and implementations (confusing these two is another fertile source of security vulnerabilities) than another, and as part of defining these practices we may decide that one programming language will integrate with these practices better than another, but that tells us more about our approach than about whether one language is more secure than another.

The most secure system I ever worked with was written completely in C, including the ROM-resident boot loader. The very small microkernel that managed mapping from virtual to physical addresses (aggressive use of the x86 architecture’s segmentation machinery here) was formally validated, and although it is not feasible to formally validate a toolchain that includes a C compiler, the toolchain was carefully audited. The design goal was to be able run arbitrary binaries outside of the microkernel with confidence that compartmentalization (yes, this was a national security application) could not be violated in either direction.
 
  • #45
Nugatory said:
A good summary of the issue is Ken Thompson’s 1984 Turing Award lecture: https://www.archive.ece.cmu.edu/~ganger/712.fall02/papers/p761-thompson.pdf

That lecture supports the idea that secure software is an oxymoron, because obviously, code is used by users other than the author.
Ken Thompson’s 1984 Turing Award lecture said:
The moral is obvious. You can't trust code that you did not totally create yourself.
Nugatory said:
The most secure system I ever worked with was written completely in C, including the ROM-resident boot loader.
Ken Thompson would not have trusted your secure system because he didn't write it. Details of why you trust it are irrelevant to Mr. Thompson.

But that level of philosophy is far above the properties of any SW, any language, any hardware.

A good discussion of trust is given in this book by Bruce Schneier. Liars and Outliers: Enabling the Trust that Society Needs to Thrive

If we trust nothing, then we become paralyzed and unable to function. We suffer from self-inflicted pain. If we trust too much, then we are vulnerable to externally-inflicted pain.

But I am optimistic that someday we may learn how to manage trust. Therefore continuing interest in the topic is warranted.
 
  • #46
.Scott said:
I have coded thousands of strcpy()'s and they all work.
Have they all been attacked?
Using that routine without considering buffer lengths or the possibility of invalid pointers is barely good enough for one-off code that will never see light of day. It is not good enough for even the lowest impact application that is going to be made public.
Perfect people make perfect code. Imperfect people make imperfect code. It is good to have languages and tools that can help the imperfect people.
 
  • #47
.Scott said:
I am astounded that major corporations need to resort to things like C# to hold to coding standards. It suggests that there are armies of programmers who aren't eager to do their full jobs.
Well. More like: there are armies of coders (appointed as programmers) who does not even know what's their job would be.
I think that's the sad reality of 'security'.
 
  • #48
FactChecker said:
Have they all been attacked?Perfect people make perfect code. Imperfect people make imperfect code. It is good to have languages and tools that can help the imperfect people.
This isn't an issue of perfect vs. imperfect. You shouldn't use strcpy() unless you know your destination is large enough. The normal mistake is not for someone to miscalculate, but to make assumptions that should never be made - like assuming that input from the outside world is going to be correct.

And yes they are attacked. I attacked them myself.
 
  • #49
Nugatory said:
And to return to the subject in the thread title... The idea that one programming language might be more secure than another is a snare and a delusion.
I agree. Security does not come as a score out of 100. A system is secure or it is not.

To be secure the hardware must;
1. Differentiate between executable code and data.
2. Have hardware bounds checking on virtual memory pages used for code and for data.
3. Restrict privileged instructions to the kernel of the OS.

When you compile a C source and execute it on that system, the task is restricted to allocated resources and cannot detect or interfere with other users or resources. Any bounds transgression, attempt to execute data, or modify code, will result in an exception seen by the OS and not by the task.

Security comes from the hardware.
You cannot build a castle, or a tower of babel, on a foundation of sand.
 
  • #50
I'm going to be a bit contrary and blame C.

The 8088 was a 16 bit computer, and 16 bit addresses go to 64k. To address more space (the original IBM PC has 640k of memory), addresses were in two parts: a segment and an offset. The physical address was (segment * 16) + offset, so 1 MB was theoretically addressable. There were four segments, CS, DS, SS and ES, intended for code, data, stack and "extra", but there were no consequences (other than what was caused by bad programming) for using them any way you wanted.

Because the physical address was easily calculable, even across segments, C pointer arithmetic worked, even across segments.

Enter the 80286. It was to address 16 MB, and it was to enforce this data model. CS, DS and SS could not overlap (not sure about ES, but probably the same) and depending on a process' privilege level or ring had varying degrees of access to these areas in memory. It couldn't (without a hack) deal with the old segment+offset addressing, so it replaced "segment" with "selector", a 16-bit number which "uniquely identifies one of 16K possible segemnts in a task's virtual address space" but "the selector value does not specify the segment's location in physical memory."

C programmers hated it. C was the dominant language at the time, and C programmers really hated it. This change killed the single 20-bit address space and it killed pointer arithmetic for pointers more than 64k apart. It's hard to express the degree of hate programmers had for it if you weren't there. It was a revolt - with few exceptions, programmers simply refused to program this way, instead using just the lowest 1MB of memory where they could pretend they had an 8086.

So the customers chose convenience over security, and the vendors saw this and provided exactly that. And that lesson has not been forgotten.
 
Back
Top