Posts by pmeunier

ReAssure 1.10 Released

This new release of our testbed software provides users with full control of experimental PCs instead of being limited to running VMware images:


  • Experimental PCs can be rebooted at will
  • There is a LiveCD in the experimental PCs, which will take a root password that you specify before rebooting the PC
  • Users are now able to replace the operating system installed by default on experimental PCs, and gain full control
  • The host operating system for VMware is restored after an experiment.

This facilitates experiments with other virtualization technologies (e.g, Xen), or with operating systems or software that don’t interact in the desired manner with VMware.

When compared with other testbeds such as Deter, the differences are that:


  • You should be able to run anything on ReAssure, that is compatible with the hardware;
  • You may try to attack the ReAssure testbed itself;
  • Malicious software should have great difficulty escaping the testbed (if not using exp01 and exp02, the computers set aside for updating images);
  • Your experiments using VMware images are portable;
  • You can take VMware snapshots;

As before, you can still:


  • Use complex network topographies for your experiments, with high bandwidth utilization on each (Gbit ethernet)
  • Extend reservations or stop experiments at will;
  • Use ISO images and VMware appliances;
  • Share image files
  • Cooperate remotely with other people, and give them access to the PCs in one of your experiments
  • Update your images from two of our experimental PCs that allow connections to the outside (exp01 and exp02)

Under the hood changes:


  • The switch management now uses a UNIX domain server instead of a script started by cron.  This increases the responsiveness of the system, allows checking the state of the switch directly in real time, and allows self-test results to be displayed on the web interface (for administrators).
  • The upload mechanism now uses a UNIX domain server instead of a script started by cron.  This increases the responsiveness of the system and allows self-test results to be displayed on the web interface (for administrators).
  • The power state of the experimental PCs is controlled via IPMI (Intelligent Platform Management Interface) on an isolated network

Visit the
project home page, the testbed management interface itself, or download the open source software.  The ReAssure testbed was developed using an MRI grant from NSF (No. 0420906). 

RuxSeed v. 1.0 Released:  A Ruby Open Source XCCDF Loader

I am happy to announce that ruxseed v. 1.0 is now available on SourceForge. Ruxseed processes XCCDF documents used for SCAP (NIST Security Content Automation Protocol) checklists. It performs benchmark resolution, i.e., the 6 “Loading” steps. Given an XCCDF document, it returns a resolved benchmark in the form of an ReXML tree. The project also contains a number of tests that might be useful to someone developing an XCCDF product.

This release enables work on more complex XCCDF processing, such as tailoring and compliance checking. If you would be interested in that functionality, and are willing to test or contribute code or test cases, please contact me.

Finally, Somebody “Gets” Secure Web Browsing and Does It The Right Way

I’ve ranted before about how insecure web browsers are, because they trust themselves, their libraries and user-added plug-ins too much.  At a very high level, they have responsibilities that can be likened to those of operating systems, because they run potentially dangerous code from different sources (users vs web sites) and need to do it separately from each other and from root (the user account running the browser), i.e., securely.  The web browsers of today look as ridiculous to me as the thought of using Windows 95 to run enterprise servers.  Run an insecure plugin , get owned (e.g., Quicktime).  Enable JavaScript, VBScript, ActiveX, Java, get owned.  Get owned because the web browser depends on libraries that have more than 6-month-old vulnerabilities (1-year old depending on how you count), and the whole thing collapses like a house of cards.  As long as they are internally so open and naive, web browsers will keep having shameful security records and be unworthy of our trust. 

IE 7’s protected mode needs to be acknowledged as a security effort, but CanSecWest proved that it didn’t isolate Flash well enough.  It’s not clear if a configuration issue was involved, but I don’t care—most people won’t configure it right either then.  IE 7’s protected mode is a collection of good measures, such as applying least privilege and separation of privilege, and intercepting system API calls, but it is difficult to verify and explain how it all fits together, and be sure that there are no gaps.  More importantly, it relies heavily on the slippery slope of asking the user to appropriately and correctly grant higher permissions.  We know where that leads—most everything gets granted and the security is defeated.

Someone not only thought of a proper security architecture for web browsers but did it (see “Secure web browsing with the OP web browser” by Chris Grier, Shuo Tang, and Samuel T. King).  There’s a browser kernel, and everything else is well compartmentalized and isolated.  Similarly to the best operating system architectures for security, the kernel is very small (1221 lines of code), has limited functionality, and doesn’t run plug-ins inside kernel space (I’d love to have no drivers in my OS kernel as well...).  It’s not clear if it’s a minimal or “true” micro-kernel—the authors steer clear of that discussion.  Even malicious hosted ads (e.g., Yahoo! has had repeated experiences with this) are quarantined with a “provider domain policy”.  This is an interesting read, and very encouraging.  I’d love to play with it, but I can’t find a download.

Notes about the Faculty Workshop on Secure Software Development

On April 13-15, I attended the “Faculty Workshop on Secure Software Development” (alternatively called “Secure Coding Faculty Workshop” by SANS), paid for by NSF (no grant number yet) and organized by Bill Chu, Matt Bishop and SANS.  There were presentations from a number of faculty involved in secure coding or software engineering, as well as some companies.  My presentation focused on secure programming, and so was somewhat off-the-mark due to my confusion about the name and objectives of the workshop.  It was more about software engineering and introducing good security practices in the CS/SE curriculum, than secure coding itself.  In hindsight, the objectives appeared to be:


  • Share content.  There was some sharing at the workshop, with an attempt to gather relevant material from attendees and combine it into a repository.  I seemed to surprise people because I didn’t bring my laptop (I wanted to avoid the temptation of a distraction, and give all my attention to the workshop, avoid lugging it and getting it through the TSA screenings) so I ended up giving urls for my secure programming material.  The difference between this repository and others “that failed” (Sam Redwine pointed out the low success rate of educational material repositories) would be that SANS and industry would be “beating down doors” of universities and industry for its adoption.  I would have preferred if we had discussed and devised a mechanism by which we could leverage existing sources, discuss duplication of efforts, make a general appeal for relevant material from all sources instead of only those at the meeting, thought about the consolidation, organization and vetting of this material in a consistent and usable manner, not to mention identifying sources of funding to do so.  Input from a librarian would have helped.  Besides correctness, organization is a key difference between expert knowledge and ordinary knowledge.  This is a big problem that requires a lot of work to do correctly.  Despite seeing on a slide earlier the quote “success is foreseeing failure”, participants did not discuss very seriously how this effort could fail.  No amount of beating down doors will make people adopt content that is poorly organized and has little usability, yet despite awareness of this problem at the workshop, I believe that this hasn’t been addressed properly.  This is not to say that it’s doomed; but let’s think about why we really need it, what we really need, how it can fail and what we need to do to make it successful just not in the next few months, but how to make it a dependable resource with a lasting success.

  • Improve the content of training materials, whether these are professional training books or reference books for university classes.  A problem is insecure code examples that are later used “as is” in production systems.  These bad examples are used to create succinct code examples, but sometimes a more secure version wouldn’t be any longer in terms of number of lines of code.  Sometimes, authors use the excuse that “it was never intended for production use”, but most students don’t know any better than what teachers show them… Educators aren’t fully aware of their responsibility in that regard, or choose to ignore it for one reason or another.  One goal of the workshop was to initiate the creation of exercises that could be used to supplement or replace insecure code examples.  In my opinion too much emphasis was put on trying to come up with some during the workshop, instead of devising a systematic way of creating them, and ensuring the identification and correction of the relevant online material.
  • Network, keep contact and keep working on it...

Some people were pleasantly surprised by the usefulness and portability of the SEED labs.  I have been using some of these in CS 390S this semester and recommend them.  The Fedora Linux VMware image that I created for CS 390S is available for download on the ReAssure public downloads page.  If some of you created more images suitable for use with the SEED labs, please upload them in ReAssure as Kevin (Syracuse) doesn’t have the bandwidth to host them.

I was personally impressed by the secure software engineering program at Leuven as described by Wouter Joosen, but disappointed when I quickly hit pages that displayed “This information is not available in English. Consult the Dutch pages”.  I guess I’ll have to resort to babel fish translation and the likes.

My final concern is, without funding commitments this effort will rely on personal heroics.  I found it ironic that we were discussing how to improve software engineering while our effort would only classify as CMM level 1.  Open source and community efforts are nice and can deliver useful things, but they can also deliver lots of wiki stubs that nobody seemingly has the time or inclination to fill and complete, as well as vetting and other management problems.  The workshop resulted in great interactions, and clearly it was intended to just start the ball rolling.  My point is that we preach that solving problems at design time is 100 times less costly than at production time, yet it seemed that we were rushing to production.  Perhaps I just didn’t “get” the vision.  Nevertheless, I’m glad that I attended; there certainly were a lot of things to think about.

New Record for the Largest CVE Entry

Last week my script that processes and logs daily CVE changes broke.  It truncated inputs larger than 16000 bytes, because I believed that no CVE entry should ever be that large, therefore indicating some sort of trouble if it ever was.  Guess what… The entry for CVE-2006-4339 reached 16941 bytes, with 352 references.  This is an OpenSSL issue, and highlights how much we are dependent on it.  It’s impressive work from MITRE’s CVE team in locating and keeping track of all these references.

A Look at MITRE’s OVAL Schemas: A Weak Proof of Compliance

If you are intrigued by OVAL, the Open Vulnerability and Assessment Language, and are considering developing rules in it or just want to understand the technical details of how it works, you will need to look at its schemas.  The OVAL Design Document, Version 5.0 states that there are 3 schemas, for “representing configuration information of systems for testing; analyzing the system for the presence of the specified machine state (vulnerability, configuration, patch state, etc.); and reporting the results of this assessment.” However, when looking at the downloads available (here’s version 5.3) you’ll notice that there are 28 pdf documents.  Which ones do you need?

The document “Introduction to the OVAL Language, Version 5.0” contains this figure:
Conceptual Breakdown of the OVAL Language
-----------------------------------------
OVAL Definition Schema
|
|--> Core Schema
|
|--> Independent Schema (family_test, variable_test, xmlfilecontent_test, etc.)
|
|--> UNIX Schema (file_test, process_test, uname_test, etc.)
| |
| |--> Solaris Schema
| |--> HP-UX Schema
| |--> MacOS Schema
| |
| |--> Linix Schema (dpkg_test, rpminfo_test, etc.)
| |
| |--> RedHat Schema
| |--> Debian Schema
|
|--> Windows Schema (file_test, wmi_test, etc.)
|
|--> Apache Schema

This isn’t a 1-to-1 match with the pdfs available for download, but presents the idea.  One difference is that the downloads are organized by rows for “Core”, others for “Common”.  One of the downloads is titled inside as “Core Common”—which row would you guess it’s in?  What’s the difference between Core, Common and Independent?

Note that “Core Common” is present in all of the schemas, from “OVAL Definition Schema” to “OVAL Variables Schema” (hmm, that’s a 4th schema!?).  So, “Core Common” is what is common to the core of all schemas.  The “core” of a schema is therefore composed of the “Core Common” and the part of the “Core” that is specific to that schema.  Then, the “Independent” part of the schema describes things that are common to all operating systems, and serves to avoid duplication between the documents specific to OSes.  So, the difference between “Independent” and “Core” is that the OS-specific parts of the schema have dependencies on the “Core” but not on the “Independent” part.

To get a complete schema, you assemble it from “Core Common”, the “Core” that is specific to that schema, the “Independent” part of the schema, and then the parts specific to your system.  So, if you are interested in Solaris definitions, you would need to download the following parts: “Core Common”, “Core”, “Independent”, UNIX and Solaris.

As a more concrete example, the test to find if Solaris is running in 64-bit mode uses the “isainfo_test”, “isainfo_object”, and “isainfo_state” elements defined in the Solaris part of the definitions schema:


<isainfo_test id="oval:org.mitre.oval:tst:3884" version="1"
comment="system is running in 64-bit mode”
check_existence="at_least_one_exists" check="at least one">
<object object_ref="oval:org.mitre.oval:obj:2704"/>
<state state_ref="oval:org.mitre.oval:ste:3528"/>
</isainfo_test>

uses this object and this state:


<isainfo_object id="oval:org.mitre.oval:obj:2704" version="1"/>
<isainfo_state id="oval:org.mitre.oval:ste:3528" version="1">
<bits>64</bits>
</isainfo_state>

From what I can tell, the OVAL interpreter is required to know that given an “isainfo_object” and an isainfo_state with a bits child, it needs to run “isainfo -b”.  Information about a scanned system can be stored in a “isainfo_item” which would also have a “bits” child (defined in the Solaris System Characteristics document).

To check if a service is running you would use the element “process_test” (defined in the UNIX Definition schema, as in:


<process_test id="oval:org.mitre.oval:tst:1334" version="1"
check="at least one” comment="The Xorg X server is running”
check_existence="at_least_one_exists"
xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<object object_ref="oval:org.mitre.oval:obj:923"/>
</process_test>

which would do a pattern matching operation to the output of “ps”:

<process_object id="oval:org.mitre.oval:obj:923" version="1"
xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<command operation="pattern match">.*Xorg\b.*</command>
</process_object>

So again the OVAL interpreter has to know that it needs to run “ps” for this test, and to store the result in a “process_item” element (predictably defined in the Unix System Characteristics schema).

This is nifty but I still feel uncomfortable that all this gathered information is falsifiable in a difficult-to-detect manner.  An attacker who compromised the system and wants to evade detection, and therefore might avoid doing suspicious or more difficult things such as replacing a closed-source OVAL interpreter, could write something resembling a rootkit that would fetch up-to-date OVAL definitions and return “correct” answers when the OVAL tool runs.  A rogue administrator that just wants to pass some tests while doing other things and operating under configurations that aren’t compliant could write a fake “ps” or “inetd” to pass one or two specific rules; that would be much easier than to mess with the OVAL interpreter itself (in their simplest form the fake programs could simply print a constant string).  An attacker could want to indicate that all patches have been applied to avoid the possibility of a patch breaking a “modified” application or closing a backdoor.  It could be done by simply modifying or creating the appropriate registry keys.

Regardless of the likelihood of these scenarios, my point is that the evaluation is “subjective” in the sense that it is done by the subject of the evaluation.  Anyone wanting to evade compliance (as SCAP and XCCDF currently rely on OVAL, even though they are independent from it in theory) could do so easily, in concept anyway, so the software doesn’t necessarily need to fool the administrator, just the OVAL tool; it doesn’t need to be a full rootkit.  OVAL therefore provides a weak proof of compliance.  Using external tests whenever possible, conducted from a trusted machine, would be much stronger, but I see no evidence of efforts in that direction.  I realize that not all tests can be conducted externally, but emphasizing possible external tests would strengthen OVAL.  I have communicated those concerns to MITRE years ago, but it seems that the easy “practical” way is still favored.  One could argue that perhaps it’s “good enough”, and provides an opportunity for vendors to deliver value with more robust auditing methods.  But if the government is the main market for OVAL products, will it buy those better products or the cheap ones?  I understand that the government “needs yesterday” a manageable solution to handle compliance issues.  However, I’m afraid that once the weaker standard of proof will be in place, it will be very difficult to upgrade.

The open source Purdue Vulnerability Scanning Cluster based on Nessus is an example of the external approach to the evaluation of compliance (disclosure: I contributed to the design of the VSC).  A mixed solution, using external scanning when possible, as well as internal, would be very powerful, especially if discrepancies were flagged.

Virtualization Is Successful Because Operating Systems Are Weak

It occurred to me that virtual machine monitors (VMMs) provide similar functionality to that of operating systems.  Virtualization supports functions such as these:


  1. Availability


    • Minimized downtime for patching OSes and applications

    • Restart a crashed OS or server


  2. Scalability

    • More or different images as demand changes

  3. Isolation and compartmentalization

  4. Better hardware utilization

  5. Hardware abstraction for OSes

    • Support legacy platforms

Compare it to the list of operating system duties:


  1. Availability

    • Minimized downtime for patching applications

    • Restart crashed applications


  2. Scalability

    • More or different processes as demand changes

  3. Isolation and compartmentalization


    • Protected memory

    • Accounts, capabilities

  4. Better hardware utilization (with processes)

  5. Hardware abstraction for applications

The similarity suggests that virtualization solutions compete with operating systems.  I now believe that a part of their success must be because operating systems do not satisfy these needs well enough, not taking into account the capability to run legacy operating systems or entirely different operating systems simultaneously.  Typical operating systems lack security, reliability and ease of maintenance.  They have drivers in kernel space; Windows Vista thankfully now has them in user space, and Linux is moving in that direction.  The complexity is staggering.  This is reflected in the security guidance; hardening guides and “benchmarks” (essentially an evaluation of configuration settings) are long and complex.  The attempt to solve the federal IT maintenance and compliance problem created the SCAP and XCCDF standards, which are currently ambiguously specified, buggy and very complex.  The result of all this is intensive, stressful and inefficient maintenance in an environment of numerous and unending vulnerability advisories and patches.

What it looks like is that we have sinking boats, so we’re putting them inside a bigger, more powerful boat, virtualization.  In reality, virtualization typically depends on another, full-blown operating system. 
more OSes
VMWare ESX Server runs its own OS with drivers.  Xen and offerings based on it have a full, general purpose OS in domain 0, in control and command of the VMM (notwithstanding
disaggregation).  Microsoft’s “Hyper-V” requires a full-blown Windows operating system to run it.  So what we’re doing is really exchanging an untrusted OS for another, that we should trust more for some reason.  This other OS also needs patches, configuration and maintenance.  Now we have multiple OSes to maintain!  What did we gain?  We don’t trust OSes but we trust “virtualization” that depends on more OSes?  At least ESX is “only” 50 MB, simpler and smaller than the others, but the number of defects/MB of binary code as measured by patches issued is not convincing.

I’m now not convinced that a virtualization solution + guest OS is significantly more secure or functional than just one well-designed OS could be, in theory.  Defense in depth is good, but the extent of the spread of virtualization may be an admission that we don’t trust operating systems enough to let them stand on their own.  The practice of wiping and reinstalling an OS after an application or an account is compromised, or deploying a new image by default suggests that there is little trust in the depth provided by current OSes. 

As for ease of management and availability vs patching, I don’t see why operating systems would be unable to be managed in a smart manner just like ESX is, migrating applications as necessary.  ESX is an operating system anyway… I believe that all the special things that a virtualization solution does for functionality and security, as well as the “new” opportunities being researched, could be done as well by a trustworthy, properly designed OS; there may be a thesis or two in figuring out how to implement them back in an operating system. 

What virtualization vendors are really doing is a clever way to smoothly replace one operating system with another. This may be how an OS monopoly could be dislodged, and perhaps would explain the virtualization-unfriendly clauses in the licensing options for Vista:  virtualization could become a threat to the dominance of Windows, if application developers started coding for the underlying OS instead of the guest.  Of course, even with a better OS we’d still need virtualization for testbeds like ReAssure, and for legacy applications.  Perhaps ReAssure could help test new, better operating systems.
(This text is the essence of my presentation in the panel on virtualization at the 2008 CERIAS symposium).

Related reading:
Heiser G et al. (2007) Towards trustworthy computing systems: Taking microkernels to the next level.  ACM Operating Systems Review, 41
Tanenbaum AS, Herder JN and Bos H (2006) Can we make operating systems reliable and secure?  Computer, 39

Open Source Outclassing Home Router Vendor’s Firmware

I’ve had an interesting new experience these last few months.  I was faced with having to return a home wireless router again and trying a different model or brand, or try an open source firmware replacement. If one is to believe reviews on sites like Amazon and Newegg, all home wireless routers have significant flaws, so the return and exchange game could have kept going on for a while.  The second Linksys device I bought (the most expensive on the display!) had the QoS features I wanted but crashed every day and had to be rebooted, even with the latest vendor-provided firmware.  It was hardly better than the Verizon-provided Westell modem, which had to be rebooted sometimes several times per day despite having simpler firmware. That was an indication of poor code quality, and quite likely security problems (beyond the obvious availability issues). 

I then heard about DD-WRT, an alternative firmware released under the GPL.  There are other alternative firmwares as well, but I chose this one simply because it supported the Linsys router; I’m not sure which of the alternatives is the best.  For several months now, not only has the device demonstrated 100% availability with v.24 (RC5), but it supports more advanced security features and is more polished.  I expected difficulties because it is beta software, but had none.  Neither CERIAS or I are endorsing DD-WRT, and I don’t care if my home router is running vendor-provided or open source firmware, as long as it is a trustworthy and reliable implementation of the features I want.  Yet, I am amazed that open source firmware has outclassed firmware for an expensive (for a home router) model of a recognized and trusted brand.  Perhaps home router vendors should give up their proprietary, low-quality development efforts, and fund or contribute somehow to projects like DD-WRT and install that as default.  A similar suggestion can be made if the software development is already outsourced.  I believe that it might save a lot of grief to their customers, and lower the return rates on their products.

Firefox’s Super Cookies

Given all the noise that was made about cookies and programs that look for “spy cookies”, the silence about DOM storage is a little surprising.  DOM storage allows web sites to store all kinds of information in a persistent manner on your computer, much like cookies but with a greater capacity and efficiency.  Another way that web sites store information about you is Adobe’s Flash local storage; this seems to be a highly popular option (e.g., youtube stores statistics about you that way), and it’s better known.  Web applications such as pandora.com will even deny you access if you turn it off at the Flash management page.  If you’re curious, see the contents in “~/.macromedia/Flash_Player/#SharedObjects/”, but most of it is not human readable. 
I wonder why DOM storage isn’t used much after being available for a whole year; I haven’t been able to find any web site or web application making use of it so far, besides a proof of concept for taking notes.  Yet, it probably will be (ab)used, given enough time.  There is no user interface in Firefox for viewing this information, deleting it, or managing it in a meaningful way.  All you can do is turn it on or off by going to the “about:config” URL, typing “storage” in the filter and set it to true or false.  Compare this to what you can do about cookies… I’m not suggesting that anyone worry about it, but I think that we should have more control over what is stored and how, and the curious or paranoid should be able to view and audit the contents without needing the tricks below.  Flash local storage should also be auditable, but I haven’t found a way to do it easily.

Auditing DOM storage.  To find out what information web sites store on your computer using DOM storage (if any), you need to find where your Firefox profile is stored.  In Linux, this would be “~/.mozilla/firefox/”.  You should find a file named “webappsstore.sqlite”.  To view the contents in human readable form, install sqlite3; in Ubuntu you can use Synaptic to search for sqlite3 and get it installed.  Then, the command:
echo ‘select * from webappsstore;’ | sqlite3 webappsstore.sqlite

will print contents such as (warning, there could potentially be a lot of data stored):
cerias.purdue.edu|test|asdfasdf|0|homes.cerias.purdue.edu

Other SQL commands can be used to delete specific entries or change them, or even add new ones.  If you are a programmer, you should know better than to trust these values!  They are not any more secure than cookies. 

Speculations on Teaching Secure Programming

I have taught secure programming for several years, and along the way I developed a world view of how teaching it is different from teaching other subject matters.  Some of the following are inferences from uncontrolled observations, others are simply opinions or mere speculation.  I expose this world view here, hoping that it will generate some discussions and that flaws in it will be corrected. 

As other fields, software security can be studied from several different aspects, such as secure software engineering, secure coding at a technical level, architecture, procurement, configuration and deployment.  Similarly to other fields, effective software security teaching depends on the audience—its needs, its current state and capabilities, and its potential for learning.  Learning techniques such as repetition are useful, and students can ultimately benefit from organized, abstracted thought on the subject.  However, teaching software security is different from teaching other subjects because it is not just teaching facts (data), “how to” (skills) and theories and models (knowledge), but also a mindset and the capability to repeatably derive and achieve a form of wisdom in various, even new situations.  It’s not just a question of the technologies used or the degree of technological acumen, but of behavioral psychology, economy, motivation and humor.

Behavioral Psychology— Security is somewhat of a habit, an attitude, a way of thinking and life.  You won’t become a secure programmer just because you learned of a new vulnerability, exploit or security trick today, although it may help and have a cumulative effect.  Attacking requires opportunistic, lateral, experimental thinking with exciting rewards upon success.  It somewhat resembles the capability to create humor by taking something out of the context for which it was created and subjecting it to new, unexpected conditions.  I am also surprised sometimes by the amount of perseverance and dedication attackers demonstrate.  Defending requires vigilance and a systematic, careful, most often tedious labor and thought, which are rewarded slowly by “uptime” or long-term peace.  They are different, yet understanding one is a great advantage to the other.  To excel at both simultaneously is difficult, requires practice and is probably not achievable by everyone.  I note that undergraduate computer science rewards passing tests, including sometimes provided software tests for assignments, which are closer to immediate rewards upon success or immediate failure, with no long-term consequences or requirements.  On top of that, assignments are most often evaluated solely on achieving functionality, and not on preventing unintended side-effects or not allowing other things to happen.  I suspect that this produces graduates with learned behaviors unfavorable to security.  The problem with behaviors is that you may know better than what you’re doing, but you do it anyways.  Economy may provide some limited justification.

Economy—Many people know that doing things securely is “better”, and that they ought to, but it costs.  People are “naturally optimizing” (lazy)—they won’t do something if there’s no perceived need for it, or if they can delay paying the costs or ultimately pay only the necessary ones ("late security” as in “late binding").  This is where patches stand; vulnerability disclosures and patches are remotely possible costs to be weighted against the perceived opportunity costs of delays and additional production expenses.  Isolated occurrences of exploits and vulnerability disclosures may be dismissed as bad luck, accidents or something that happens to other projects.  An intense scrutiny of some works may be necessary to demonstrate to a product’s team that their software engineering methods and security results are flawed.  There is plenty of evidence that these attempts at evading costs don’t work well and often backfire. 
Even if change is desired, students can graduate with negligible knowledge of the best practices presented in the
SOAR on Software Security Assurance 2007.  Computer science programs are strained by the large amount of knowledge that needs to be taught; perhaps software engineering should be spun off, just like electrical engineering was spun off from physics.  Companies that need software engineers, and ultimately our economy, would be better served by that than by getting students that were just told to “go and create a program that does this and that”.  While I was revising these thoughts, “Crosstalk” published some opinions on the use of Java for teaching computer science, but the title laments “where are the software engineers of tomorrow?” I think that there is just not enough teaching time to educate people to become both good computer scientists and software engineers, and the result is something that satisfies the need for neither.  Even if new departments aren’t created, two different degrees should probably be offered.

Motivation—For many, trying to teach software security will be in one ear, out the other unless consequences are demonstrated.  Most people need to be shown the exploits that a flaw enables, to believe that it is a serious flaw.  This resembles how a kid may ignore warnings about burns and hot things until a burn is experienced.  Even as teenagers and adults, every summer some people have to re-learn how sunscreen is needed, and the possibility of skin cancer is too remote a consideration for others.  So, security teaching needs to contain a lot of anecdotes and examples of bad things that happened.  I like to show real code in class and analyze the mistakes that were made; that approach seems to get the interest of undergraduates.  At a later stage, this will evolve from “security prevents bad things” to “with security you can do this safely”.  Actualizing secure programming can make it even more interesting and exciting, by discussing current events in class.

Repetition—Repeated experiences reinforce learning.  Security-focused code scanners repeat and reinforce good coding practice, as long as the warnings are not allowed to be ignored.  Code audits reinforce the message, this time coming from peers, and so result in peer pressure and the risk of shame.  They are great in a company, but I am ambivalent about using code audits by other students, due to the risk of humiliation—humiliation is not appropriate while learning, for many reasons.  Also, the students doing the audit may not be competent yet, by definition, and I’m not sure how I would grade the activity.  Code audits by the teacher do not scale well.  This leaves scanners.  I have been looking into it and I tried some commercial code scanners, but what I’ve seen are systems that are unmanageable for classroom use and don’t catch some of the flaws I wish they would. 

Organization and abstraction—Whereas showing exploits and attacks is good for the beginner, more advanced students will want to move away from black lists of things not to do (e.g., “Deadly Sins") to good practices, assurance, and formal methods.  I made a presentation on the subject almost two years ago.

In conclusion, teaching secure programming differs from typical subject matters because of how the knowledge is utilized; it needs to change behaviors and attitudes; and it benefits from different tools and activities.  It is interesting in how it connects with morality.  Whereas these characteristics aren’t unique in the entire body of human knowledge, they present interesting challenges.