nCircle.com >> 360 Security >> VERT

Web Poll

May 22, 2009

Microsoft Enables Drive-By Downloads in Firefox

Chris Sullo has a post out over on the HP Security Labs blog on his experience downloading Google Chrome. He clicked and it was installed... no download prompt, no installer, nothing. I actually experienced it this morning before I left my apartment but in my haste said I'd wait until tonight to explore further. I really thought I was going crazy... I'm glad to know that I'm not, or at least not in this case.

I don't know if horrified is a strong enough word to express how this makes me feel. Shocked, disgusted, sorry I've ever defended Microsoft in the past... these are a few things that come to mind. Not only did they undermine the security of Firefox... they've destroyed my trust in them. How will I ever feel comfortable accepting another Microsoft update (after all, that's how .NET came to be installed on my computer). Had I went and downloaded it... sure, but I didn't I did what we in the security industry tell every individual to do... I installed my available updates. I even reviewed them but there was no note that read "CAUTION: This will decrease the security of your computer".

Microsoft has managed to successfully allow drive-by downloads in Firefox. My skin is crawling... and unfortunately if my wife is at home browsing right now my computer probably is to.

May 19, 2009

Some Thoughts on the OWASP Top Ten

Over the past few weeks, I've been looking at the OWASP Top 10 and thinking back to my time spent as the Sys Admin for a SMB. As the technical resource at the company... web app development also fell on my shoulders. This wasn't simply building the company website, as I worked for a marketing company this included full blown web applications for clients. Now prior to joining nCircle, I lived and breathed security... it was (and still is) my passion. This isn't the case for Sys Admins and developers at other SMBs and even larger enterprises. Security is often an afterthought.... sometimes a "way-afterthought". For these people, the ultimate resource to turn to is the OWASP Top 10, the ten most pressing concerns in web application security decided on by experts in the industry. The OWASP Top 10 "represents a broad consensus about what the most critical web application security flaws are" and the people at OWASP "urge all companies to adopt this awareness document within their organization and start the process of ensuring that their web applications do not contain these flaws." I don't disagree with this, if everyone takes the steps to prevent these flaws, we'll have a safer online world.

That being said, given the OWASP stated purpose of the Top 10, I don't feel that it is written to best represent everyone who uses it. The Top 10 often feels as though it is written by industry experts for the rest of the industry. This isn't, in my mind, what the document was intended to do. The Top 10 may be referred to by pen testers or web application researchers to reference, but it's primary goal is to raise awareness and provide assistance to developers. Many of these developers aren't security oriented and simply write code... look at the colleges and universities, they have programs pumping out plenty of web developer grads who have never seen a course on secure coding. Usability is number one is many of their projects. It is these people that I feel the Top 10 fails... it doesn't give them something they can easily work off and to me that should be the primary goal of a project such as this.

Let's take a look at two scenarios.

Scenario #1

Imagine you work for a small marketing company with less than 30 employees. You are the sys admin with all the regular sys admin duties, however you are also tasked with the responsibility of building web applications and/or web sites for customers and for use within the company. You have limited time and take the OWASP Top 10 as your guide to securing the application you are building. You aren't security oriented and someone pointed you toward the document. If you first tackle A1 (XSS) you'll read the following: "Cross-site scripting, better known as XSS, is in fact a subset of HTML injection. XSS is the most prevalent and pernicious web application security issue. XSS flaws occur whenever an application takes data that originated from a user and sends it to a web browser without first validating or encoding that content." You follow the advice of "Ensure output is passed through htmlentities() or htmlspecialchars()" and continue on to the next line item A2 (Injection Flaws).

Here you read this description, "Injection flaws, particularly SQL injection, are unfortunately very common in web applications. There are many types of injections: SQL, Hibernate Query Language (HQL), LDAP, XPath, XQuery, XSLT, HTML, XML, OS command injection and many more." As stated you aren't a security person, this is a job that you ended up in but one of the things you notice is the mention of HTML Injection. Why does that sound familiar? Oh yeah, A1 was a subset of HTML Injection... well I've protected against A1, that must mean I'm good here and you move on to A3. STOP! How about we look at the other types of injection (perhaps SQL Injection) and protect against those as well. Right now, reading this, you are thinking that no one would ever do that... but it happens. Now why does it happen?

A1 is XSS and A2 is Injection Flaws. XSS is a subset of HTML injection which is a child of Injection Flaws, yet it's also been made a peer of Injection Flaws. There is a logic flaw that exists here and it is enough to cause confusion for many people.

Scenario #2

Now let's imagine that you are an enterprise with separate teams for Development, System Management and Security Auditing. Company policy states that audits must be done before Web Applications go into production and again immediately after going into production. The criteria for the audit is defined by the OWASP Top 10. Development and QA have done their part and the application is audited internally. The application passes audit (no vulnerabilities according to the Top 10) and sent off to System Management for deployment. The system is deployed and a follow-up audit is performed. Again no issues are found and the web app is live. Two months later a report comes in that your web app has been blacklist for serving malware. An investigation ensues and sure enough, live malware is being distributed... the website is pulled down and forensic investigation reveals that a flaw in the server software was used to upload malware to the server. If the auditing team had been using the 2004 edition of the Top 10, they would have discovered this flaw, however Insecure Server Configuration was removed from the 2007 edition of the list.

Now as I said, I've been considering the Top 10 for quite some time, and both of these potential situations have caused me some concern. Last week I started to consider this write-up on the subject and instead decided to contact the Top 10 mailing list to discuss these issues. While the readdition of Insecure Server Configuration seems to have been well received the problem that I see in XSS and Injection Flaws has not. I understand that the people responsible for this list are considered industry experts and I don't meant to slight anyone by making the suggestion that the current list is flawed. That being said, since a new version of the list is planned, that means the current iteration isn't perfect and that there is room for improvement. I believe that this area is one of the areas where improvement can be achieved, but I'm not so full of myself to think that because I believe it, it must be true.

I fully understand that in the past, it made sense to distinguish between XSS and SQL Injection, they were two major issues that needed recognition. I'm not sure though that the categories XSS and Injection Flaws properly represent the issues at hand. With more and more people referencing the Top 10 and the PCI Security Council leaning heavily on it to define web related portions of the PCI-DSS, I feel we need to make it as clear and concise as possible.

That being said, there are three ideas that I feel more properly describe this situation:

1) Drop Injection Flaws from the list, if the important items are XSS and SQL Injection and we don't want to combine them for fear of a loss of importance, then why lump SQL Injection in with anything. XSS and HTML Injection are closer than SQL Injection and HTML Injection yet they are not defined in that way. So A1 would be XSS and A2 would become SQL Injection.

2) Merge XSS into Injection Flaws. Make Injection Flaws A1, leaving A2 open for the current "risk de jour" and lump them together in a way that makes them technically accurate and easier to understand.

3) Create the OWASP Top 20, or two separate Top 10 lists. One that identifies the buckets of larger groupings (Injection Flaws) and the other identifies the specific vulnerability classes (XSS, SQL Injection, etc).

As I said, this didn't receive the warmest welcome on the OWASP Top 10 list, but I can't help but wonder if it's a matter of the experts not being able to place themselves in the shoes of the people using the list. This is a common and easily made mistake in our industry, we become so comfortable and familiar with the material that while it makes sense within our own grouping, we forget that the material needs to be referenced and acknowledged by people that don't live with our mindset.

March 17, 2009

Off to CanSecWest

Just wanted to let everyone know that I'm off to CanSecWest for the remainder of the week. If you're going to be there and want to talk security, nCircle, VERT or anything really... Feel free to track me down. You can also ping me on twitter (@treguly).

March 15, 2009

Patchigation: How much do you want to know?

Recently Microsoft released a blog post addressing MS09-008, after I raised an issue with it. I think it's clear where my colleagues and I stand on the issue, but here's a quick summary for those who haven't been following ...

The MS09-008 "patch" provides the functionality to apply a mitigation (Global Query Block List) and the application of the mitigation. One of my colleagues even coined the term "patchigation", since the issue is never actually patched. To patch the issue Microsoft would have had to block the ability to set wpad and isatap entries dynamically and they chose not to do this. Instead they have mitigated the risk of a malicious entry by providing a method of blocking the valid response from being sent.

So where does that leave us?

  • Before Patchigation
    1. Attacker sends Dynamic Update to set the wpad entry to a malicious target
    2. DNS Stores wpad entry
    3. Victim queries DNS and is provided the malicious wpad entry
  • After Patchigation
    1. Attacker sends Dynamic Update to set the wpad entry to a malicious target
    2. DNS Stores wpad entry
    3. Victim queries DNS and is told the address doesn't exist
  • After a proper Patch (which isn't available)
    1. Attacker sends Dynamic Update to set the wpad entry to a malicious target
    2. DNS Rejects wpad entry
The reason I originally brought this issue to light was because Microsoft chose function over security and decided that if a wpad entry already existed, the mitigation should not be applied. So we can actually break out 'After Patchigation' into "wpad" and "no wpad" .
  • After Patchigation - no wpad
    1. Attacker sends Dynamic Update to set the wpad entry to a malicious target
    2. DNS Stores wpad entry
    3. Victim queries DNS and is told the address doesn't exist
  • After Patchigation - wpad (valid or malicious)
    1. Attacker sends Dynamic Update to set the wpad entry to a malicious target
    2. DNS Stores wpad entry
    3. Victim queries DNS and is provided the malicious wpad entry

But I thought I was patched? Why didn't Microsoft inform me about this?

To be fair, Microsoft did provide information about this (strictly speaking) - the advisory contains a Known Issues link that points to a knowledge base and that knowledge base contains a single line, halfway down the page to inform you that wpad and isatap entries won't be created if they existed prior to the host being patchigated. It's not directly referenced in the advisory, and the Known Issues" link wasn't added until after I contacted Microsoft and wrote my initial blog post, but I digress ...

Microsoft has since commented that it is not the goal of an update to undo an attack that has already taken place and that customers are encouraged to apply the update. I do not believe they should aim to undo previous attacks and I firmly believe that customers should apply the update. The update addresses more than the WPAD issue and we have encouraged our customers to apply the update from the time it was released.

I do, however, believe that this practice of patchigation is a dangerous practice. By burying a packaged mitigation within the monthly patches, Microsoft leaves customers who have already been compromised with a false sense of security that there is no problem. As I've said many times in the past, I'm a big fan of Microsoft's Security Program in general. As a Security Researcher however, my appreciation has to take a back seat to exposing risks as I find them. This one is risky, I found it, and I exposed it.

Microsoft has also stated that no previous patch has ever undone an attack. This is not the first time I've heard the argument that patches are not aimed at undoing an attack, and I feel the need to be clear - I do not expect a Microsoft patch to undo an attack, I expect a Microsoft patch to effectively prevent future attacks. This patchigation does not do that.

If a wpad entry exists, the mitigation is not applied. Since the patch and mitigation are one and the same, that means that the issue is not actually remediated. It's not a matter of undoing the single attack that's taken place already, it's an issue of not preventing future attacks. This same issue holds true for organizations with valid wpad entries, the mitigation isn't applied (as Microsoft has indicated, there's no way of knowing if an entry is valid or not) and therefore future attacks can occur. So this isn't about undoing a single attack, this is about preventing future attacks. I suspect customers' expectations are the same as mine: once I'm patched, I'm immune to future attacks.

So I put the question to you: Is patchigation good enough? Whether you think it is or think it isn't, how much do you want to know?

March 11, 2009

Functionality Versus Security - Who Wins?

I wanted to share the response that I received from Microsoft and provide some of my own feedback. I must admit that I was initially floored by their response, which was:

"Thanks for bringing this to our attention. While I understand your concern, this is in fact expected functionality of the security update."

[removed discussion of issue]

There are important reasons why this path was chosen: it is not possible to tell legitimate WPAD entries from illegitimate ones that were loaded by attackers. Hence our need to accept an already "existent" entry as being valid.

They also pointed me to a KB that references this issue. What's interesting is that this KB wasn't referenced in the advisory release; it was added today as a 'Minor Update'

V1.1 (March 11, 2009): Clarified that CVE-2009-0093 does not apply to supported editions of Windows Server 2008. Added a link to Microsoft Knowledge Base Article 962238 under Known Issues in the Executive Summary. Clarified what systems are primarily at risk for CVE-2009-2033. Finally, updated a finder acknowledgment for CVE-2009-0233 and CVE-2009-0234.

I was then asked in future to wait for a response from them before having such discussions publicly. Anyone who knows me knows that I fully support contacting the vendor when you have a newly discovered vulnerability and I've always reported my findings to Microsoft first. In this case, however:

  1. This was not a newly discovered vulnerability. How to exploit the vulnerability was already public knowledge.
  2. This public discussion did not benefit malicious individuals. It did, however, raise some awareness with Microsoft's customers who may believe they are adequately protected when they are not.

So why was I floored by Microsoft's response? They didn't actually patch this vulnerability; instead they introduced a means of mitigation and deployed that mitigation in the update. That alone would be fine. The issue I have is that they have punted security altogether in the interest of functionality. The responsible thing to do would be to find a balance between the two.

There are a number of approaches that Microsoft could have taken here, that they chose not to take:

  1. Provide a simple message during installation of the patch, notifying the user of existing wpad or isatap entries in the DNS server zones and informing them that the intended mitigation would not be applied.
  2. Modify the way that dynamic updates work to provide a dynamic update block list, restricting wpad or isatap from being updated dynamically. As it stands right now you can still submit updates for these, they just wont be resolved if they exist in the global query block list.
  3. Add both entries to the global query block list and allow users to go back and remove them if the functionality was required.
  4. Bring this case to the public as part of the original Advisory if they already knew about it.

These are quick examples from a long list of alternative approaches that could have been taken - each of which would have provided more responsible guidance to their customers than the "don't ask; don't tell" method that they chose.

I'm probably the the biggest Microsoft supporter within VERT. I'm a huge fan of the work they've done to improve security across the board. That being said, I can't help but see this as a step backwards. I understand the need to preserve functionality, but not at the cost of sweeping security issues under the rug. Simply providing a comment within the original advisory would have been a step forward. Instead, no notification was provided to their customers until after I had brought the issue to their attention. Even then, the response was a single line linking to a KB. That KB contains a list of other KBs and one of those contains a single line indicating that this may occur. This suggests that Microsoft was aware of this issue and released their update with minimal concern for security. I believe their customers deserve more.

Earlier today, Larry Seltzer commented that "Microsoft updates don't undo exploits". This is 100% true; however undoing the exploit in this case would be reverting a configured wpad/isatap entry. I'm not asking Microsoft to undo exploits; I'm simply asking that they provide the mitigation that their advisory claims it will provide or proactively advise customers that a particular risk has been accepted on their behalf.

In this case, they provided neither guidance nor remediation.

Winner: functionality by technical knock out.

March 10, 2009

Successful Exploit Renders Microsoft Patch Ineffective

Patch Tuesday can be a long night for a VERT Engineer. With nCircle's 24-hour Patch Tuesday SLA, we work long hours to ensure our customers get the best detection available. These nights are usually filled with coffee, bad jokes and really bad music. Tonight was a little different... as it included a cool yet disturbing discovery. The discovery was that the patch for MS09-008 is highly flawed in it's patching of CVE-2009-0093.

This vulnerability allows users to set a WPAD entry in DNS when dynamic updates are enabled. Internet Explorer, configured to "Automatically Detect Settings", will query for this WPAD value and attempt to download proxy settings from the associated server. This could allow an attacker to Man-in-the-Middle the connection.

The flaw that I discovered is with servers that have already been exploited – in that compromised servers will already contain a WPAD entry. I initially thought, "No Problem! The block list will keep me from getting a response," but I’m a researcher, so I had to be sure.

It turns out that this isn't the case. Instead, the patch checks to see which entries have been created in the DNS server and *only adds block list entries for values not already being served*. In other words, if your DNS server contains an entry for WPAD and you apply MS09-008, the block list will not have WPAD added to it. Subsequent queries for WPAD will continue to be answered and if the WPAD entry is from a previous attack, your users will continue to be Man-in-the-Middled - even after you are patched.

This has serious consequences, as enterprises may mistakenly believe that this vulnerability has been remediated on compromised servers. After all, the patch appears in the 'Remove Programs' dialog and the patch registry keys are created. As a result patch management solutions and Microsoft’s Automatic Update service will likely report incorrectly that the patch has been successfully applied.

To verify that you are indeed effectively patched:
Check that HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DNS\Parameters\GlobalQueryBlockList contains both 'wpad' and 'isatap'

Note: Although WINS also makes use of a query block list (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WINS\Parameters\QueryBlockList) WINS is not affected by this issue.

We have contacted Microsoft to notify them of this issue and are awaiting a response. VERT’s checks confirm that the vulnerability has been effectively remediated. If you’re not an nCircle customer, follow up with your vendor to ensure that they are checking for more than just the presence of the patch.

January 30, 2009

Where PCI Fails

Anton Chuvakin has an interesting post up on how PCI could have possibly failed in the Heartland issue. I had initially planned to avoid talking about Heartland has it has been blogged to death, resurrected and blogged to death again.

Anton gives 5 possibilities as to what could have happened and they are (summarized):

  • 1. Bad QSA
  • 2. Compliant but a password was set to something simple following the tests
  • 3. Non-Compliant but begged for a card brand to say they were OK
  • 4. Compliant but hit with malware that bypassed PCI-Mandated Controls
  • 5. Compliant but an employee walked out with the data.

After laying out 5 possible options, Anton asks (rhetorically) for comments on "which of these cases indicates that "PCI failed"". I almost commented on his blog but decided instead to write a blog post. I disagree with his opinion that none of these are PCI failures.

I don't know that PCI can (realistically) do much about #2, #4 and #5, but I do believe that PCI has failed if #1 or #3 is the case. I should preface this by saying that I'm a huge supporter of PCI-DSS. While the program may not be enough on its own, it's a start and a start is what we need right now.

The fact that card brands are ultimately responsible for certification is a problem, and ultimately this is a failure on the program ... period. No exceptions, No Mulligans ... do not pass Go, do not collect $200. What good is a certification if the certification group is off to the side and doesn't preside over the final decisions. It reminds me of the various IT/IS certifications and how there are two camps with nearly a 50/50 split on their usefulness, and worse yet, it creates too many "not my jurisdiction" cracks for things to fall through. The SSC creates the DSS and trains/certifies Assessors to audit against a supposedly objective standard that is subjectively governed by 5 different Card brands.

Now the bigger issue (in my mind) ... the "Bad QSA". The existence of "easy grader", "we just look at the docs", "pay per compliance" QSAs is definitely evidence of a PCI failure. QSA FAIL. PCI SSC FAIL. PCI PROGRAM FAIL. This is one of the reasons why "PCI" struggles to be taken seriously by the Security community. nCircle is a certified ASV (I don't think that's a secret (if it is... well now you know :) )). I'm actively involved in the preparation, completion, and ongoing maintenance of our certification. We invest a lot of time and energy to ensure we're as good as we can possibly be ... because we feel that it's important. Subpar audits are not acceptable. If you are barely hitting your mark as an ASV or QSA, you should be gone.

So in the end, yes... there are scenarios proposed by Anton where PCI fails, but that doesn't mean we should disregard PCI or throw it away. It means we should work to solve these problems and evolve the standard to something that works. As long as we in the community give the PCI Security Program a free pass when it falls down, we become a part of the reason for its failures. Criminal and Civil Codes exist so citizens, law-makers, police, judges and lawyers have a common understanding. The PCI Security Program has not yet evolved to provide this common understanding and until it does, there will continue to be instances of PCI FAIL.

December 16, 2008

The IE Vuln & A Monthly Patch Release Process

As I'm sure everyone has heard by now that there's an IE 0-day floating around. The result of this 0day is that some people are questioning if the monthly MS Tuesday is really a good idea these days. The alternative is that patches could be released as soon as they are available.

I'm still of the opinion that MS Tuesday is the right way to approach the issue. We've seen other large enterprise vendors follow in Microsoft's footsteps. I'd say there are two main reasons to keep a monthly patch cycle. The first is for system administrators and their already hectic lives. Imagine if patches were released randomly as they were ready. This year saw 77 bulletins for Microsoft products. If they were "released as ready" that would have resulted in more than a bulletin a week... and we're talking about the bulletins, what if each patch was "released as ready". For example, what if every IE vuln was patched individually, or each Office vuln? This month's advisories patched 28 unique CVEs... that's almost one a day over the course of the month. It would be unreasonable to ask admins to maintain a respectable level of patch status.

My second reason is related to consumers. We constantly see reports of unpatched boxes and users who dislike the patching process. If Windows Update starts offering daily or weekly patches, end users are going to give up on patching. It will become a chore for them.

Yet many people want patches as quickly as possible, so how do we solve this problem? Why couldn't the solution be a public beta patch program? I know Microsoft has a patch beta program that enterprises with large deployments can get involved with, people who have the labs to provide feedback on a larger scale. This would be more consumer / small business focused, since they don't qualify for Microsoft's current beta patch program. Although, that's not to say that enterprises couldn't choose to go this route instead. Interested parties can sign up to download the patches themselves. These patches would be available after development and before Microsoft begins QA (or perhaps after initial QA, this point could be decided on in the future).

Admins who want to test serious issues in their labs to ensure a faster rollout once the official patch is released could choose to do so. End users who have been calling out Microsoft for not releasing patches more quickly and for sticking to their monthly schedule, could download these beta patches and make use of them.

Now... I can hear the argument already. Malicious individuals will download the beta patches and reverse them to find the vulnerability. This is true, I'm not going to argue it but they're finding the vulnerabilities right now and making use of them. Perhaps this public beta program is only used for already public vulnerabilities or perhaps we look at the alternatives. To flesh this out a little further... the bad guys will always find the vulnerabilities. Whether they find them today or tomorrow is of little difference, they will find them and somebody will be unpatched. The best we can do is hope to protect as many people as possible. With actively exploited vulnerabilities, I propose that the answer is a beta patch program such as this one.

As I said, maybe that isn't the case with private vulnerabilities. Since they sit quietly without being discovered, sometimes for months on end. However, if it's a choice between a beta program and "release as ready", I would prefer the beta program. It gives users a choice without making the end user feel pressured to patch. If there's valid reason for an out of band advisory (MS08-067 for example) then by all means release it, however we have to weigh the security of the end user with the capability of the end user.

If we make the move to 'release as ready' administrators will have major backlogs and consumers will ignore patches. So the malicious individual will reverse the patch and still have plenty of viable targets. I believe that 'release as ready' is no less dangerous than a public beta program and there's more benefit to the public beta program.

I'm sure that someone somewhere is saying "release as ready" is the same as the beta program, in that people can get the patches earlier than with a scheduled monthly release. This is true... and when I think 'people', I'm thinking hackers. If the "hackers" reverse the beta patch and produce an exploit, then we have an active exploited vulnerability without an official patch and this is a problem. Then again, it's not unlike having a ZERT patch... in fact I consider ZERT to be evidence that a public beta patch program is a good idea. But let's look go back and look at the "release as ready" idea through the eyes of the consumer though.

I come home from work, sit down to use my computer and that little yellow icon is telling me I have updates waiting to be installed. I click install, start typing emails and 5 minutes later I'm told I have to reboot. I save my work, reboot, wait for my computer to come back on, log in, wait for my software to load (I know... you're getting impatient reading this sentence but imagine if you're this end user) and finally I'm back to work typing that same email. Now imagine that this happens more than once a week. What is that end user going to do? They're going to get fed up and disable automatic updates. Now we have a user that is less secure than they were on the monthly update cycle... because once a month they could handle, but this weekly (or even daily) process is unbearable. At this point we have a worse situation then we did with a monthly patch release and a beta patch program.

So in the end, the Pros and Cons of a Public Beta Patch Program are:

Pros:
Monthly Update Cycle is maintained.
Patches are available to those that desire them.
We don't inundate the end user with patch releases.

Cons:
Malicious Individuals could determine the vulnerable condition

As I said though, I believe this con exists with the 'release as ready' program as well, yet it doesn't have the potential pros. That being said, I'm definitely for the idea. Thoughts, Opinions and Comments from others?

December 1, 2008

A Great Way To Start a Monday

photo.jpg


Thankfully it's been resolved :)

November 11, 2008

super is as super does

The other day one of my co-workers (hi Bob!) reviewed a tricky bit of Python code that I had written and asked why I was explicitly calling <BaseClass>.<method> instead of using 'super'. And my immediate answer (to myself, since Bob had gone offline) was 'I never use super, super is bad'.

However, that comment got me thinking, why don't I use Python's built-in super? Well, I knew why, back when I was getting started with Python I read an article called "Python's Super Considered Harmful" (by James Knight) and made a mental note to myself to never use it. End of story, I never re-examined that decision and I suspect that I may have passed this 'wisdom' on to others.

So here it is two years and several thousand lines of Python later, I went back and re-read the article. With a more experienced eye I found a number of points that (in my opinion) were somewhat subjective conclusions about the merits and risks of super. I also found the following discussion relating to the article between the Mr. Knight and GvR (if you don't want to read the whole thread, the summary is GvR rebuts the assertion that super is in fact the problem). I also found an extensive description of when and how to correctly use super.

However, after all that reading, I had a new question that I didn't know the answer to: In a new style base class (e.g. one that inherits directly from object), is it necessary or beneficial to __init__ the parent class? For example:

class A( object ):
    def __init__( self, *args, **kwargs )
        super( A, self ).__init__( *args, **kwargs )   # Do I need to do this?

The official documentation is not clear (at least to me) on this issue. There are many examples of classes which do not make this call.

You'd think it would be explained here, but it's not really addressed. There is a discussion in this bug which suggests to me that it isn't something that is always addressed.

The best treatment of this issue that I have found is in the link I posted above, which states "Note that in the first case M's call to super is critical to allowing the rest of the init calls to happen, even though its superclass is object." But their example doesn't really state why it is critical, so I played with it for a bit. My first try was this:

class A( object ):
    def __init__( self, *args, **kwargs ):
        super( A, self ).__init__( *args, **kwargs)
        print 'A'
class B( A ):
    def __init__( self, *args, **kwargs ):
        super( B, self ).__init__( *args, **kwargs)
        print 'B'
class C( A ):
    def __init__( self, *args, **kwargs ):
        super( C, self ).__init__( *args, **kwargs)
        print 'C'
class D( B, C ):
    def __init__( self, *args, **kwargs ):
        super( D, self ).__init__( *args, **kwargs)
        print 'D'
>>> print D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'> )
>>> d = D()
A
C
B
D

Okay... so what happens if A's call to super is commented out?

>>> print D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'> )
>>> d = D()
A
C
B
D

Nothing! So it doesn't matter, right? Well... then why did the Chandler Project article say it was critical? Their inheritance example was a little more complex, involving two paths of inheritance from object:

class M(object):
  """ Mixin class """
  def __init__(self, *args, **kwds):
    print 'init.M'
    super(M, self).__init__(*args, **kwds)
class B(object):
  """ Base class """
  def __init__(self, *args, **kwds):
    print 'init.B'
    super(B, self).__init__(*args, **kwds)
class D(B):
  """ Derived class """
  def __init__(self, *args, **kwds):
    print 'init.D'
    super(D, self).__init__(*args, **kwds)
class CL(M, D):
  """ Class Left """
  def __init__(self, *args, **kwds):
    print 'init.CL'
    super(CL, self).__init__(*args, **kwds)
>>> print CL.__mro__
( <class '__main__.CL'>, <class '__main__.M'>, <class '__main__.D'>, <class '__main__.B'>, <type 'object'> )
>>> cl = CL()
init.CL
init.M
init.D
init.B

So what if we change the definition of M to this (and redefine the others unchanged):

class M(object):
  """ Mixin class """
  def __init__(self, *args, **kwds):
    print 'init.M'
    #super(M, self).__init__(*args, **kwds)
>>> print CL.__mro__
( <class '__main__.CL'>, <class '__main__.M'>, <class '__main__.D'>, <class '__main__.B'>, <type 'object'> )
>>> cl = CL()
init.CL
init.M

WOAH!!!! The MRO is the same, but the cooperative calling fails! The init methods of D and B are never called! Yikes. GvR talks about the cooperative calling pattern here, but he doesn't really get into the pitfalls of it. So I can't say exactly why, from an internals point of view the cooperative calling fails, except that I think it essentially falls back to the old-style class "first found" approach in the absence of the call to object.__init__.

So one more thing then, is invoking object.__init__ directly the same as invoking it via a call to super( cls, self ).__init__ where cls is a direct child of object? The answer is, to my surprise, no.

I redefined the M class from the Chandler Project example like this and reran the previous test.

class M(object):
  def __init__(self, *args, **kwds):
    print 'init.M'
    object.__init__(self, *args, **kwds)

The result was the same as if the super call was commented out!

>>> print CL.__mro__
( <class '__main__.CL'>, <class '__main__.M'>, <class '__main__.D'>, <class '__main__.B'>, <type 'object'> )
>>> cl = CL()
init.CL
init.M

Bottom line: be aware of the differences between "new style" and "old style" classes. Since "old style" classes are going away in Python , it's probably a good idea to get into the habit of making consistent and correct use of "new style" classes to avoid unpleasant surprises in complex inheritance situations.

-Ross

Bio

Blog: VERT
Author: nCircle VERT

nCircle VERT is the research team behind nCircle, continuously publishing updates for nCircle IP360 and nCircle's family of products. VERT conducts deep research across a broad class of network security intelligence, creating unique, agentless detection for: vunerabilities, host configurations, applications, services, user accounts, operating systems, and other network security conditions. Members of the group use this blog to share their opinions on the security industry, emerging threats, technology trends, and the world at large.

Categories