386 karma · joined September 15, 2010
Anyway, one issue I have with "pass" is that it leaks metadata, as it uses the file system to organize different credentials, while only the files storing the credentials itself are encrypted.
Also "pass" uses GPG for encryption, which can provide additional security if you store your private key on an external drive or smartcard, and take additional measures to make it more difficult to obtain access to your password store and private key at the same time. But in the more common setup where the password store is stored along the private key on the same device, cracking your GPG passphrase will require less computation than cracking a passphrase using PBKDF2 with 256,000 iterations like used for key derivation in mypass.
Unlike most Show HN posts this isn't a new software, but one that I initially created back in 2014, and ended up spending a fair amount of time on recently, leading to its 2.0 version which I released today. In the beginning it was just a hack scratching a personal itch of mine. But I think mypass has matured a lot since then, and I'd love to get some feedback from other potential users.
But I ended up storing everything into one single encrypted file, rather than having one file per password. Though I see the point about the UNIX philosophy (i.e. "everything is a file"), but that way you'd leak information, i.e. what the passwords stored are for.
Anyway, I'd appreciate any feedback on mypass.
You can use anything that is exposed by the Linux kernel under /sys/class/leds/*. This includes the keyboard backlight of ThinkPads. As for other vendors, it depends on whether the keyboard backlight (or any other LED) can be controlled in software, and if so whether it is supported by any kernel driver.
If you try it out, let me know how well it works. So far I only had a chance to test it on a ThinkPad X230 and X250, and I would be interested to know how well it works on other models, potentially even with other vendors. Though, I haven't seen any non-ThinkPad laptop yet that has LEDs that can be controlled through the Linux kernel.
Also in case you are using Firefox on Debian/Ubuntu, note that blinklight requires at least Firefox 50, which is not yet in Debian stable/testing, but Firefox 52 can be installed from experimental.
We work remotely, so is our hiring process. While it would be possible to give a programming task to a candidate, we won't have any control over whether they did it themselves, or how much time they actually spend on it. Well, the former is less of a problem, once you discuss the solution you see pretty quickly whether they did it themselves and understand how their solution works. However, candidates that want the job will try hard to do as best as possible, so some candidates that you give a 2h task to, tend to spend much more time on it. Others might not have as much time to spend on the task, since they usually still have a full-time job. So the results are not comparable.
Besides that, I find it quite difficult to find a task that can be done in 2h, but gives a sufficient insight of their skills, however you cannot expect somebody to take on a more elaborate task, whether paid or not, because most candidates are in a full-time job when they apply.
Also, this might be different in the US, but here in Germany, if the candidate isn't a freelancer/contractor at the moment, but permanently hired by an other company (this is normal), there is no way to pay them officially.
> Input function
Yes, in Python 2, input() is a shortcut for eval(raw_input(...)), and documented as such. Obviously that is not a safe way to parse user input, and therefore it has been changed in Python 3. So this has been fixed, but if you don't read the documentation you probably will keep introducing security issues with whatever programming language.
> Assert statement
If you want to effectively protect against a certain condition, raise an exception! Asserts, on the other hand, exist to help debugging (and documenting) conditions that should never occur by proper API usage. Stripping debugging code when optimizing is common practice, not only with Python.
> Reusable integers
First of all, this behavior isn't part of the Python programming language, but an implementation detail, and a feature as it reduces memory footprint. But even when small integers wouldn't be cached, you would still have the same situation when using the is operator on variables holding the same int object. On the other hand, caching all integers could easily cause a notable memory leak, in particular considering that ints in Python 3 (like longs in Python 2) can be as large as memory available. But either way, there is no good reason to check for identify if you want to compare values, anyway.
> Floats comparison
floats in Python use essentially the native "double" type. Hence they have whatever precision, your CPU has for double precision floating point numbers, actually it is specified in IEEE 754. That way floating point numbers are reasonable fast, while as precise as in most other programming languages. However, if that still isn't enough for your use case, Python also comes with the decimal module (for fixed-point decimal numbers) and the fractions module (for infinite precision fractions).
And as for infinity, while one would expect float('infinity') to be larger than any numerical value, the result of comparing a numerical value with a non-numerical type is undefined. However, Python 3 is more strict and raises a TypeError.
> Private attributes
Class-private attributes (those starting with __) exist to avoid conflicts with class-private attributes of other classes in the class hierarchy, or similar accidents. From my experience that is a feature that is rarely needed, even more rarely in combination with getattr()/setattr()/delattr(). But if you need to dynamically lookup class-private attributes you can still do so like hastattr('_classname__attrname'). After all, self.__attrname is just syntactical sugar for self._classname__attrname.
Also note that private attributes aren't meant as a security mechanism, but merely to avoid accidents. That's not specific to Python; in most object-oriented languages it is possible to to access private attributes, one way or another. However, Python tries to be transparent about that fact, by keeping it simple.
> Module injection
Yes, Python looks in a few places for modules to be imported. That mechanism is quite useful for a couple of reasons, but most notably it's necessary to use modules without installing them system-wide. It can only become a security hole if a malicious user has write access to any location in sys.path, but not to the script, importing the modules, itself. I can hardly think about a scenario like that, and even then I'd rather blame the misconfiguration of the server.
> Code execution on import
Yes, just like every other script language, Python modules can execute arbitrary code on import. That is quite expected, necessary, and not limited to Python. Even if module injection is an issue, it doesn't make anything worse, as you you don't necessarily have to run malicious code on module import but could do it with whatever API is being called. But as outlined above, this is a rather theoretical scenario.
> Shell injection via subprocess
Yes, executing untrusted input, is insecure. That is why the functions in Python's subprocess module, by default, expect a sequence of arguments, rather than a string that is parsed by the system's shell. The documentation clearly explains the consequences of using shell=True. So introducing a shell injection vulnerability by accident, in Python, seems less likely than with most other programming languages.
> Temporary files
If anything, Python is as unsecure as the underlying system, and therefore as most other programming languages too. But CWE-377, the issue the author is talking about, isn't particular easy to exploit in a meaningful way, plus it requires the attacker to already have access to the local temporary directory. Moreover, Python's tempfile module encourages the use of high-level APIs that aren't effected.
> Templating engines
The reason jinja2 doesn't escape HTML markup by default is that it is not an HTML template engine, but a general purpose template engine, which is meant to generate any text-based format. Of course, it is highly recommended to turn on autoescaping when generating HTML/XML output. But enforcing autoescaping would break other formats.
Jumps out of loops and other blocks work now. However, there are some limitations:
1. As I only have 4 bytes left to inject POP_BLOCK instructions, you can't exit more than 4 blocks with a goto. But this is handled and results into a SyntaxError rather than crashing Python.
2. Jumps into loops still doesn't work. However, it's handled now, and causes a SyntaxError as well.
3. When jumping out of a try- or with-block the finalizer is skipped.
10000 loops, best of 3: 72.9 µs per loop @ CPython 2.7.10 with NOP
10000 loops, best of 3: 77.2 µs per loop @ CPython 2.7.10 with JUMP_FORWARD
10000 loops, best of 3: 106 µs per loop @ CPython 3.5.0 with NOP
10000 loops, best of 3: 106 µs per loop @ CPython 3.5.0 with JUMP_FORWARD
100000 loops, best of 3: 8.6 µs per loop @ PyPy 2.4.0 with NOP
100000 loops, best of 3: 8.7 µs per loop @ PyPy 2.4.0 with JUMP_FORWARD
To my surprise, in fact, JUMP_FORWARD isn't any faster than 7 NOPs. In Python 2.7, JUMP_FORWARD is even slower. So reverted:
https://github.com/snoack/python-goto/commit/d19d244a9e5efdf...
Thanks for the pointer!
Yes, technically it would be possible to remove the code instead injecting NOPs. But then I'd have to adjust the jump targets. However, I don't think these NOPs are too bad. Note that goto jumps directly after the NOP ramp of the label, and the NOPs of the goto itself are never reached. The only scenario where NOPs are actually seen by the interpreter is when the natural code path visits a label.
EDIT: Instead re-assembling the bytecode and adjusting jumps, I went to use JUMP_FORWARD(3) instead 7 NOPs now. Note that there are still 4 NOPs left to fill the gap, these however are never executed as they are skipped by the preceding jump instruction. https://github.com/snoack/python-goto/commit/2b0f5e5069cbb88...
The old mechanism, that is the non-standard "beforeload" DOM event + synchronous messaging via canLoad, had it's issues. But the new one is entirely different from the hooks Chrome and Firefox provide to intercept requests. So I'm certainly not a fan of it either, as this makes it even more elaborate to port extensions relying on content blocking to Safari, and massively reduces the amount of code that can be shared between the respective Chrome, Firefox and Safari extension.
But even more importantly, I fear that it will have some shortcomings when it comes to blocking requests depending on its context (e.g. frame hierarchy). At least I'd be very surprised if they do a better job than Google did with Chrome's declarativeWebRequest API.
If somebody knows any more details about that new API please let me know.
Adblock Plus also blocks tracking when you add the EasyPrivacy filter list [1]. So you won't need Ghostery anymore. But you can also use both extensions at the same time, if you want.
It is absolutely unacceptable to that without asking the user. It is also illegal in some countries. Adblock Plus doesn't do that, and even provides an optional filter list to block tracking on websites.
Indeed there was a bug on Chrome and Opera that re-enabled Acceptable Ads during an update. And of course it is tempting to believe that this was intended, given the controversy around Acceptable Ads. But believe it or not, every release of every software has bugs. And consider the complexity of the code initializing Adblock Plus, migrating old settings, setting up default filter lists and dealing with different storage APIs for almost every browser. Also a single setting being reset during update, is not a case you easily notice during testing. So it is no surprise that a bug like that made it into the release at some point.
Beside that there are several cases where browser profiles can be corrupted. That includes browser crashes, bugs in the browser itself, unreliable storage devices and a few other cases. You will realize that users of every extension that can be configured, occasionally report that their settings had been reset. Of course that don't bothers you if you use the default settings anyway. But also there is not much extension developers can do against that.
But even on Safari Adblock Plus blocks requests loading images, frames, scripts and other resources, by cancelling the beforeload event. Though it is not possible to block XMLHttpRequests and requests initiated by third-party plugins like Flash.
Adblock Edge just disabled Acceptable Ads by default and removed that option from the UI. Also considering that Adblock Edge is less maintained, it's not worth using it instead of Adblock Plus, if you ask me. You can just disable that option in Adblock Plus.
.textfield {
&-label {
...
}
&-input {
...
}
}However the comment you replied to was about the accusation that Adblock Plus would be dishonest, which just isn't true.
By the way Adblock Plus has put Reddit and some other smaller websites on the white list for free to support them. But unfortunately Adblock Plus has also to cooperate with larger companies to make some money, themselves. But still, all ads that are getting on the white list are mild, and not the kind of ad that made once everybody of us that pissed off, that we started to use ad blockers.
Another thing I would like to mention is that, around the same time Adblock Plus introduced "Acceptable Ads", a lot of websites at least here in Germany started to detect ad blockers and asked the user to disable his ad blocker. Otherwise the website refused to deliver content or provide functionality. With the increase of popularity of ad blockers, the people running websites driven by ads will no longer tolerate that their ads are blocked. And there will be probably nothing you can do against that. Considering that, it is actually great that those websites can just get on a white list used by the majority of AdBlock Plus users. So the websites can continue to make enough money from their ads and people that are smart enough to disable "Acceptable Ads", like you and me, still get all ads blocked.