May 04, 2013
And on a completely unrelated note...
Some harmless, old-fashioned fun with CSS
- It's not particularly outlandish or constrained - at least compared to the earlier PoCs with CAPTCHAs or chess boards.
- It collects information without breaking immersion. This is done by alternating between "real" and "probe" asteroids. The real ones are always visible and are targeted at the spaceship; if you don't take them down, the game ends. The "probe" asteroids, which may or may not be visible to the user depending on browsing history, seem as if they are headed for the spaceship, too - but if not intercepted, they miss it by a whisker.
- It is remarkably high-bandwidth. Although the PoC tests only a handful of sites, it's possible to test hundreds of URLs in parallel by generating a very high number of "probe" asteroids at once. A typical user visits only a relatively small and uniformly distributed number of websites from any sufficiently large data set, so only a tiny fraction of probes would be visible on the screen. In fact, the testing could be easily rate-limited based on how frantic user's mouse movements have been in the past second or so.
- It's pretty reliable due to the built-in "corrective mechanisms" for poor players.
February 20, 2013
Firefox: HTTPS and response code 407
CONNECT request with a plain-text message such as this:
Hi, mom!
[...additional padding follows...]February 14, 2013
Boring non-security updates strike again!
- An article on 3D printing that I have written for MAKE. It's an attempt to take a more balanced look at the current prospects of home manufacturing.
- Omnibot mkII is a spiffy new robot of my design.
- Last but not least, here's something for photography buffs.
November 16, 2012
Lessons in history
June 08, 2012
May 30, 2012
Yes, you can have fun with downloads
What's the issue, then? Well, it's pretty funny: predictably but not very intuitively, the attacker may initiate such cross-domain navigation not only to point the targeted window to a well-formed HTML document - but also to a resource served with the Content-Disposition: attachment header. In this scenario, the address bar of the targeted window will not be updated at all - but a rogue download prompt will appear on the screen, attached to the targeted document.
Here's an example of how this looks in Chrome; the fake flash11_updater.exe download supposedly served from adobe.com is, in reality, supplied by the attacker:
All the top three browsers are currently vulnerable to this attack; some provide weak cues about the origin of the download, but in all cases, the prompt is attached to the wrong window - and the indicators seem completely inadequate.
You can check out the demo here:
The problem also poses an interesting challenge to sites that frame gadgets, games, or advertisements from third-party sources; even HTML5 sandboxed frames permit the initiation of rogue downloads (oops!).Vendor responses, for the sake of posterity:
- Chrome: reported March 30 (bug 121259). Fix planned, but no specific date set.
- Internet Explorer: reported April 1 (case 12372gd). The vendor will not address the issue with a security patch for any current version of MSIE.
- Firefox: reported March 30 (bug 741050). No commitment to fix at this point.
April 09, 2012
Well, I'm in a bit of a pickle...
So what I wanted to do instead is, once again, annoy the few remaining readers with my hobbyist work. Specifically, I wanted to showcase three things:
- Omnibot, an interesting robot with a reconfigurable drivetrain,
- Cycloidal drive, a mini-project to make an unorthodox type of transmission,
- Adventures in CNC, my semi-humorous summary of my experiences with home manufacturing.
February 12, 2012
It's this time of the year again
January 10, 2012
p0f is back!
December 19, 2011
Notes about the post-XSS world
This collection of notes is a very crude thought experiment in imagining the attack opportunities in a post-XSS world. The startling realization I had by the end of that half-baked effort is that the landscape would not change that much: The hypothetical universal deployment of CSP places some additional constraints on what you can do, but the differences are not as substantial as you may suspect. In that sense, the frameworks are conceptually similar to DEP, stack canaries, or ASLR: They make your life harder, but reliably prevent exploitation far less frequently than we would have thought.
Credit where credit is due: The idea for writing down some of the possible attack scenarios comes from Mario Heiderich and Elie Bursztein, who are aiming to write a more coherent and nuanced academic paper on this topic, complete with vectors of their design, and some very interesting 0-day bugs; I hope to be able to contribute to that work. In the meantime, though, it seems that everybody else is thinking out loud about the same problems - including Devdatta Akhawe and Collin Jackson - so I thought that sharing the current notes may be useful, even if the observations are not particularly groundbreaking.
December 10, 2011
X-Frame-Options, or solving the wrong problem
I have discussed some aspects of this problem in the past: my recent entry showcased an exploit that flips between two unrelated websites so quickly that you can't see it happening; and my earlier geolocation hack leveraged the delay between visual stimulus and premeditated response to attack browser security UIs.
A broader treatment of these problems - something that I consider to be one of the great unsolved problems in browser engineering - is given in "The Tangled Web". But today, I wanted to showcase another crude proof-of-concept illustrating why our response to clickjacking - and the treatment of it as a very narrow challenge specific to mouse clicks and <iframe> tags - is somewhat short-sighted. So, without further ado:
There are more complicated but comprehensive approaches that may make it possible for web applications to ensure that they are given a certain amount of non-disrupted, meaningful screen time; but they are unpopular with browser vendors, and unlikely to fly any time soon.December 08, 2011
The old switcharoo
(If you don't get it, try again, and follow instructions on the screen.)
Interesting results can be also achieved in some browsers with history.back(), but I'll leave this as an exercise for readers. The same goes for the implications it has for clickjacking, drag-and-drop, and other attacks normally associated with frames.
PS. Another silly proof-of-concept as a bonus: click here.
December 02, 2011
CSS :visited may be a bit overrated
:visited selectors in order to prevent websites from stealing your browsing history.
It is widely believed that techniques such as cache timing may theoretically offer comparable insights, but the attacks demonstrated so far seemed unconvincing. Among other faults, they relied on destructive, one-shot testing that altered the state of the examined cache; produced only probabilistic results; and were far too slow and noisy to be practically useful. Consequently, no serious attempts to address the underlying weakness have been made.
My proof of concept is fairly crude, and will fail for a minority of readers; but in my testing, it offers reliable, high-performance, non-destructive cache inspection that blurs the boundary between :visited and all the "less interesting" techniques.
November 15, 2011
"The Tangled Web" is out
Okay, okay, it's official. You can now buy The Tangled Web from Amazon, Barnes & Noble, and all the other usual retailers for around $30. You can also order directly from the publisher, in which case, discount code 939758568 gets you 30% off.
No Starch provides a complimentary, DRM-free PDF, Mobi, and ePub bundle with every paper copy; you can also buy e-book edition separately. Kindle and other third-party formats should be available very soon.
More info about the book itself, including a sample chapter, can be found on this page.
November 04, 2011
In praise of anarchy: metrics are holding you back
Why? I think there are two qualities that make all the difference in our line of work. One of them is adaptability - the capacity to identify and respond to new business circumstances and incremental risks that appear every day. The other is agility - the ability to make changes really fast. Despite its hypnotic allure, perfection is not a practical trait; in fact, I'm tempted to say that it is not that desirable to begin with.
Almost every framework for constructing security metrics is centered around that last pursuit - perfection. It may not seem that way, but it's usually the bottom line: the whole idea is to entice security teams to define more or less static benchmarks of their performance. From that follows the focus on continually improving the readings in order to demonstrate progress.
Many frameworks also promise to advance one's adaptability and agility, but that outcome is very seldom true. These two attributes depend entirely on having bright, inquisitive security engineers thriving in a healthy corporate culture. A dysfunctional organization, or a security team with no technical insight, will find false comfort in a checklist and a set of indicators - but will not be able to competently respond to the threats they need to worry about the most.
A healthy team is no better off: they risk being lulled into complacency by linking their apparent performance to the result of a recurring numerical measurement. It's not that taking measurements is a bad idea; in fact it's an indispensable tool of our trade. But using metrics as long-term performance indicators is a very dangerous path: they do not really tell you how secure you are, because we have absolutely no clue how to compute that. Instead, by focusing on hundreds of trivial and often irrelevant data points, they take your eyes off the new and the unknown.
And this brings me to the other concern: the existence of predefined benchmarks impairs flexibility. Quite simply, yesterday's approach, enshrined in quarterly statistics and hundreds of pages of policy docs, will always overstay it welcome. It's not that the security landscape is constantly undergoing dramatic shifts; but if you don't observe the environment and adjust your course and goals daily, the errors do accumulate... until there is no going back.
October 28, 2011
Good news, everyone!
No Starch Press just posted a sample chapter for The Tangled Web. You can grab the PDF here and see what it's all about. The book itself should be available by November 15; you can also preorder on Amazon.
If you don't know what this is all about, you can also head over to the home page of the book; but the bottom line is that I think it's the first-ever reasonably detailed examination of the browser security model and its evolution through the years - and really, that's something you just need to know to develop modern web apps.
PS. It's apparently always April Fools' at Microsoft!
October 02, 2011
An origin is forever
The Internet is a pretty seedy place, yet we are quite willing to hand over our secrets to a small group or trusted web apps. Heck, in recent years, we also started giving them capabilities: social networking sites often get to see your geolocation, and your instant messenger may be able to access your microphone or webcam feeds. Some of this does not even require your initial consent: certain browsers and plugins come with hardcoded domains that are permitted to install software updates, or change system settings at a whim.
The push toward web application capabilities is somewhat frightening once you realize that the boundaries between web applications are very poorly defined, and that nobody is trying to solve that uncomfortable problem first. Look at the scoping rules for JavaScript DOM access, for HTTP cookies, and for auxiliary mechanisms such as password managers: they not only differ substantially, but routinely interfere with each other in destructive ways. Compartmentalizing complex web applications should be a breeze, but instead, it's an impenetrable form of art.
Worse, content isolation on the web is very superficial - so even if the boundaries can be drawn, most types of privileged contexts can't distance themselves from the rest of the world, and expose just a handful of well-defined APIs. Instead, every non-trivial web application needs to heavily compensate for the risk of clickjacking, cross-request forgery, reflected cross-site scripting, and dozens of other attacks of that sort. All the developers eventually fail, by the way: show me a domain with no history of XSS, and I will show you a web application nobody cares about.
Unlike some other tough challenges in browser engineering, the risks of living with privileged applications could mitigated fairly nicely simply by requiring some effort up front: even without inventing any new security mechanisms, you could require applications to use origin cookies, have a sensible CSP policy, and use HSTS, before being allowed to prompt for extra privileges. It's not impossible to do something meaningful - it's just unpopular with the creators of privileged APIs.
But the problems with the clarity of robustness of application boundaries aside, there is also a third, perhaps more fascinating issue: what do you do if your web application execution context becomes corrupted in some way? As it turns out, there is no mechanism for the server to say that from now on, it wants to have a clean slate, and that the browser should drop or at least isolate any already running code, or previously stored data.
This seemingly odd wish is actually critical to web application security. For example, let's assume there is an XSS vulnerability in a web mail system or a social networking application. Because of the convenient but unfortunate design of HTML, such vulnerabilities are unavoidable, but we seldom wonder if it's possible to cleanly and predictably recover from them. Intuitively, patching the underlying bug, invalidating session cookies, and perhaps forcing password change, is all it should take; in fact, applications using httponly cookies can often skip the last two steps.
Alas, an once-compromised web origin can stay tainted indefinitely. At the very minimum, the attacker is in full control for as long as the user keeps the once-affected website open in any browser window; with the advent of portable computers, it is not uncommon for users to keep a single commonly used website open for weeks. During that period, there is nothing the legitimate owner of the site can do - and in fact, there is no robust way to gauge if the infection is still going on. And hey, it gets better: if content from the compromised origin is commonly embedded on third-party pages (think syndicated "like" buttons or advertisements), with some luck, attacker's JavaScript may become practically invincible, surviving closing the original application and the deletion of browser cache. If that doesn't give you a pause, it should.
And let's not forget open wireless networks: the problem there is about as bad. It does not matter that you are not logged into anything sensitive while visiting Starbucks. An invisible frame, a strategic write to localStorage, or a bit of DNS or cache poisoning, is all it takes for the attacker to automatically elevate his privileges the moment you return to a safe environment and log back in.
With all that, and with the proliferation of mechanisms such as web workers and offline apps, we are rapidly approaching a point where recovering from a trivial XSS bug and other common web security lapses is getting almost as punishing as recovering from RCE - and for no good reason, too. Sure: today, it's so easy to phish users or exploit real RCE bugs, that backdooring web origins is not worth the effort. But in a not-too-distant future, that balance may shift.
September 09, 2011
Critical (of) severity
I think that one of the cornerstones of vulnerability management is just an example of that. I am talking about the concept of vulnerability severities: I believe that they serve no real purpose, other than obfuscating the true intent of speech.
It's not that we don't need a codified taxonomy; but the term "severity" and the abstract levels attached to it ("critical", "high", "medium", "low") are a remarkably poor proxy for what we actually want to say.
The notion of severity is used in two distinct settings:
- In a position of authority: For example, when an internal security team is communicating with developers. In this case, the intent of assigning severity is to instruct the developer to do one of the following:
- Drop all other work and fix the bug now.
- Fix the issue in a couple of days.
- Fix at own leisure, or not at all.
- In an advisory position: Say, when a vendor is notifying end users about the availability of a fix. In this case, the actual message usually is any of the following:
- You are in imminent danger. Patch now.
- You are at a limited risk, but prompt action is advisable.
- We don't think there is a substantial risk.
Only we're not running a numbers station: we're trying to tell people something very important, and we need them to understand us right away. There is no way around the fact that terms such as "critical" or "high" intuitively mean different things to different people, and almost certainly not just the thing you actually wanted to say. If the severity needs to be accompanied with several pages of organization-specific explanatory text, something is horribly wrong.
Instead of "highly critical", just start telling your users "patch right away".
August 29, 2011
So you want to write a security book?
- You will not get professional editorial feedback. Having an independent sanity check from a person who publishes books for a living helps you set the style and flow of the chapters, and arrange them reasonably. This is harder than it seems. Even the best ideas look bad when presented poorly.
- You will have to take care of technical illustrations, page layout, indexes, and so on - requiring some talent, and easily adding 50-100 hours of work into the mix.
- You will have to pay for technical editing and proofreading - or ship the book with typos and grammar errors, which never helps.
- You will have to invest some effort into marketing, accounting, etc.
August 26, 2011
The subtle / deadly problem with CSP
Content Security Policy is sometimes criticized on the grounds of its complexity, potential performance impact, or its somewhat ill-specified scope - but I suspect that its most significant weakness lies elsewhere. The key issue is that the granularity of CSP is limited to SOP origins: that is, you can permit scripts from http://www1.mysite.com:1234/, or perhaps from a wildcard such as *.mysite.com - but you can't be any more precise. I am fairly certain that in a majority of real-world cases, this will undo many of the apparent benefits of the scheme.
To understand the problem, it is important to note that in modern times, almost every single domain (be it mozilla.org or microsoft.com) hosts dozens of largely separate web applications consisting of hundreds of unrelated scripts - quite often including normally inactive components used for testing and debugging needs. In this setting, CSP will prevent the attacker from directly injecting his own code on the vulnerable page - but will still allow him to put the targeted web application in a dangerously inconsistent state, simply by loading select existing scripts in the incorrect context or in an unusual sequence. The history of vulnerabilities in non-web software strongly implies that program state corruption flaws will be exploitable more often than we may be inclined to suspect.
Content-Type for any CSP-controlled scripts - but even this approach may be insufficient. That's because of the exceedingly common practice of offering publicly-reachable JSONP interfaces for which the caller has the ability to specify the name of the callback function, e.g.:
GET /store_locator_api.cgi?zip=90210&callback=myResultParser HTTP/1.0
...
HTTP/1.0 200 OK
Content-Type: application/x-javascript
...
myResultParser({ "store_name": "Spacely Space Sprockets",
"street": ... });
Having such an API anywhere within a CSP-permitted origin is a sudden risk, and may be trivially leveraged by the attacker to call arbitrary functions in the code (perhaps with attacker-dependent parameters, too). Worse yet, if the callback string is not constrained to alphanumerics – after all, until now, there was no compelling reason to do so – specifying callback=alert(1);// will simply bypass CSP right away.
The bottom line is that CSP will require web masters not only to create a sensible policy, but also thoroughly comb every inch of the whitelisted domains for a number of highly counterintuitive but potentially deadly irregularities like this. And that's the tragedy of origin scoping: if people were good at reviewing their sites for subtle issues, we would not be needing XSS defenses to begin with.
April 09, 2011
Using View > Encoding can kill you (in a manner of speaking)
Picking an alternative encoding through that menu overrides the character set not only for the top-level document, but also for all the nested frames - even if they happen to be cross-domain or hidden from view. And that may very well enable the owner of the visited page to carry out an XSS attack against a random third-party application without your knowledge.
Most security researchers associate encoding-related XSS problems with UTF-7, a somewhat preposterous and unnecessary encoding scheme that, by design, allows overlong encoding of 7-bit ASCII values (with disastrous consequences for HTML parsing). Not all browsers support UTF-7, and users are not likely to make that choice in the aforementioned menu. So, we're fine, right?
Well, not exactly. Many other, still popular multi-byte encodings, including Shift JIS or EUC-*, are also fairly problematic: their parsers often suffer from character consumption bugs, and in contrast to UTF-8, relatively little attention has been given to cleaning this up.
For example, with forced Shift JIS, this input is likely to be exploitable:
<img src="http://fuzzybunnies.com/[0xE0]"> ...this is still a part of the markup... " onerror="alert('Hi mom!')" x=" ...Simple demo here.
March 12, 2011
Pwn2own considered (somewhat) harmful
I also think that Pwn2own, an annual browser hacking contest run by TippingPoint, does not deliver the same value. The formula of the contest boils down to this: once a year, a single, secretly developed exploit is exchanged for a substantial amount of money. No information about the flaw or its back story is revealed in the process, and given that this trade is negligible in comparison to the annual volume of browser vulnerabilities, there is absolutely no intrinsic value in observing it.
That, alone, is not a compelling criticism; at best, it's a reason not to watch. But then, there are some negative consequences, too: it is in the interest of the conference and contest organizers, and the participating researchers, to get publicity for their findings - and journalists, who do not necessarily have a holistic view of the day-to-day browser security research, embrace such high-profile developments with disproportionate enthusiasm. The resulting ecstatic press coverage ultimately undermines any attempt to have a meaningful and reasonable discussion about the state of browser security.
Take this quote, which likely will be repeated in every Safari-related story for the next twelve months:
"A team was able to exploit Safari to exploit a MacBook Air in five seconds. Yes, five seconds - less time than it takes most people just to type 'Safari got hacked in less than five seconds'."
That's remarkable, but also completely wrong. It takes days or weeks to find and exploit a vulnerability, and Pwn2own is no exception: the actual exploits are prepared months or weeks in advance, and simply executed on the day the contest takes place. I do not think there is a single person in the information security industry who would say that the discovery of a normal browser vulnerability is a notable event: several hundred such flaws are discovered and resolved every year in every browser, as evidenced by release notes maintained by the vendors with varying degrees of accuracy. Neither the fact that somebody discovered a vulnerability before Pwn2own, nor that this person needed needed five seconds to execute that pre-made code, is a useful measure of anything.
Similarly, the survival of Firefox and Chrome intuitively makes me happy, because I know that these browsers give a lot of thought to security - but I do not think that Pwn2own is a meaningful testament to this. Perhaps these two vendors merely patched up the vulnerability somebody wanted to use, and there was not enough time to find a new one. Or perhaps nobody attending the event (which brings together only a tiny fraction of the infosec community) had the expertise and the inclination to target this particular browser.
Yes, there are vendors who lag behind the rest when it comes to vulnerability response and proactive security work; and there are some hard problems we still have to solve to make the web a safer environment. But the headlines inspired by Pwn2own (and probably encouraged by the organizers) are very unfair, and unnecessarily alienate the parties who should be paying attention to their security posture. Investigating real data, and asking some hard-hitting questions, can make more of a difference... and if done right, it can be more fun.
March 11, 2011
A note on an MHTML vulnerability
As some of you may be aware, Microsoft Internet Explorer supports MHTML, a simple container format that uses MIME encapsulation (nominally multipart/related) to combine several documents into a single file. Each container may consist of a number of possibly base64-encoded documents, with their content type determined solely by the inline MIME data.
Perhaps by the virtue of not having cross-browser support, the MHTML format is not commonly used on the web - but it is employed by Internet Explorer itself to save downloaded pages to disk; and embraced by some third-party applications to deliver HTML-based documentation and help files.
To facilitate access to MHTML containers, the browser also supports a special mhtml: URL scheme, followed by a fully-qualified URL from which the document is to be retrieved; a "!" delimiter; and the name of the target resource inside the container. Unfortunately, when MHTML containers are accessed over protocols that provide other, normally authoritative means for specifying document type (e.g. Content-Type in HTTP traffic), this protocol-level information is ignored, and a very lax MIME envelope parser is invoked on the retrieved document, instead. The behavior of this parser is not documented, but it appears that in many cases, adequately sanitized user input appearing on HTML pages, in JSON responses, CSV exports, image metadata, and so forth, is sufficient to trick it into treating the underlying document as valid MHTML. All that is needed to keep this parser happy is the ability to place several alphanumeric and punctuation characters on the target page, in several separate lines.
The payload inside such an unintentionally served "MHTML container" is able to execute JavaScript, and has same-origin DOM access to the originating domain; with some minimal effort, it is also able to access to domain-specific cookies. Therefore, this behavior essentially represents a universal cross-site scripting flaw that affects a significant proportion of all sensitive web applications on the Internet.
Based on this 2007 advisory, it appears that a variant of this issue first appeared in 2004, and has been independently re-discovered several times in that timeframe. In 2006, the vendor reportedly acknowledged the behavior as "by design"; but in 2007, partial mitigations against the attack were rolled out as a part of MS07-034 (CVE-2007-2225). Unfortunately, these mitigations did not extend to a slightly modified attack published in the January 2011 post to the full-disclosure@ mailing list.
It appears that the affected sites generally have very little recourse to stop the attack: it is very difficult to block the offending input patterns perfectly, and there may be no reliable way to distinguish between MHTML-related requests and certain other types of navigation (e.g., <embed> loads). A highly experimental server-side workaround devised by Robert Swiecki may involve returning HTTP code 201 Created rather than 200 OK when encountering vulnerable User-Agent strings - as these codes are recognized by most browsers, but seem to confuse the MHTML fetcher itself.
Until the problem is addressed by the vendor through Windows Update, I would urge users to consider installing a FixIt tool released by Microsoft as an interim workaround.
Update: see this announcement for more.
March 06, 2011
The other reason to beware ExternalInterface.call()
ExternalInterface.call(...), which implements a JavaScript bridge to the hosting page. It takes two parameters: the first one is the name of the JavaScript function to call. The second one is a string to pass to this function.
It is understood that the first parameter should not be attacker-controlled (of course, mistakes happen :-). It is also understood that there is no inherent harm in putting user input in the second parameter, if the callback function itself is not behaving stupidly; in fact, Adobe documentation gives an example that follows this very pattern:
...
ExternalInterface.call("sendToJavaScript", input.text);
...
Such a call would be translated to an eval(...) statement injected on the embedding page. This statement looks roughly the following way:
try {
__flash__toXML(sendToJavaScript, "value of input.text"));
} catch (e) {
"<undefined/>";
}
When writing the supporting code behind this call, the authors remembered to use backslash escaping when outputting the second parameter: hello"world becomes hello\"world. Unfortunately, they overlooked the need to escape any stray backslash characters, too.
So, try to figure out what happens if the value of input.text is set to the following string:
Hello world!\"+alert(1)); } catch(e) {} //
I reported this problem to Adobe in March 2010. In March 2011, after following up, I received the following response:
"We have not made any change to this behavior for backwards compatibility reasons."
Caveat emptor :-)
Warning: OBJECT and EMBED are inherently unsafe
type= parameter in your <object> or <embed> markup, what are the security consequences of allowing users to embed third-party Flash movies in their posts when you enforce the appropriate security restrictions on your end (allowScriptAccess, allowNetworking, allowFullScreen all set to none)? Or, to make things simpler, how about permitting a straightforward video file, with type=video/x-ms-wmv?
If you think this is safe, you may want to know that the HTML5 spec has a different view. The specification effectively takes away the ability for any single party to decide how a particular plugin document should be handled by the browser. Under the new algorithm, instead of your funny cat video, you may accidentally end up embedding Java, which has unconditional access to the DOM of the embedding page through DOMService. Whoops, looks like you are owned now.
According to the spec, if your visitor's browser has, say, a Windows Media Player plugin that recognizes the type=video/x-ms-wmv value on your webpage, that plugin will be used regardless of Content-Type. This part is intuitive. Alas, if the plugin is not found, the specification compels the software to look at Content-Type next, giving the hosting party an opportunity to override the intent specified on your end.
To further complicate the picture, in some circumstances, browsers may also ignore both type= and Content-Type values: for example, Internet Explorer and WebKit browsers will play Flash videos served with Content-Type: pants/whatever and loaded with type=certainly/not-flash just because a stray .swf file extension is spotted somewhere in the URL. The file name signal is problematic, as it can usually be tampered with by whoever provides the URL. This strategy brings a yet another player into the picture, and each party can sabotage the security assurances sought by the rest.
It would be more reasonable to keep the behavior of <object> and <embed> consistent with that of other type-specific subresource tags (e.g., <applet>, <img>, or <script>), and give control over how the document is rendered to whoever authored the markup. This approach is still not without peril, because it makes it impossible for some sites to indicate that a particular text/plain or image/jpeg response is not meant to be interpreted as a malicious applet. But that last problem can be fixed by requiring Content-Type and type= to match, perhaps through an opt-in mechanism controlled with a new HTTP header. And in any case, the proposed logic does not help.
In the end, the currently specified behavior seems highly counterintuitive, and undoes all the work plugin that vendors such as Adobe or Microsoft put into adding security controls to ensure that their plugin content is reasonably safe to embed across domains that do not fully trust each other.
Test cases here. Joshua Stein also reports that they confuse Flash-blocking tools.
February 21, 2011
Give me A, give me P, give me T
My view is a bit different. Any organization that focuses solely on prevention of non-targeted attacks is making a grave mistake. This hasn't changed at all in the past two decades: attackers interested in a particular target, and willing to spend several weeks on such a pursuit, were always a huge problem. In a vast majority of documented cases, they did not need to be unusually sophisticated to succeed, too - and in proportion to the size of the online economy, I don't think they are more numerous than, say, ten years ago.
Fending off these attackers in large and complex environments is very difficult, and requires in-depth in-house expertise, lots of ingenuity - and even then, it may occasionally fail. Alas, at the behest of vendors and infosec pundits, many organizations made exactly the wrong choice, and spent the bulk of their efforts on ISO 27002, PCI, SOX, and off-the-shelf AV and IDS tools - building a more measurable and familiar, but ultimately vulnerable, world.
It is increasingly evident that the value of these solutions in containing determined attackers is fairly small. The parties involved would prefer to say that they had done the right thing, and the threat landscape has changed in the meantime, instead. But the claim that they are facing a brand new, incredibly sophisticated adversary is a very self-serving one.
So, I am simply saddened by the emphasis on the "advanced" part of the term, and the Cold War rhetoric employed to push even more expensive and ultimately meaningless products and approaches. Whether you are a government agency or a Fortune 500 corporation, chances are, buying services such as 0-day vulnerability notifications or botnet monitoring is not an efficient use of your money.
February 18, 2011
Possibly the most fascinating HTML parser behavior ever
When parsing HTML documents, browsers recognize two methods of specifying tag parameter values: a "bare" form (such as <img src=image.jpg>), which is terminated by angle brackets, whitespaces, and so on; and a quoted form (<img src="image.jpg">) which is terminated only by a matching quote.
Every browser makes the decision by looking at the first non-whitespace character after the name=value separator. If this happens to be a single or a double quotation mark, the second parsing strategy is used; otherwise, the first method is a go. Internet Explorer also recognizes backticks (`) as a faux quote, leading to security flaws in a fair number of HTML filters - but even with this quirk, the behavior is still pretty straightforward. In particular, in the following example, stray quotes will not have any effect on how the tag is interpreted:
<a href=http://www.example.com/?">This text is not a tag parameter anymore.">Click me</a>
But here's the thing: Internet Explorer seems to be doing a substring search for an equals sign followed by a quote anywhere in the parameter name=value pair. Therefore, the following syntax will be parsed in a very different way:
<a href=http://www.example.com/?=">This is still a part of markup indeed!">Click me</a>
It's one of the most unique and surreal HTML parser quirks I am aware of (and it survives to this day in Internet Explorer 9). In principle, it allows any server-side HTML filter to get out of sync with the browser, leading to parameter splitting and tag consumption. In reality, it has a limited practical significance: if your HTML filter is relaxed enough to allow this syntax to go through, it is probably already vulnerable to the abuse of other syntax tricks.
February 16, 2011
The world of HBGary
It is also not because of the likelihood that a similarly opportunistic and amoral corporate culture is endemic to the entire sector - a suspicion made more credible after noticing that the leaked proposal uses the letterhead of another government-friendly company, Palantir, and generously credits a third one: Berico.
No, that's not it. The reason why I am frightened is the emergence of a new class of government contractors - a class that depends on the perpetration of an alluring, yet completely irrelevant belief: that an incredibly sophisticated and determined adversary is constantly scheming to wage a devastating cyber-war against everything we hold dear.
It is an ugly truth: for the past 10 or 15 years, the security industry has made virtually no progress in helping large organizations deal not with Bond-esque villains, but with the simple threat of bored kids and geeks with an agenda - their most significant, and most unpredictable foe. It is tempting to frame the constant stream of high-profile failures as a proof for the evolution of your adversary. But when you realize that almost every single large institution can probably be compromised by a moderately skilled attacker, this explanation just does not ring true.
The inability to solve this increasingly pressing problem is no reason to celebrate - and even less of a reason to push for preposterous, unnecessary spending on silly intelligence services, or to promote overreaching and ill-defined regulation. If anything, it is a reason to reflect on our mistakes and perhaps go back to the drawing board. But between all the talk of cyber-jihad and APT, this unpleasant message is easy to overlook.
...
On the flip side, the difficulty of securing a complex enterprise hardly applies to specialized, well-funded security outlets: that one problem is easy to fix. These companies should have an abundance of expertise and resources to tightly manage and monitor their relatively small and self-contained networks. Similarly, their employees can be reasonably expected to exercise above-average restraint and a good dose of common sense. It is an uncomplicated matter of living up to your own bold claims.
From this perspective, the purported details of the attack on HBGary - a horribly vulnerable, obscure CMS; unpatched internal systems; careless password reuse across corporate systems and Twitter or LinkedIn; and trivial susceptibility to e-mail phishing - are a truly fascinating detail. These tidbits seem to imply either extreme cynicism of their staff... or an ubelievable level of cluelessness. And from a broader perspective, both of these options are pretty scary.
Oh, the ironic part? Despite all the lofty rhetoric, looks like in the end, they have been undone by just a bunch of bored kids.
February 04, 2011
So you think *your* capability model is bad?
CAP_* boundaries are not particularly well aligned with the underlying OS, and not internally consistent - and therefore, much of the resulting granularity is almost completely meaningless: for example, there is no substantial benefit of giving an application just CAP_SYS_MODULE, CAP_MKNOD, CAP_SYS_PTRACE, or CAP_SYS_TTY_CONFIG privileges, as all of these are essentially equivalent to giving root access to the ACLed program.
I thought it would be interesting to engage in a similar thought experiment for the browser environment - after all, it is quickly becoming the equivalent of a complex and powerful operating system for modern web applications.
As far as normal web applications are considered, there is no concept of a globally privileged access level; permissions to access content on client and server side are controlled by four separate, implicit authentication schemes, instead:
- HTTP cookies (reference):
- Visibility: explicitly visible to client and server code.
- Scoping: scoped to the originating functional domain (or subdomain thereof). Can be additionally scoped to a specific document path; this meaningless as a security boundary.
- Notes: a kludge to allow scoping to HTTPS only is present - the
secureflag; this mechanism offers far less benefit than it could, because HTTP and HTTPS cookie jars are not isolated otherwise.
- Visibility: explicitly visible to client and server code.
- Legacy HTTP authentication (reference):
- Visibility: explicitly visible to server code; sometimes exposed to client code.
- Scoping: scoped to a protocol-host name-port tuple. In some but not all browsers, additionally scoped to a specific request path; or to a server-declared "realm" string.
- Visibility: explicitly visible to server code; sometimes exposed to client code.
- Client SSL certificates:
- Visbility: visible to server code only.
- Scoping: scoped globally in the browser.
- Notes: in most but not all browsers, user must confirm sending a certificate to a particular destination host name once within a browsing session.
- Visbility: visible to server code only.
- Script origin:
- Visibility: principally visible to client code only; unreliably disclosed to server on some requests.
- Scoping: origin is defined by a protocol-host tuple; port number is also included in most, but not all, browsers.
- Visibility: principally visible to client code only; unreliably disclosed to server on some requests.
- Notably absent: network context. The information about the circumstances in which a particular credential is established is not analyzed or preserved. Because of the persistence of web content, this poses a significant problem with public wireless networks.
- Subresource loads (reference):
- Relevant to: the ability to load images, scripts, plugins, frames, and other types of embedded content; and to navigate the top-level window.
- Security boundaries: this capability is not generally restricted in modern browsers. Certain response types can be read directly across websites; others can be requested, and then examined only indirectly.
- Interactions: server response can and often will be tied to server-recognized credentials, including cookies, SSL certificates, or client-supplied origin (non-universal
Originor unsafeRefererheader).
- Relevant to: the ability to load images, scripts, plugins, frames, and other types of embedded content; and to navigate the top-level window.
- DOM access (reference):
- Relevant to: the ability to directly access loaded documents through the JavaScript Document Object Model - a method considerably more versatile than the previous scenario.
- Security boundaries: privilege scoped to origin; when origin is not fully qualified, behavior is undefined. Scope can be expanded to functional domain via
document.domain; this has unintended consequences and is usually unsafe. - Interactions: access is not tied to any other credentials; for example, replacing or removing cookies does not revoke access from old documents to the new ones, and vice versa.
- Relevant to: the ability to directly access loaded documents through the JavaScript Document Object Model - a method considerably more versatile than the previous scenario.
- Most types of browser API access:
- Relevant to: access to browser-managed interfaces such as
postMessage(),localStorage, geolocation information, pop-up privileges, and so forth. - Security boundaries: permissions theoretically scoped to origin, but Firefox and MSIE currently violate this rule for
localStorageandsessionStorage, and scope to host; when origin is not fully qualified, behavior is undefined. Additional top-level window scoping is introduced forsessionStorage. Unlike with DOM access, these permissions are not affected bydocument.domain. - Interactions: access is not tied to any other credentials.
- Relevant to: access to browser-managed interfaces such as
- XMLHttpRequest API reference):
- Relevant to: the ability to make almost arbitrary, credential-bearing HTTP requests, and read back raw responses, from within JavaScript code.
- Security boundaries: permission scoped to origin; when origin is not fully qualified, behavior is undefined. Port number is always compared, even in browsers that do not include it in other origin checks. Scope not affected by
document.domain. - Notes: access to another origin is possible after a simple HTTP handshake in modern browsers.
- Interactions: server response can and often will be tied to server-recognized credentials.
- Relevant to: the ability to make almost arbitrary, credential-bearing HTTP requests, and read back raw responses, from within JavaScript code.
- Web sockets API (reference):
- Relevant to: a new HTML5 feature in WebKit browsers, allowing scripts to establish long-lived stream connections to arbitrary servers.
- Security boundaries: scripts can access any server and port after a successful completion of a challenge-response handshake.
- Interactions: server is provided with requestor's origin information and cookies to authenticate the request.
- Relevant to: a new HTML5 feature in WebKit browsers, allowing scripts to establish long-lived stream connections to arbitrary servers.
- Cookie access (reference):
- Relevant to: the ability to read or write the
document.cookieproperty. - Security boundary: content is scoped to a particular domain, path, and
secureflag level, as governed by cookie scoping rules. Cookies may also be tagged ashttponly, preventing reads (but not writes) from within JavaScript. - Notes:
document.cookiehas highly asymmetrical write and read behavior; it is possible to overwrite cookies for subdomains, paths, orsecure/httponlysettings well outside setter's nominal visibility. - Interactions: not tied to any other credentials or network context. Substantially incompatible with DOM access boundaries, affecting both schemes: DOM rules make cookie path scoping useless, while lax cookie scoping often undermines DOM origin-based isolation in cookie-authenticated web applications.
- Relevant to: the ability to read or write the
- Password managers:
- Relevant to: password auto-completion capabilities integrated with most browsers.
- Security boundaries: stored credentials are scoped to origin, path, and form layout; only the first part constitutes a meaningful security boundary.
- Notes: in some but not all browsers, an explicit user action needed to expose credentials to the origin.
- Interactions: incompatibility with DOM access rules makes path and form scoping useless from security perspective. Existing credentials are not taken into account when completing form data. Saved passwords are generally converted to cookie-based credentials by the server using an application-specific mapping.
- Relevant to: password auto-completion capabilities integrated with most browsers.
- Cache control:
- Relevant to: implicit and explicit retrieval of previously cached documents when requested by the client-side code.
- Security boundaries: cached content is scoped to original request URL and POST payload; once retrieved from the cache, it follows the same rules as any fresh response would.
- Interactions: caches may be shared by multiple users. Cached content is not explicitly tied to any credentials - logging out does not invalidate cached documents, and does not prevent same-origin access later on. If shared proxies are accidentally permitted to cache the response, it may be returned to other users, even though their requests do not bear relevant cookies.
- Relevant to: implicit and explicit retrieval of previously cached documents when requested by the client-side code.
- Internet Explorer zone model:
- Relevant to: a proprietary mechanism that allows elevated privileges to be granted to certain content; and to prevent navigation between certain groups of websites.
- Security boundaries: a mix of origin scoping for explicitly defined URLs; protocol-level scoping for
file://content; and IP, host name, and proxy configuration heuristics for Intranet resources. - Notes: local network heuristics can fail spectacularly in certain settings. Zone settings are fairly cryptic and difficult to understand. Users frequently add not-particularly-trustworthy websites to more privileged zones to work around usability problems.
- Interactions: not consistently synchronized with any other security boundaries. Largely neglects to consider the impact of cross-site scripting flaws.
- Relevant to: a proprietary mechanism that allows elevated privileges to be granted to certain content; and to prevent navigation between certain groups of websites.
- Plugin access:
- Relevant to: various activities of plugin-delivered active content, which generally shares the HTTP stack, cookie jar, and document cache with the browser; and has DOM access to the embedding page.
- Security boundaries: a variety of custom, inconsistent models: for example, Java considers all content originating from the same IP as same-origin; Flash glances over redirects and considers their result same-origin with the initial URL. Most plugins also offer multiple ways to negotiate cross-domain access.
- Notes: plugin origin is derived from the URL from which the code is retrieved;
Content-TypeandContent-Dispositionis usually ignored during this operation. - Interactions: largely inconsistent with all other browser security mechanisms.
- Relevant to: various activities of plugin-delivered active content, which generally shares the HTTP stack, cookie jar, and document cache with the browser; and has DOM access to the embedding page.
February 01, 2011
The dreaded curse of openness
"Android is open-source, which means the hacker can also understand the underlying architecture and source code. We have to give credit to Apple, because they are very careful about it. It's impossible for certain types of viruses to operate on the iPhone."
Now that Kaspersky has, ahem, joined the open source crowd - I worry that hackers may soon be able to understand the operation of anti-virus software as well. And beyond that unthinkable point, only darkness looms.
January 22, 2011
CSP, HTML5, and the aesthetics of security
The dominant theme of some of the security-relevant debates we are having today is that of aesthetics - an argument most prominently embodied by the controversy around Mozilla's Content Security Policy, an ambitious (and now scaled back) vision for controlling the interactions between all content on the web.
In a nutshell, many browser developers, especially those contributing actively to HTML5 security, seem to favor simplicity - and for all the good reasons, too. From their perspective, this principle brings:
- Clarity of vision: the incomprehensible and practically unmanageable mess of Microsoft Internet Explorer's security zone settings serves as an important cautionary tale: trying to scratch all itches at once, and accounting for every possible corner case, can be a self-defeating design pattern - and possibly a security risk.
- Ease of deployment: modest mechanisms that do not seek to redefine every aspect of browser behavior at once are much easier to implement in the browser itself, and much easier roll out and manage on application level - improving the odds of actually making a difference.
- A reduced number bugs: historically, complex security features have been shown to have far more failure modes. In essence, the fewer things can be misunderstood or overlooked, the better we are all off.
- Long-term consistency: unexpected conflicts between same-origin policy, HTTP cookies, password managers, document caching, SSL, plugins, and many other disjointed security mechanisms governing modern browsers have caused untold suffering to application developers - and still make it extremely hard to achieve certain seemingly simple goals, such as developing HTTPS-only services capable of surviving active attackers on public wifi networks.
- Better support for complex use cases: it is easy to devise a way to mitigate XSS vulnerabilities for 80% of all websites on the Internet - but for a vast majority of these, XSS is not a devastating problem to begin with. If, by the virtue of being overly simplistic, the proposed solution is not suitable for the top 1,000 most sensitive destinations on the web - complex properties such as online banking, social networks, webmail interfaces - then the benefit of rolling it out is disproportionately low.
...
The second, equally interesting clash in the browser security community is that over manners: determining the proper method to solve a particular problem. Seemingly minor disagreements about peripheral detail are often at the core of competing designs and implementations: XDomainRequest versus CORS; toStaticHTML() versus *.innerStaticHTML; and many more.
In most cases, both sides of the argument make a strong case for the superiority of their vision, at least for a set of uses they care about. For example, a recent counter-proposal to CSP XSS defenses focuses on two fairly minor changes - replacing policy specifications in HTTP headers with <meta> tags; and replacing server callbacks for reporting policy violations with a DOM event handler.
The problem is, all of these approaches make quite a lot of sense:
- Policy location:
- HTTP headers: more difficult to inject through common XSS vectors - therefore slightly safer.
- HTML tags: easier to place on a page when application developer has no fine-grained control over web server settings - therefore somewhat more likely to be widely embraced.
- HTTP headers: more difficult to inject through common XSS vectors - therefore slightly safer.
- Reporting mode:
- Server-side: will not fail if policy is broken to a point of preventing any client-side code from running - more reliable, therefore less scary to deploy.
- Client-side: easier to employ when there are limitations on the server-side logging and reporting infrastructure available - more useful to developers.
- Server-side: will not fail if policy is broken to a point of preventing any client-side code from running - more reliable, therefore less scary to deploy.
This is not a bad thing, to be sure - conviction and a desire to personally make an impact is what drives the open source community, and precisely what makes it so great; but that mechanism also makes it much harder to find a sensible middle ground. And if we don't find it soon - perhaps at the expense of some of our beliefs - I think it's going to haunt us all in the future... browser engineers, web application developers, and mere users alike.
January 01, 2011
Announcing cross_fuzz, a potential 0-day in circulation, and more
cross_fuzz - an amazingly
effective but notoriously annoying cross-document DOM binding fuzzer that
helped identify about one hundred bugs in all browsers on the market - many of said bugs exploitable - and is still finding more.
The fuzzer owes much of its efficiency to dynamically generating extremely long-winding sequences of DOM operations across multiple documents, inspecting returned objects, recursing into them, and creating circular node references that stress-test garbage collection mechanisms.
cross_fuzz fuzzing algorithm:
- Open two windows with documents of any (DOM-enabled) type. Simple HTML, XHTML, and SVG documents are randomly selected as targets by default - although any other, possibly plugin-supported formats could be targeted instead.
- Crawl DOM hierarchy of the first document, collecting encountered object references for later reuse. Visited objects and collected references are tagged using an injected property to avoid infinite recursion; a secondary blacklist is used to prevent navigating away or descending into the master window. Critically, random shuffling and recursion fanout control are used to ensure good coverage.
- Repeat DOM crawl, randomly tweaking encountered object properties by setting them to a one of the previously recorded references (or, with some probability, to one of a handful of hardcoded "interesting" values).
- Repeat DOM crawl, randomly calling encountered object methods. Call parameters are synthesized using collected references and "interesting" values, as noted above. If a method returns an object, its output is subsequently crawled and tweaked in a similar manner.
- Randomly destroy first document using one of the several possible methods, toggle garbage collection.
- Perform the same set of crawl & tweak operations for the second document, but use references collected from the first document for overwriting properties and calling methods in the second one.
- Randomly destroy document windows, carry over a percentage of collected references to the next fuzzing cycle.
I also believe that at least one of the vulnerabilities discovered by cross_fuzz may be known to third parties - which makes getting this tool out a priority.
The following summarizes notification and patch status for all the affected vendors:
- Internet Explorer: MSRC notified in July 2010. Fuzzer known to trigger several clearly exploitable crashes (example stack trace for
CVE-2011-0346) and security-relevant GUI corruption issues (XP-only, example,CVE-2011-0347). Reproducible, exploitable faults still present in current versions of the browser. I have reasons to believe that one of these vulnerabilities is known to third parties.Comment: Vendor has acknowledged receiving the report in July (case
10205jr), but has not contacted me again until my final ping in December. Following that contact attempt, they were able to quickly reproduce multiple exploitable crashes, and asked for the release of this tool to be postponed indefinitely. Since they have not provided a compelling explanation as to why these issues could not have been investigated earlier, I refused; see this timeline for more. - All WebKit browsers: WebKit project notified in July 2010. About two dozen crashes identified and addressed in bug 42959 and related efforts by several volunteers. Relevant patches generally released with attribution in security bulletins. Some extremely hard-to-debug memory corruption problems still occurring on trunk.
- Firefox: Mozilla notified in July 2010. Around 10 crashes addressed in bug 581539, with attribution in security bulletins where appropriate. Fuzzing approach subsequently rolled into Jesse Ruderman's fuzzing infrastructure under bug 594645 in September; from that point on, 50 additional bugs identified (generally with no specific attribution at patch time). Several elusive crashes still occurring on trunk. Bad read / write offset crashes in
npswf32.dllcan also be observed if the plugin is installed. - Opera: vendor notified in July 2010. Update provided in December states that Opera 11 fixed all the frequent crashes, and that a proper security advisory will be released at a later date (release notes list a placeholder statement: "fixed a high severity issue"). Several tricky crashes reportedly still waiting to be resolved.
Note that with Opera, the fuzzer needs to be restarted frequently.
December 20, 2010
Carrot, stick, research, disclosure
"If you share details of a security issue with us and give us a reasonable period of time to respond to it before making it public, and in the course of that research made a good faith effort to avoid privacy violations, destruction of data, or interruption or degradation of our service, we will not bring any lawsuit against you or ask law enforcement to investigate you for that research."
I respect my colleagues at Facebook - but I do not think this policy deserves such praise.
The problem is that with extremely rare exceptions, software vendors do not object to being given reasonable notice about a vulnerability - but one of the most significant points of contention between them and the research community is the meaning of that single, special word: "reasonable".
Because of different incentives, businesses have a history of allowing privately reported vulnerabilities to go unresolved for a year or more; and many of the best-known names in the industry have attempted to suppress good-faith attempts to alert the public to their apparent non-responsiveness.
I suspect that Facebook is capable and willing to respond to vulnerability reports promptly, and will not resort to such tricks - but that does not make the policy sound any better. The promise not to sue people who satisfy an unspecified but vendor-defined expectation of "reasonable time" implicitly creates a threat of prosecution in non-compliant cases; and equates them to other, clearly malicious practices listed in that aforementioned paragraph.
There are interesting examples of exceptional, researcher-friendly policies out there; this one doesn't belong, yet.
December 13, 2010
Unencrypted public wifi should die
Straightforward snooping and cute tricks such as sslstrip aside - all of them still deadly effective, by the way - there are many less obvious problems we simply can't solve any time soon:
- Cookie poisoning: JavaScript same-origin policy draws a clear boundary between encrypted and non-encrypted content - but HTTP cookies are critically broken in this regard. It is possible to selectively overwrite
securecookies with malicious values over HTTP - with disastrous consequences for most of the contemporary web apps. - Plugin SOP problems: similarly to cookies, the variants of same-origin access rules implemented by plugins such as Java, Flash, or Silverlight, are often peculiar - and do not necessarily respect the isolation between encrypted and non-encrypted content (but share the cookie jar and document cache with the rest of the browser).
- Cache poisoning: browser cache persists across network visits. On insecure wireless networks, malicious active content can be persistently cached in any non-encrypted origin - even if that origin is not intentionally visited - and will be carried onto trusted networks accessed later on (e.g., home or corporate environments); in other words, your browser may be essentially permanently backdoored after a single visit to a public hotspot. Curiously, there is some renewed interest in this area of recent. HTML5 features such as cache manifests and local storage promise to make the problem even more pronounced.
- Cache retrieval: for the same reason, content injected over insecure wireless networks can comprehensively enumerate and read back all previously stored objects in browser cache, in arbitrarily selected non-encrypted origins - a huge privacy problem for as long as any remotely sensitive data is still exchanged over HTTP - even when this exchange itself happens only over private, secure networks.
- Address bar autocompletion poisoning: even with mechanisms such as Strict Transport Security in place, content injected over insecure networks may attempt to silently poison address bar autocompletion mechanisms - ensuring that future attempts to navigate to a particular website will be completed in a subtly incorrect way, and will take the victim to a malicious domain name instead.
PS. As of today, encrypted 802.11 is not much better for this use: the fiasco of WEP aside, on WPA2-PSK networks with publicly advertised key, insiders may simply decode and modify traffic to other clients by watching the handshake; while other authentication systems may be vulnerable to "Hole 196". On top of that, attackers may opt to impersonate "trusted" access points as seen fit. These shortcomings are incredibly frustrating - but can be addressed; in fact, some proprietary workarounds seem to be available already.



