Jump to content

Jacques1

Members
  • Posts

    4,207
  • Joined

  • Last visited

  • Days Won

    209

Everything posted by Jacques1

  1. That's funny, because I just gave you three(!) different ways: a separate HMAC ECB mode no encryption as long as the e-mail addresses are kept away from the web frontend If you want to discuss this new topic in detail, do create a new thread.
  2. The global search function (search in forums) takes around 20 seconds to come up with the results.
  3. First off: We're talking about hypotheticals now. Since you already stated that you won't use the e-mail addresses as usernames, all problems related to that approach are no longer relevant. I'm saying that your loop idea requires locking (in whatever shape or form). And when you can only process one registration at a time, an attacker can jam your system with minimal resources to prevent legitimate registrations. A cron job running at a low frequency makes it even worse. Just do the math: One registration every hour means that 1,000 fake registration keep you busy for more than a month. Actually, there is a second approach besides ECB: If you store an HMAC of each e-mail address, the database system can enforce the uniqueness of the addresses without actually needing to know them. But of course the application will still leak information about the e-mail addresses everywhere.
  4. It's worse: To prevent race conditions, you'd have to block all new registrations while the check is in progress. Otherwise multiple processes running at the same time might register the same e-mail. It's easy to see how a global registration block could be abused for a denial-of-service attack. As long as your server is kept busy with address checks, no legitimate user can create an account. Like I said, the only feasible option for encrypting the e-mail addresses is to use ECB mode. This makes the ciphertext dependent only on the key and allows the database system to do searches and string comparisons. Unfortunately, those nice features of ECB mode are also nice for attackers. Since the same plaintext block is always mapped to the same ciphertext block, an attacker can see matching substrings and use the information to partially or fully derive the plaintext e-mail addresses. This was exploited in the Adobe hack, for example. Even worse: An attacker can actively probe for substrings simply by creating their own accounts. If you're specifically required to use e-mail addresses as usernames, go with ECB and make sure you understand the security implications.
  5. You shouldn't directly upload files to your server either. This can easily fudge up your site, and it will be very difficult to recover from a problem when you've made multiple changes over a longer period of time. Instead, use version control software like Mercurial or git. This allows you to properly manage changes and update the server in a controlled manner. Since all mainstream IDEs have built-in support for version control, committing a change is just as easy as uploading in a file in DW. You can then either let the server update itself, or you do it manually (whatever you prefer). I understand that you like DW, but I get the impression that it's actually preventing you from discovering better solutions and making progress. I'm also afraid you won't find many developers who use DW. But of course you're free to try.
  6. I don't have a solution for this particular problem, but after 10 years of programming, I think it's time to abandon Dreamweaver and switch to a professional IDE (PhpStorm, Netbeans, Eclipse, whatever). If you're into minimalism, there's Notepad++. And as a nice side effect, your tools will no longer fudge up your code.
  7. The arrow -> is used to access properties of an object. But you have an array, not an object. The array index syntax looks like this: $res[0]['number1'] Your prepared statement doesn't make sense either. Instead of passing the dynamic input to parameters (which is the whole point), you insert it straight into the query string, potentially introducing SQL injection vulnerabilities.
  8. So the problem only happens in Chrome, yes? This would confirm that it's a browser bug. Inline scripts and styles created by JavaScript are not supposed to be blocked by CSP. In any case, jQuery 1.3.2 is ancient, and the offending line doesn't seem to exist in newer versions. So update jQuery and try again. If it still doesn't work, whitelist this particular script with a nonce.
  9. You've asked the exact same question before. Please stop doing that. This problem is a matter of common sense anyway. WinSCP doesn't store keys; you've stored keys. So look up the path in the original configuration, grab the file and copy it. Shouldn't be too hard. Windows also has a search function.
  10. Maybe there's a compromise: You use the “Other Programming Languages” for now, and when there's a significant amount of threads for a particular language, this discussion is resumed. This is actually what I originally suggested.
  11. Ruby takes a slightly different approach to OOP, but that's a good thing: It's more pure, more elegant and has many best practices already built in: Every value is an object, including numbers, strings, booleans, arrays etc. Even classes are objects which allows for some interesting design choices: Ruby doesn't need the concept of static attributes or methods, because a class object can have methods and attributes just like any other object. There's a clear class hierarchy with BasicObject as the root node. There's no raw attribute access like in PHP. A object only exposes methods, and attributes are implemented as a getter and/or setter method together with an internal object variable. So everything I told you above is already part of the language. Error handling is implemented purely with exceptions. There are no low-level errors like in PHP. So instead of fumbling with error handlers and all kinds of edge cases, you can simply wrap the main code in a begin-rescue statement (Ruby's equivalent of try-catch). The every-value-is-an-object rule in particular makes the language very elegant. For example, instead of using a for loop, you can simply call the upto() or downto() method of an integer: 1.upto(10) do |i| print i end vs. for ($i = 1; $i <= 10; $i++) { echo $i; } Instead of using a foreach loop, you call the each() method of the collection object (similar to jQuery): chars = ['H', 'e', 'l', 'l', 'o'] chars.each do |ch| print ch end vs. $chars = ['H', 'e', 'l', 'l', 'o']; foreach ($chars as $ch) { echo $ch; } So, yes, I would give it a try and jump straight to Ruby. You'll learn a lot about OOP, you'll learn a new language, and you might actually like what you see. Unlike PHP, Ruby has some great books (particularly the famous “pickaxe book” and a well-written introduction from the language author), code you find online is usually OK, and there are plenty of knowledgeable programmers around. If there's permanent interest, I'm sure we can open a new Ruby forum here. One small warning, though: Ruby is a general-purpose language, so it's less plug-and-play when it comes to web applications. For hobby stuff, you can install the Sinatra framework and use its built-in webserver. For more serious applications, you'll need an application server like Puma behind Apache/nginx.
  12. It actually isn't true. An attribute created within a method is a real attribute. It's not limited to the method scope in any way. Dynamic properties are valid (that's why the magic methods __get() and __set() exist). They just shouldn't be used unnecessarily.
  13. Best practice is to use parent, because it allows you do change the class names at any time. If the names are hard-coded everywhere in the methods, that's a lot more difficult.
  14. Not really. Unfortunately, PHP isn't a great language for learning OOP, because all OOP parts have been added on top of the procedural paradigm at a very late stage. This is why they often seem unnatural and hard to understand. If you're really interested in OOP, you should consider learning it together with a language that has been designed in an object-oriented manner from the ground up. My personal favorite is Ruby (which is a scripting language), and of course there are classical OOP language like Java (which is heavier). In the above case, you want a protected attribute without initialization. It doesn't hurt to initialize the attribute with an empty string, but it's simply unnecessary when the name is immediately assigned within the constructor. Initialization makes sense when you don't assign a value in the constructor.
  15. PHP lets you do almost anything, but if you want to learn proper OOP, you should adhere to very strict standards – regardless of what the PHP interpreter says. The reason why you should declare attributes (with a line saying public/protected/private $attName) is that you need to know the attributes of an object to write correct code. When I type $obj->num with a properly declared attribute, my IDE immediately gives me a lot of important information: whether the attribute actually exists (I could have made a mistake) the type and meaning of the attribute through the documentation the initial value where the attribute comes from (could be a superclass) and where it's used With dynamically added attributes, you get none of this. You're flying blind. This may be OK for a simple test class, but when you're dealing with a complex architecture and dozens of classes, you definitely need to know what's going on. “It works” isn't enough. The point of initializing an attribute (with public/protected/private $attName = ...) is to make sure the attribute has a reasonable default value as opposed to null. Unfortunately, the example code is a fairly bad example. It would make a lot more sense to assign the name through the constructor: <?php class Member { /** * @var string */ protected $username; /** * @param string $username */ public function __construct(string $username) { $this->username = $username; } } This provides several benefits: A member object is always completely initialized with a valid name. In your case, the name is initially empty. PHP can check the type of the input (only in PHP 7). In your case, nothing prevents me from setting the username to 123. The attribute is safe, because it cannot simply be manipulated from the outside. In your case, any part of the application can change it to any nonsense value at any time. The latter is also the reason why attributes should almost never be public. You don't want uncontrolled changes and nonsense values. If you need to expose the attribute at all, you do it through getters and setters. A getter method simply returns the attribute value so that it can be read (but not changed) from the outside. A setter method takes one argument, validates it and assigns it to the attribute (if the value is valid). This allows the outside world to change the attribute in a controlled(!) manner. <?php class Member { /** * @var string */ protected $username; /** * Getter for the username * * @return string */ public function getUsername() { return $this->username; } /** * Setter for the username; this must be omitted if the username should be read-only * * @param string $username the new username */ public function setUsername(string $username) { // validation (can be much more strict) if ($username == '') { throw new InvalidArgumentException('Username cannot be empty'); } $this->username = $username; } /** * @param string $username */ public function __construct(string $username) { $this->username = $username; } } No. The var keyword comes from PHP 4 and is long obsolete. If you see it being used in a tutorial, pick a different tutorial.
  16. PHP can add properties dynamically, but you should avoid this at any cost, because you won't get documentation, you won't get code completion, and you cannot easily distinguish between legitimate attributes which just aren't declared and plain programming errors (e. g. mistyped attributes). In this particular example, it's also problematic that the attribute can be uninitialized when you use it.
  17. Get the value where? In PHP? That's not possible, because the URL fragment (the part after #) is never sent to the server. It's purely client-side. It might be a good idea if you explain what exactly you're trying to do. I mean the broader picture.
  18. The code you've copied and pasted checks for PHP 4.3.0 which was released 14(!) years ago and doesn't even work for mysqli which was released 12 years ago. So wherever you got this from, it's literally ancient. I understand that you're still learning, and that's exactly what this forum is for. What I'm trying to get across is that programming is more than “somehow making things work”. Sure, you can assemble your programs from 14-year-old code snippets you found somewhere on the interwebs. And you might even get a result in the sense that you see rendered HTML on the screen. But that's not really programming. Modern PHP is actually a decent language which allows you to write secure and compact code, but so many people learning PHP (not just you) seem to be stuck in early 2000. That's why I'm trying to promote the PHP of 2016.
  19. For the record: extract() is a terrible function which should not be used in any kind of serious code. Flooding the symbol table with dynamic variables is not only unnecessary, unclean and error-prone. It can fudge up your entire security if the data is user-controlled. When you have an associative array of data, simply keep it that way. No reason to turn it into a set of variables.
  20. Manual escaping is nonsense and simply doesn't work. I've reviewed lots of code from many different programmers who were all convinced that they “just have to remember to call the escape function”, and they've all failed. Sure, you can fix those two simple lines. But can you write a entire application with thousands of lines of code without ever making a mistake? Do you fully understand even the most obscure edge cases? Have you found a solution to inherent problems like the fact that encoding issues can break escape functions? I doubt it. We have prepared statements now. Use them. There's no reason to write code like it was 1990 and put yourself and your users at unnecessary risk.
  21. The code is not fine. You're wide open to SQL injection attacks, because you insert the user input straight into the query string. And instead of using exceptions as I said above, you're relying on this weird self-made error handling where most relevant information is missing. If you print those error messages on your actual website, that's yet another problem. Learn mysqli. Make sure you actually understand features like prepared statements and exceptions.
  22. There aren't any big differences. But I find true/false more appropriate than 1/0, and declaring methods as private means you prohibit subclasses from using them, which doesn't really make sense in this case.
  23. It's a security vulnerability in any case, because even wrong passwords will often be very close to the actual passwords. They may in fact be actual passwords from other sites which the user mixed up, or they're old passwords which can be used to figure out the new passwords. You really cannot log any password of any kind. I'm not even sure how that data would be useful. No, it's a class/interface name (the first case in the list). <?php /** * */ class LoginAttemptsLog { /** * @var PDO the connection to the underlying database */ protected $database; /** * @param PDO $database the connection to the underlying database */ public function __construct(PDO $database) { $this->database = $database; } /** * @param string $username */ public function logFailedAttempt($username) { $this->logAttempt($username, false); } /** * @param string $username */ public function logSuccessfulAttempt($username) { $this->logAttempt($username, true); } /** * @param string $username * @param boolean $successful */ protected function logAttempt($username, $successful) { $attemptStmt = $this->database->prepare(' INSERT INTO user_login (login_status, login_ip, login_username, login_datetime) VALUES (?, INET_ATON(?), ?, NOW()) '); $attemptStmt->execute([($successful ? 1 : 0), $_SERVER['REMOTE_ADDR'], $username]); } }
  24. Sounds like a permission problem. Are you sure that the Unix account of the webserver (usually something like www-data) has execute permissions for every single directory of the path and read permissions for the script?
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.