This reminds me a lot of one of the original ways to run unsigned code on the Sony PSP.
If you made two directories:
SomeApp
SomeApp%
And then launch the folder with the % sign then the code that checks for valid signatures will check in the directory without the %, but the code that actually launches the binary will still run the code in the directory with the %.
So all you need to do is get any binary with a valid sig and put it in the SomeApp folder while putting the code you actually want to run in SomeApp%.
A while back I filed a bug on libplist with some examples of the hilarious this-is-not-XML issues in Apple's userland plist parser, which people might find fun here as it is highly related to this issue.
Jay, I just wanted to say thanks to all the groundbreaking work you’ve done in the jailbreaking scene. Ages ago I had an iPad Touch and I had so much fun jailbreaking it and playing around with Cydia tweaks.
> I just hate GUIs for development, especially when you Google how to do something, and the answer is a series of 17 “click here and there”s that are no longer valid because all the GUI stuff moved somewhere else in the last update.
It's not just developer tools that suffer from this problem. I opened iMovie recently after not playing with it for almost 10 years, and was so flabbergasted at how everything worked. Took me almost 2 weeks to sync my own song to a series of cut video clips (cut out of larger videos, which was the main problem). Maybe I'm just an idiot, but googling around for solutions ended up with either out-of-date answers or completely unrelated problems.
I just wish that the app would use even one or two conventions from the 40-50 years of GUI research that has been done...
I'm convinced that the reason for the constant game of GUI musical chairs - of which Microsoft is the most guilty - is due to developers attempting to justify their employment.
My experience has been the opposite - developers being resistant to frontend changes, which tend to get pushed through by UI/UX people (which is their job), or in more broken organizations, opinionated managers or executives.
The IT industry benefits from fashionable UIs (dark or bright, angular or rounded, 2D or 3D, etc.) and architectures (server centric, client centric, etc.) quite similarly to the fashion industry benefiting from rising and falling hemlines and wide vs skinny ties.
It’s hilarious that it was easier for me to adjust to FCPX than to try to move my amateur video editing brain to new iMovie, so much so that I just renew my trial once a year instead of try to use iMovie. They ported the iOS version and it shows (especially considering how many features are missing from iMovie 09).
Even many programming examples are long out of date. Google for how to do something and the top answers are 10-15 years old using jquery or C++11 etc...
Maybe we should take this as a lesson that we should use the simplest marshalling format that adequately captures our use cases rather than using a swiss-army knife format like XML.
I agree in general. But XML as used in plists is actually not especially complicated, if you aren't trying to be a webbrowser and tolerate invalid input.
Your security-sensitive parser should not attempt to tolerate invalid input.
Probably you should not have multiple separate implementations of it, either.
Plists support dates (json doesn’t explicitly), and has you explicitly type the contents, which can help make sure that when you want a string you don’t get an int.
They could always drop XML for YAML and get more issues!
I dislike XML and would not chose it for my projects. But... in this case, it does seem like a good idea to require explicitly closed tags. Seems like it could remove 1000 error potentials for every 1 parser error.
Yeah, an XML parser that allows invalid XML (tags must be closed, per the spec[1]) is pretty clearly a terrible choice for a security-sensitive purpose. Likely it was just oversight / accidental reuse, and it's a somewhat common error, but it's very much an engineering mistake and not an XML flaw.
Fair enough. When I worked for Apple, I would often take a gander at the iOS source code. There was a lot of legacy stuff in there, as in, "do not modify this method, we don't know what it does" in comments. There were certainly legacy components in there from many years back, and it didn't seem like tech debt was on the radar. At least when I was there.
Certainly there are various bits that are legacy and behave like that, but generally speaking, calling the entire thing legacy is a bit of a stretch. Also considering it started in 2007, I think the definition of legacy is quite short termed here. It also implies a negativity, that if you’re not jumping from technology to technology then you’re doing something wrong. I disagree with that viewpoint.
As someone currently taking a break from reverse engineering the internals of CoreGraphicsServices on macOS, I can't resist saying that iOS can't possibly be as legacy as this.
I thought the Windows Registry was reviled because it was a single database that held everything from user customization to device driver and boot configuration, in one file. It was contrasted with the Unix/Linux way, which was single-purpose text files, with the system-wide configuration in protected /etc files, and user-specific configuration in ~/. files
Plists are the best of both worlds. They're a file format rather than a system database, so user-specific config goes in ~/Library/, application-specific config goes in the *.app/ bundles, and system-wide config is in /System or /Library. But it's also a unified format, so each program doesn't need to implement its own parser, and users and developers don't have to wonder how application XYZ decided to escape backslashes, in its config file.
How are they "the macOS equivalent of windows registry"? Or is that just a generic techno-slur?
I meant it in the sense that it turned into binary blobs that became less accessible for humans to manage, and a place where both Apple and 3rd party vendors started hiding magic stuff stored who-knows-where in a format that isn’t easy to grep / find.
It is far from the Windows registry. Everything is file-oriented, making it easy to backup or wipe away any given plist. The plists themselves are well named and located files that tell you what it is, and things don’t appear in multiple places. No program that gets installed needs to modify any system plists; in fact, apps pretty much never access plist that they don’t own. This last fact makes it so different from windows that you don’t see “plist repair apps” in the same way you do for windows.
Binary plists are identifiable to ascii plists, they’re just more compact. plutil is a utility that can convert them back and forth. Internally the plist classes can be passed either to load and they won’t bat an eye.
The author mentions that this bug saved him 1000s of hours in development. How is a sandbox escape useful in development? Can someone give me an example?
If you're looking for 0day kernel exploits that might be popped from say MobileSafari, having an unrestricted, unsandboxed non-root shell is a much better starting point compared to a regular sandboxed app launched from xcode. Or even just for inspecting the filesystem outside a regular app's restricted container.
Apple said that they’d make research devices available to select people, but as far as I can tell nobody seems to have gotten one. (Not to mention that such a policy, even if it actually handed out devices, is fairly exclusionary.)
The section of the WHATWG HTML spec about parsing XHTML begins with this note:
> An XML parser, for the purposes of this specification, is a construct that follows the rules given in XML to map a string of bytes or characters into a Document object.
> Note: At the time of writing, no such rules actually exist.
What do the authors of HTML mean by this? Isn't there a spec for XML? There is -- here's what it has to say about comments (https://www.w3.org/TR/xml/#sec-comments):
12.2.5.45 Comment state
Consume the next input character:
U+003C LESS-THAN SIGN (<)
Append the current input character to
the comment token's data. Switch to
the comment less-than sign state.
U+002D HYPHEN-MINUS (-)
Switch to the comment end dash state.
U+0000 NULL
This is an unexpected-null-character
parse error. Append a
U+FFFD REPLACEMENT CHARACTER
character to the comment token's data.
EOF
This is an eof-in-comment parse error.
Emit the comment token. Emit an end-
of-file token.
Anything else
Append the current input character to
the comment token's data.
The spec defines what to do for every character, even characters that should not appear in valid HTML. An HTML parser will behave exactly the same as another HTML parser in all circumstances.
You can see the success of this approach on the real web; inconsistent HTML parsing between browsers is no longer the issue it used to be 15 years ago. It may be more work to write, but I wish HTML's precise, step-by-step format was more common. Writing a spec as a list of rules makes it easier to implement (as a first pass, you can just go line-by-line and translate it to code) and reduces the chance of inconsistencies like the one in the article (and their associated security implications).
I am very skeptical. This state-machine approach seems much more like an implementation than a specification. Having a reference implementation could certainly be a good thing, but this doesn't even look like something one could run and test against.
The declarative form of Comment, above, is wonderfully concise and clear when compared to these several lines of imperative, update-this/goto-there style alternative. You can see in your head what it should match without mentally simulating these specific instructions against some imagined parser state.
There certainly can be a host of terrible issues with BNF-style grammars. When they're just used as a notation to write down a bunch of rules, with no regard to actually implementing these rules, the result can be a sprawling and terribly ambiguous mess. For instance, this[1] is an abject disaster, chock full of ambiguity and senseless distinctions.
But if one is prepared to take the effort to really write a machine-readable grammar like this[2], the result is a straightforward, high-level, concise spec that can be compiled into an implementation to boot. What's not to like?
If you made two directories:
And then launch the folder with the % sign then the code that checks for valid signatures will check in the directory without the %, but the code that actually launches the binary will still run the code in the directory with the %.So all you need to do is get any binary with a valid sig and put it in the SomeApp folder while putting the code you actually want to run in SomeApp%.