Okay, fine—sort of. I have a beef with this.
Good security practice is about implementing layers of security, and this flies in the face of that. If certain other vulnerabilities are present, the most obvious one being HTTP response splitting, then CSRF is once again possible. Any vulnerability that could allow custom headers to be inserted in a CSRF request now makes them possible because the authenticity token is bypassed by a custom header.
In my opinion, if a site has data worth protecting with an anti-CSRF authenticity token, there’s no reason not to use it for all requests that can alter that data. Doing the bare minimum is what I call Just-Barely-Enough Security.
Note that Rails 3.0 handles CSRF protection differently (within Rack), and I have not examined it; the above comments apply only to Rails 2.x.
So it turns out that Rails is not the only web framework out there where the CSRF protection was in the just-barely-enough category. I have also been working on a Django 1.1 project recently, and in doing so I have found another category of just-barely-enough security (fixed in Django 1.2). Django 1.1 generates the authenticity token in a somewhat weak manner, but it is not weak enough that it is exploitable by itself. The weakness is that the authenticity token is the MD5 hash of a site-wide secret concatenated by the session ID (in contrast, Rails 2.3 and Django 1.2 generate a completely random token for each session). Because of how MD5 hashes are computed, an attacker could potentially learn the state of the MD5 computation up to the point of hashing the site-wide secret and himself compute any authenticity token given a session ID without further consulting the Django server. However, this is not an issue by default because Django’s session fixation protection prevents it from responding with session IDs that it did not generate, so the attacker cannot build up the necessary information to perform the attack. But if something were to be configured wrong on the Django server and a session fixation attack were to be possible, then the attacker would have more avenues for exploitation than just using session fixation on the victim directly.
Even worse would be a situation where the session fixation issue was found and repaired, but not before an attacker gleaned the necessary information to generate authenticity tokens for the site. The site administrator would think he closed the security hole, but his site may still be exploitable based on previously leaked information. That would be rather unfortunate.
]]>Honestly, at first I found it a little frustrating. There I was spending half my time watching someone else implement some stuff, and my brain simultaneously stuck elsewhere solving world hunger while trying to be “helpful” to that other guy with me. It took a few weeks before the benefits really started dawning on me and also to appreciate the contribution I make when not the guy with the keyboard. I think many people have recounted much of what is great about pair programming, but the one that I have not heard that really makes me giddy is that your partner prevents you from being lazy.
In particular, I do not mean that your partner prevents you from using things like email as a distraction from getting stuff done (another benefit that others have recounted). Instead I mean that when you are racing to complete a programming task and you encounter a decision to: (1) hack it and jam something in place quickly, or (2) Doing It Right but burn up extra time doing so. Without a partner you typically choose #1 while lamenting that you did not choose #2. You add to your technical debt and bad karma and you are ridden with guilt; it is a double whammy!
With a partner, what happens instead is that you suggest #1 to your partner, but regardless of whether your partner can discern whether #1 is Doing It Right he can see your hesitation and draws your thoughts out of you about #2. Before you know it, he is excited to see you through to Doing It Right! Your heart leaps in joy and later, when you go home for the day, you smile just a little more when your sweetheart asks, “how was work today, honey?” 
As the dinosaurs continue to fall, the need for the goods and services they have been providing up until now will not disappear. The people that previously fed the dinosaurs (customers and employees) will have new opportunities to feed another kind of creature that has always been around here and there but will explode in numbers to take care of the things dropped by the dinosaurs. These creatures are the mammals.
Mammals are good for economies. Most of them are small, light on their feet, and they are warm-blooded. They do not create a “Customer Loyalty” program to pretend they care; they actually do care, and that care is felt person-to-person in the dealings of business. Because mammals are typically smaller than dinosaurs, it is easier for them to operate closer to home. Your money stays local instead of going to Washington or New York. In the good times when Washington and New York are flush with cash, the dinosaurs are happy to re-invest it everywhere. As times turn ugly, they will cling onto your cash and your locale will see nothing coming back. This is why it is so hard to find a loan these days, even if your credit worthiness is really good.
I urge people to not wait for the dinosaurs they feed to collapse, but to invest today in the mammals available in your area. Your money will be going towards making your local economy more robust and better able to provide new jobs in your area as the dinosaurs continue to release personnel. Times will be tough for the next year or two, but in the end I want to look back at this time as the time of opportunity—our time for building a new kind of economy that will take care of us for time eternity.
Let me repeat one thing before I sign off: invest in your local mammals today. Feed them now so they will be strong enough to feed you back when you need them.
]]>If you are not familiar with my AVLTree project, it is a C library that implements AVL trees and provides an interface for indexing and iterating over objects. I like to think of it as my little C answer to the hashes and dictionary objects available in more advanced languages.
]]>I thought it would be so nice to be able to do this that I wrote the VBA to do it. I call it TemplateKicker. To use it, I copy the TemplateKicker module and the TemplateKickerVariables class module into my spreadsheet from TemplateKicker.xls (this file also contains the example shown here). Then I write a macro to insert the values for each location I am reporting on:
Public Sub Widget_Report()
Dim Vars As TemplateKickerVariables
Dim LocationIDs As Variant
Dim WidgetSales As Variant
Dim Index As Integer
LocationIDs = Array("A-12345", "B-22222", "C-33333", "D-2R2", "E-5555")
WidgetSales = Array(34, 12, 15, 6, 39)
Set Vars = New TemplateKickerVariables
For Index = 1 To 5
Vars.SetVar "location:" & Index & ".id", LocationIDs(Index - 1)
Vars.SetVar "location:" & Index & ".widgets.sold", WidgetSales(Index - 1)
Next Index
KickWorksheet(ActiveWorkbook, Sheets("Sheet1"), Vars).Name = "Widgets"
End Sub
One run of the macro later, and I have a new worksheet with the results:
TemplateKicker also has the following features that I will showcase in upcoming blog posts:
Even with all this, however, TemplateKicker does have some limitations:
Still, I think this is a great start to doing some pretty awesome things in Excel VBA. I do not know if I will develop it further, but if you find it interesting please let me know!
As a side note, CosineWave Technologies Inc. now also offers VBA solutions for business automation now. Please drop me a line if you have need for some tools to automate your workflow when using Microsoft products (or many other products for that matter)!
Here are the highlights of the pros:
But there are also the cons:
I think Mephisto is a better platform than Radiant at this point, and in my opinion it gives Rails a reasonably usable blogging platform. Before committing more time to it, however, I think I will take a look at the much touted Drupal. I have been meaning to take a look at it anyway. 
Here are the primary services that I offer today:
Please go to the CosineWave website and drop me a line if you are interested in hiring me!
And to all my friends and colleagues that have helped me get here: thank you very much!
]]>My morning at work went relatively fast. I had very few scheduled tasks because of meetings dotting my schedule and my vice president’s group was all going out to play Whirlyball for the afternoon. Additionally, due to my company’s sales team scoring a big contract, the company was serving free Lou Malnati’s pizza for lunch.
Whirlyball was probably the most fun of the day, but it is what happened afterward that is the most interesting. I arrived at Houlihan’s at 6:30, preparing to socialize with other security professionals at Chisec 16 starting at 7:00. I did not wait long. I had hardly sat down when Maniac showed up, always full of interesting conversation and even an Asus Eee PC, something I had never seen before. It was not long before the room was full of other security professionals from all over the Chicago area.
With 20–30 people in a room, you do not get to talk to everyone. I primarily spoke with a couple guys from the University of Chicago and some consultants from no less than three different firms. It was Thomas Ptacek that gave me the biggest surprise of the evening.
Tom told me that it is getting increasingly rare to find computer people that know C. I had never thought about it, but I could see why this would be a problem. I have been using C since 1994, and I simply consider it a staple of my computer abilities. It is like part of the foundation. It is through C that I know how a shell interacts with an operating system, or how any program interacts with other components of the system. My knowledge of C is how I learned about the general structure of a running process in memory, and from that I understand how things like buffer overflow attacks actually work. It is through C that I even know how Ruby handles its garbage collection, at a low level. In regard to modern computer architecture, if you do not know C, then I would be incredulous if you told me that you really understand computer architecture. I am not sure that knowledge of C++ can really convey the same understanding, except that someone could do so by paying close attention to the subset of C++ that is C.
I wonder… do you know C? If I were to compile a list of important languages that all computer programmers should learn, C would be high on the list, if not the top language. Certainly there are other important languages out there that expand ones mind around advanced programming topics, such as Ruby, Lisp, and ML, but down at the linker level C is the language that all other languages communicate with the operating system or the hardware—application binary interfaces (ABIs) are designed around how C compilers generate object files. It is that important.
]]>Also, I want to share this bit posted on Jim Weirich’s blog. He said it is on his wall, and I liked it so much that it is also on mine now, too.
]]>I was going to review it for its security best practices and WS-Security recommendations… but there are not any. Take that to mean what you will.
]]>But Cosine, you might say, Paul developed Arc so that the language would have nifty breakthrough features unlike any ever seen before to make code more concise! Without the base language support for these features, Ruby will not beat Arc at its own game!
Well, someone has already written a library (it should be reformatted properly into one, anyway) in response to the Arc Challenge that implements part of the Arc standard library, exposing for Ruby any language features in Arc that Paul was trying to showcase in the Arc Challenge.
Paul, please give us a challenge that shows a fundamental language design difference rather than displaying a gap in the presently available libraries. I know you are a smart cookie, so you must be hiding something up that sleeve.
Actually, I can think of one advantage Arc has over Ruby. Arc is Lisp whereas Ruby is not, and following from that Arc has macros while Ruby has ugly workarounds to fake macro writing. But everyone already knows that. Hmmm, maybe what we really want to do is have all our Ruby gems and Rails made available for Arc? Arc on Rails, anyone? I think that would be pleasant.
]]>Why wait? Get out there and get started with Rails today! 
1. SSL is ubiquitous and most everyone knows how to use it, whereas WS-Security is largely an “unknown” to most organizations.
2. Both SSL and WS-Security are easy to “drop in” to a typical web service architecture, though SSL is somewhat easier due to the previous observation.
Both SSL and WS-Security have programs or libraries that make adding them to an existing web service a reasonable task.
Adding SSL to a web service can be as easy as putting Stunnel or other SSL termination software in front of the service. However, to integrate SSL’s authentication features one would need to have the results of the SSL handshake passed into the application somehow. More often a server ends up using weaker credentials, such as username and password, inside the SSL connection to establish the identity of its users.
With WS-Security, implementation can be done by adding a few calls to an appropriate WS-Security library, such as WSS4J (Java) or WSS4R (Ruby).
3. SSL provides security for an entire connection; WS-Security secures each message one by one.
If an application keeps a connection open to make multiple requests of a web service, then SSL would provide better performance than WS-Security. Exactly how much better may depend on your servers’ average load. The difference in computation is due to SSL using mostly symmetric key encryption after the initial handshake at the start of the connection, whereas WS-Security needs to perform asymmetric key encryption on each message (one computation for handling encryption and one computation for handling the signature). Symmetric key encryption is a lot faster than asymmetric key encryption, and while both technologies switch to using symmetric key encryption as fast as possible to provide the best performance, WS-Security is unable to avoid those asymmetric key computations on every message.
On the other hand, since security is applied on a message-by-message basis with WS-Security, an application is not susceptible to possible channel hijacking or HTTP splitting attacks that could occur with SSL. If either of these things were to happen when WS-Security was in use then its security features would still protect the message and the data.
4. SSL requires an immediate communication with the endpoint to securely transmit data; WS-Security can protect a message that is queued up or stored on intermediate servers without additional concerns.
With SSL, the SOAP messages themselves remain unencrypted but are transmitted through a secure tunnel (the SSL link). If that message ends up being stored on a disk (queued) prior to use, then it is unprotected from being read or tampered with by anyone who can obtain access to that disk. If you think this is unlikely then you should know that attackers are often able to leverage poorly configured web, FTP, Citrix, remote desktop, and Windows file sharing servers to access disk. This is one of several reasons that encryption of data at rest has become more important recently, and “at rest” refers to any time data hits a disk or a tape, not just when it resides within a database.
On the other hand, WS-Security imposes its protections upon the message itself, so if the message were to be copied by an adversary he could not read it. If the attacker could find a way to get write access to the disk containing the WS-Security protected message waiting in queue, any attempt to tamper with the message is detected by WS-Security’s integrity protection features.
Comparison Summary
SSL (pros):
SSL (cons):
WS-Security (pros):
WS-Security (cons):
After reviewing the differences I suggest that WS-Security should be the preferred choice of most enterprises. Do note that I suggest you do both SSL and WS-Security (for defense in depth and to provide some security by obscurity against those that would sniff your packets), but if you were to limit it to one or the other then I would prefer WS-Security. The issue that convinced me was the security of messages left in queue on disks. This situation happens rather frequently (swap files, anyone?) and is often done unbeknown to the original application architect as the system grows and the message delivery mechanism is changed. WS-Security simply provides security from end to end without worrying that every step of the way is secured appropriately as well; SSL only promises security between the endpoints of the SSL tunnel.
]]>Fortunately, the GNU Screen program can share that command line session of yours with other users with accounts on the same Unix host. Screen comes with a multi-user mode that allows them to connect to it. Each user can be granted permissions to each window to view, interact, or issue other commands to Screen. Here is a .screenrc file I have used to implement three groups of users: read-only users that can view all windows, read-write users that can also type in all windows, and an administrative user (the account that runs screen in my case) that retains all permissions within Screen.
multiuser on aclchg READERS +r-wx "#" aclchg READERS -rwx "?" aclchg READERS +x colon,license,windows,next,prev,select,other,detach,suspend,redisplay,lastmsg,windowlist,help,stuff aclchg WRITERS +rw-x "#" aclchg WRITERS -rwx "?" aclchg WRITERS +x colon,license,windows,next,prev,select,other,detach,suspend,redisplay,lastmsg,windowlist,help,stuff aclgrp watcher1 READERS aclgrp watcher2 READERS aclgrp trusted1 WRITERS aclgrp trusted2 WRITERS aclumask "*"-rwx cosine+rwx READERS+r-wx WRITERS+rw-x "?"-rwx "??"-rwx
In this example, the administrative user is cosine. The read-only users watcher1 and watcher2 are in the READERS group. Likewise, the read-write users trusted1 and trusted2 are in the WRITERS group. Users are placed in groups with the aclgrp command.
The other commands to set this up can be understood with a careful read of Screen’s man page. The short of it is that for READERS we give read access but no write or execute (+r-wx) for all windows (#), then we do not allow any access (-rwx) to any Screen commands. Next we do enable access (+x) to a reasonable set of Screen commands necessary for navigation and comfortable viewing—otherwise Screen would not allow the user to change windows, exit his session, or a few other commands Screen users take for granted. The aclumask command provides a similar level of coverage to windows that are yet to be created. The WRITERS group is given similar permissions, except users in that group are also allowed to write (i.e. type things) into all windows.
If we wanted to create an ADMINS group that had full control of screen (able to create new windows and execute arbitrary screen commands), we could do so by replacing the aclumask command with another that replaces the mention of the cosine user with an ADMINS group, adding a pair of aclchg commands to grant this group access to everything, and then adding some users to the group:
aclchg ADMINS +rwx "#" aclchg ADMINS +rwx "?" aclgrp cosine ADMINS aclgrp admin1 ADMINS aclgrp admin2 ADMINS aclumask "*"-rwx ADMINS+rwx READERS+r-wx WRITERS+rw-x "?"-rwx "??"-rwx
If you begin experimenting with these “acl” commands in Screen, do make sure you test your configurations before using them. Screen did not make these commands particularly user-friendly, and they do not always behave how you might think they do. They feel like they were bolted onto the program as an afterthought, and if you have been reading my blog for very long you know how I feel about that. I would not use Screen’s multi-user mode for any high-security application.
]]>[]:
irb(main):001:0> a = [1, 2, 3, 4, 5] => [1, 2, 3, 4, 5] irb(main):002:0> a[1..-1] => [2, 3, 4, 5] irb(main):003:0> a[1..a.size] => [2, 3, 4, 5] irb(main):004:0> a[1...-1] => [2, 3, 4]
Now we just saw first hand some of how we manipulate Arrays in Ruby. But what if we are curious about what else we can do with an Array? It would be really nice if we could quickly get a list of methods available for my Array. Oh, but we can! Every Ruby object has a methods method that returns an Array populated with the names all the messages it responds to.
irb(main):005:0> a.methods => ["select", "[]=", "inspect", "compact", "<<", "&", "clone", "method", ... (over 100 other methods) ..., "unshift", "sort_by", "to_yaml_properties", "fill", "max", "is_a?", "uniq!", "[]"]
Oh, that is a lot of methods! My version of Ruby/irb returned 128 methods for the object, and they are hard to read all mixed up like that. Good thing we can sort them, too:
irb(main):006:0> a.methods.sort => ["&", "*", "+", "-", "<<", "<=>", "==", "===", ... (over 100 other methods) ..., "uniq", "uniq!", "unshift", "untaint", "values_at", "yaml_initialize", "zip", "|"]
By scanning the methods available to an object you can get an idea of what you can do with it before you even look at proper documentation (which you want to have handy, too). Using the methods method from irb is also a fast way to recall the name of a method if you forget it and your text editor or IDE does not help you figure it out. I sometimes just try out methods unknown to me just to see what happens, and then I check the documentation shortly thereafter to ensure I understand it.
The most important aspect of irb that enabled me to learn Ruby and keep up with changes in the language was the ability to vet out short bits of code before putting them into a program. For example, if I need to ensure a complicated regular expression will match what I want it to, I can do the initial testing in irb. Then those tests done in irb that supply confidence that the regular expression is correct are copied into the unit tests. Here is a simple example to illustrate the idea:
irb(main):007:0> 'foo bar baz' =~ /\/ => nil
Oops! I expected an Integer result, which would denote there was a match. However, I forgot I was working in Ruby instead of an old version of grep, and the notations denoting a word boundary in regular expressions are different between the two. It is easily fixed:
irb(main):008:0> 'foo bar baz' =~ /\bbar\b/ => 4
One other trick I employ in irb is to get a list of currently loaded classes, at least as defined at the top level (i.e. a class within a class or module, like Net::HTTP, will not show up, but Net will and then one could drill down from there). This can be done because every class can be identified by a constant value, and a list of these constants can be obtained from the Object class using the constants class method:
irb(main):009:0> Object.constants.sort => ["ARGF", "ARGV", "ArgumentError", "Array", "BasicSocket", "Bignum", "Binding", "Buffering", ... (over 100 other entries) ..., "UNIXserver", "UNIXsocket", "URI", "UnboundMethod", "VERSION", "YAML", "ZeroDivisionError", "Zlib"]
Not all of the entries returned are classes (e.g. ARGF and ARGV), but it does not hurt to know about the other defined constants, too.
With irb at my disposal learning Ruby was a snap, and it was very fun. If you have not yet had the pleasure of learning Ruby then perhaps irb can make your journey more fun, too. Let me know if you try it out!
]]>irb from the command line (Interactive Ruby is a menu option in the most common Windows Ruby package). One of my most frequent uses of irb is as a calculator:
irb(main):001:0> 1465 + 1723 => 3188
Simple addition is not too exciting, but that’s just the beginning. When Ruby is at your fingertips, the sky is the limit (limited by your imagination, of course). You can sum up a whole list of numbers quickly:
irb(main):002:0> [1, 2, 3, 4, 5, 6].inject(0) { |x, y| x + y }
=> 21
Use variables to store values or add to them:
irb(main):003:0> a = 515 => 515 irb(main):004:0> a += 23 => 538
Or perhaps you need a special function to crunch your numbers today? Just define it, possibly as an instance method for the Array or Integer classes, and then have a blast with it:
irb(main):005:0> class Array
irb(main):006:1> def sum_of_squares
irb(main):007:2> inject(0) { |s, x| s + x * x }
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0> [1, 2, 3, 4, 5, 6].sum_of_squares
=> 91
Take advantage of some mathematical constants! They are available, too, using the Ruby constants shown below.
irb(main):011:0> Math::PI => 3.14159265358979 irb(main):012:0> Math::E => 2.71828182845905
Finally, there is just one thing to note. If you are doing division and want a decimal point in your results then you need to make sure you are using at least one floating point precision number in your statement (otherwise the result is an integer dividend):
irb(main):013:0> 2352.0 / 17 => 138.352941176471 irb(main):014:0> 2352 / 17 => 138
Using irb as a desktop calculator is really just scratching the surface of what one can do, but I think it is a rather cool application of it. If you have never used irb, or even Ruby, go ahead and give it a try! I hope you find it just as useful as I do.
]]>However, today I will do as many other blogs do and point to some interesting content from elsewhere that I recently came across. There are two recent articles by Nate Lawson that are very interesting; you may find them here and here, and I suggest you read them. They discuss the security of internal system components—hardware security.
As security practitioners continue to struggle with networks and applications, we still have the same issues affecting components of our hardware. The exact same issues, in fact: authorization, authentication, and security versus performance to name a few. I smile at the thought of a conference room somewhere in the bowels of Intel or AMD where engineers and managers discuss threat models and risk equations and make decisions on what to implement and how to implement PC hardware features based on costs and risks in a manner no different than how a web application’s security is discussed at a software company.
]]>
My solution is not very complicated or long at 57 characters (9 of them spaces, 6 of them optional), but it is less than the ideal of the shell providing better support for pipe redirection. I would like to see zsh incorporate the Plan 9 redirection syntax to make this easier. I would have suggested it to them, but I feel like such a suggestion should have a patch attached.
Anyway, go ahead and post answers or potential solutions to the puzzle below in the comments. If you do not want to register for an account you can email your answers or questions to cosine at cosine dot org. I will post noteworthy comments sent to my email below.
]]>
; {puzzle2000 | tee out.log} |[2] tee err.log
This is standard output
This is standard error
; cat out.log
This is standard output
; cat err.log
This is standard error
As seen above, the puzzle2000 script outputs two lines. It outputs “This is standard output” to standard output and “This is standard error” to standard error. The challenge is repeating the above Plan 9 shell functionality using the Bourne shell instead. Back in 2000 it took me about two weeks of throwing ideas around to work out a solution. This is non-trivial because the Bourne shell’s pipe syntax can only connect the pipe from standard output of the first process to standard input of the second. So can you figure out how to extend this functionality? Give it a try!
Please do not post answers or spoilers in the comments of this post. I have set up an additional post to discuss possible answers and to avoid spoiling it for those that want to work out the challenge. I have also provided a little bit of information about my own solution there, and will eventually update that post with the solution itself. Feel free to post your answers in the comments there (do not read them if you do not want to be spoiled!). Also, if you do not want to register for an account you can email your answers or questions to cosine at cosine dot org, and I will post them if they are good (that is, if they would contribute to a positive discussion) even if they are not correct.
Note that I will delete comments below if they are a spoiler or if they discuss possible answers, so please limit the discussion here to clarification about what the challenge is or other general comments.
]]>