Jump to content

Jacques1

Members
  • Posts

    4,207
  • Joined

  • Last visited

  • Days Won

    209

Everything posted by Jacques1

  1. That check is supposed to help you how exactly? I mean, as you've already found out, you cannot prevent people from purposely giving you a fake e-mail address unless you force them to go through a confirmation procedure. So all of your checks are limited to catching mistakes. Formal validation obviously makes sense for that, but what do you expect to get from a DNS check? Are you afraid that people might accidentally enter something like “gmail.comm” instead of “gmail.com”? I find that rather far-fetched.
  2. C'mon. Have you even read those? Do you not know that w3schools in particular is one of the worst resources on the Internet? They are not associated with the W3C in any way. It's a private company which does nothing but fool users, spread bullshit and sell useless “certificates”. In fact, every single one of the above three “tutorials” is dangerously wrong and makes both the application and the server itself wide open to code injection attacks. At best, those are examples of what you should not do when you implement an upload.
  3. What is this weird JavaScript code generator stuff, anyway? I mean, what are you trying to achieve in the end? Generating code is generally a very bad idea, and it's particularly bad in a web context. You waste your time struggling with syntax noise, you'll probably screw up some detail in the highly complex JavaScript grammar, and you invite the whole world to try a code injection attack. For example, if you plan to put the generated code into a script element, you've already lost, because you've failed to escape critical characters like the backslash or the ampersand which can be used for a cross-site scripting attack. Long story short: You're almost certainly doing it wrong. If you want to exchange data, you should do exactly that. Just make a script which JSON-encodes the array with the built-in json_encode() function and echos the result. You can then fetch the data with Ajax.
  4. I doubt that. The code is full of security vulnerabilities, configuration issues, conceptual errors, bugs and plain nonsense. Either hand out excellent code, or don't hand out code at all. It doesn't help anybody if you post some half-baked script . In fact, it's downright harmful, because people looking for help tend to blindly take anything they can get. I wouldn't be surprised if this very code is running on some live server right now. Sorry for the harsh reaction, but sometimes less is more.
  5. You generally must not prepend a backslash to literal characters. For example, “\s” is obviously something completely different than a simple “s”. Yes. Like almost all home-made e-mail regexes, this is nonsense, both technically and semantically. Whoever wrote this doesn't really understand regexes and hasn't bothered to read the standards. So don't use this is a template or for learning. An underscore never has a special meaning. And a hyphen within a character class is only taken literally if it's at the beginning or the end. Otherwise it signifies a range (as you've already seen). Whatever flaws the PHP validator may have: They're nothing against the garbage that floats around on the Internet. So do use the built-in validator and avoid home-made regex hacks. Regexes are generally overrated. I understand that they're fascinating for beginners, because they seem like an almighty text processing tool. I used to feel the same. But after a while, you'll see the deficiencies and realize that they're the wrong tool for most jobs. A regex is great for simple patterns like a date or something. But it's just not powerful enough for anything more complex like an e-mail address or even a full-blown language like HTML. That's where the abuse begins.
  6. What do you mean by “conflict”? The subclass methods override the superclass methods just like always. What's the problem with that, and what do you want instead?
  7. It makes no sense to learn the obsolete MySQL extension and then start over with PDO. Just use PDO from the start. The old extension is dead since more than a decade; the only reason why it's still around is because of legacy applications, old tutorials and clueless teachers. The old MySQL extension reflects the technology of the 90s. A lot has changed since. For example, we use prepared statements to securely pass values to a query. We employ exceptions to represent errors in a smart way. And we make use of object-oriented programming. You should start right in the 21st century instead of going back in time. What do you expect to find there?
  8. How do you know that a user which is not logged in owns a particular comment and is allowed to delete it? I mean, you don't want arbitrary users to delete arbitrary comments, right?
  9. This makes no sense. MySQLi is much more difficult to use than PDO. And of course it's limited to MySQL, which is another downside. So if you rewrite your database code, do it properly and go with PDO. If you were planning to cheat and merely add an “i” to all mysql_* functions, this doesn't get you anywhere. It's still the same insecure code. Sure, you'll get rid of the deprecation warnings, but that's not worth the effort.
  10. Don't invent your own crypto algorithms. Contrary to popular belief, it's not as easy as randomly throwing together a bunch of hash algorithms. It requires expert knowledge, careful design, extensive peer review and real-life testing for at least a decade. You don't fulfil a single one of those requirements. This doesn't even make sense: So $key is a secret key, I guess? Do you not realize that this allows an attacker to break all hashes in parallel once they've obtained the key? Why do you keep calculating the SHA-512 hash of $key? Do you not realize that the result is always the same? The entire algorithm requires just one SHA-512 calculation and 26 WHIRLPOOL calculations. Do you not realize that even a stock PC can do this millions of times per second? There may be tons of other weaknesses, but none of us is a cryptographer, so none of us is qualified to talk about it. My advice is: Forget about home-made algorithms and use a professional solution. The current de-facto standard for password hashing is bcrypt. It was designed by people who actually know what they're doing and has been around for 15 years. In addition to that, it's well-integrated into PHP. If you have PHP 5.5, you can make use of the new Password Hashing API. If you don't have version 5.5 but at least 5.3.7, you can use the password_compat library from the same author. I understand that it's temping to play around with cryptography and try to come up with something new. But cryptography is hard science. Trying to come up with a new password hash algorithm with no qualificiation whatsoever is like trying to perform a brain surgery with a rusty screwdriver.
  11. This is a bad idea. The REMOTE_ADDR depends on the server setup and may very well be identical to the SERVER_ADDR at all times (in case of a reverse proxy, for example). While this may work as a quick hack in your specific case, it's definitely not a solution. As trq already said, place the scripts outside of the document root. If that's not possible, there's something wrong with how you use paths.
  12. The Location header tells the browser to ignore the response body and immediately jump to the specified page. So, no, it doesn't work like that. You either need a meta element or a JavaScript-based redirect (which will obviously not work if JavaScript is turned off). However, the whole idea is very bad as explained by the W3C in the link. Automatic redirects are generally confusing and can come at an inconvient time. What if the user was just about to do something on the page? This is 90s technology, we don't do that anymore. Either leave out the message stuff and just do an immediate redirect or implement a proper Ajax UI which handles this in a user-friendly way (this won't be easy).
  13. There's a lot wrong with this. First of all, PHP 5.2 is hopelessly outdated. It was abandoned back in 2011 and is full of unfixed bugs. Even worse: The bcrypt implementation of all PHP versions before 5.3.7 is broken. So you cannot use PHP 5.2. If that's all you get from your webhoster, then there's something very wrong with their update policy. Get away from them and get a proper hoster. Secondly, never just copy and paste some code you found somewhere on the Internet. Whoever wrote this implementation clearly doesn't know what she's doing. The salt alphabet is wrong, the salt is not random, and there's no error checking whatsoever. This is badly screwed up. Last but not least, never fumble with cryptography on such a low level. When you call crypt() directly, you're doing it wrong. This function is highly complex and shouldn't be used by anybody but library authors. So: Get a proper webhoster with an up-to-date PHP version. You need at least 5.3.7 to use bcrypt. The current version is in fact 5.5. If you can get PHP 5.5, use the new Password Hashing extension. It offers a nice high-level interface for password hashing and takes care of all the ugly details. If you cannot get PHP 5.5, you need a proper library. Use the password_compat library by Anthony Ferrara. You need to get familiar with error checking, especially when you deal with security code. You can't just call a function and assume that it always runs successfully. What if it fails? You need to check that by looking at the return value.
  14. There isn't always a “tutorial” telling you exactly what to do. I've given you a fairly extensive overview, why not start with that? If you have issues with a specific step, just ask. You could do that, but why would you? If the user has multiple files with the same name in different directories, they again run into the problem of name collisions. Either they have to manually rename their files or, which is even worse, they accidentally overwrite old files. In addition to that, this combination of the internal user ID and the user-provided name is neither convenient for you nor for the user. So what's the point of that? The original filename chosen by the user and the actual filename on the server are two different things which have nothing to do with each other. When you store the file on your server, you don't care about which name the user chose on their PC. You need to choose a name which is appropriate for your server (no collisions, easy lookup etc.). The original filename is just metadata which goes into the database. Either use the primary key from the database as the filename or a purely random name (which is what I prefer). Of course you can display the original filename on the page, but it makes no sense to actually store your files like that. If you absolutely must include the original filename the URL (for SEO purposes or whatever), append it to the physical name: https://uploads.yoursite.com/images/8881d83fe82501a7adf9049714f0d20f-my-cute-kitten.jpg
  15. Your script doesn't have any security at all. The problem is that you appearently don't understand the risks and how to deal with them. Yes, you're doing a bunch of type checks, but none of this has anything to do with security. Throwing together a bunch of tutorials is not a good starting point. Most of them are already crap, and if people blindly copy and paste them, that's like Chinese whispers: At the end, it's all gibberish. A much better approach is to actually think about the problem and come up with an intelligent solution. So what is the problem? A user might upload a server-side script to attack your server. Or they might upload a client-side script to attack other users or, indirectly, your server. Validating the file type does not help against any of this. I can give you a perfectly valid image which even looks fine and still contains malicious code. For example, the JPEG format explicitly allows arbitrary text comments, so an attacker can easily embed PHP or JavaScript code. The point is that the file must be treated as an image. As long as that's the case, there's no problem. But if your server or the browsers of your users think they should execute the file, you're in deep trouble. How a file is treated depends mostly on the extension. Never accept the user-provided extension like you currently do. An attacker will upload an image ending with “.php” or “.html”, and suddenly you have a PHP script or HTML document on your server. Only allow specific extensions like “.jpeg” or “.png”. You also need to choose a unique filename. You can't just take the user-provided name, because then your users may overwrite existing files. Either use the value of an AUTO_INCREMENT column or generate a random filename. The latter is preferred if you don't want the whole world to see who uploaded what when. To make sure that your webserver will indeed not execute any uploaded files, turn off script execution in the upload directory. Apache has the SetHandler directive for that. To prevent client-side scripts from being executed, use Content Security Policy. This is limited to modern browsers, though. In addition to that, serve the uploaded files from a separate domain so that malicious script cannot affect your main site even if they are executed. Avoid using a subdomain, because then an attacker will still be able to set cookies for the main site and, for example, perform a session fixation attack. But if a subdomain is all you can get, it's better than nothing. Wrapping it up: Validate the extension, not the file type. Only allow specific image extensions. Choose a unique filename, do not accept the user-provided name. Turn off script execution in the upload directory. Use Content Security Policy. Serve the uploaded files from a separate domain (preferrably not a subdomain of your main site).
  16. Stuffing queries into the database makes absolutely no sense whatsoever. It makes even less sense when I look at the actual query. All that does is retrieve one particular record from one table, which means the only relevant parameters are the ID the possibly the table. Anyway, if you want proper help, you need to tell us the actual problem, not what you think is the solution.
  17. In general, you can't just include files from somewhere on the Internet. The script is on somebody else's server, and you usually don't have access to the servers of other people. Remote includes are a special feature which only works if you turn it on (via allow_url_include) and have FTP access to the remote server. In that case, PHP will download the script and execute it as if it was a local file on your server. This feature is very controversial, because it's obviously a major security risk. What if the script contains malicious code? Any halfway competent administrator will not even allow remote includes. It's probably best to just forget it and not regard it as a valid solution in the first place. Anyway, let's hypothetically assume that you do have a remote include. In that case, you of course need the entire environment necessary to run the script. If there are queries, then you need the database. If there are references to other scripts, you need those other scripts etc. Since you most certainly don't have the database of PHP Freaks, the whole idea is bound to fail. On the other hand, an API is an interface to a remote server. The server exposes a certain set of functionalities for you to use. For example, PHP Freaks could create an API to let us fetch arbitrary posts. There are no rules how an API should look like. It's entirely up to the service provider. All an API is supposed to do is accept requests (usually via HTTP) so that the user can trigger an action or get data. If you think that a GUI helps people use your service, why not?
  18. Like I said, you just calculate the total when needed. There's absolutely no reason for physically storing it. You do realize that MySQL can do more than just “SELECT *”, right? You can do all kinds of calculations and data aggregation within the query.
  19. And why exactly do you think you need a column to hold the total? Just calculate it with MySQL when needed: SELECT r1 + r2 + r3 + r4 + r5 AS total -- this is bad design FROM cautotest ; However, the poor database design already shows in this simple query: When you have a group of values, you do not create a column for each one. This violates the First Normal Form. A dead giveaway for this problem is that you start numbering your columns. Instead, you create an extra table to store the values as rows. In your case, you'd have something like this: ref_id | round | points -------+-------+------- 2 | 1 | 90.0 2 | 2 | 412.0 The huge advantage is that doing calculations accross the rows becomes trivial, and you can change the number of rounds at any time. Now the query is as simple as this: SELECT ref_id , SUM(points) AS total FROM cautotest GROUP BY ref_id ;
  20. Not quite, those are several different things. First of all, a string column in MySQL has a character set/encoding and a collation. The character set/encoding defines which characters are available and how they're encoded (mapped to bytes). In your case, you would use utf8mb4 which is Unicode with the UTF-8 encoding. The collation is a set of rules for how two strings should be compared. If you want a case-insensitive comparison with Danish-specific rules, you would indeed use utf8mb4_danish_ci. In any case, it's important to understand the difference between collation and character set/encoding. On the other hand, there's the character set/encoding of the connection. This doesn't have to match the one of the column. For example, you can access a utf8mb4 column via a latin1 connection. MySQL will automatically convert the data if possible. The connection encoding is very important and a cause of many errors. When you had issues with Danish characters, I'm pretty sure you indeed had a latin1 connection, because that's the default. The problem is that latin1 only supports 256 characters, so all Unicode characters outside of this small subset cannot be represented. Long story short: You have to define the character set/encoding for your stored data. This is done with the CHARACTER SET keyword at database-level, at table-level or at column-level. You need to specify the collation for your stored data. This is done with the COLLATE keyword. You have to set the character set/encoding of your database connection. This depends on the database extension you're using: In PDO, you use the charset attribute in the constructor. In MySQLi, you call the set_charset() method. And in the old MySQL extension, you call mysql_set_charset(). Like I already said above, you must not execute a SET NAMES query. While this does change the encoding as well, it breaks the inner workings of the PHP database functions and can lead to security vulnerabilities. Never use SET NAMES except when you're sitting in front of a MySQL console and manually enter the queries.
  21. Defining the character encoding with PDO is a breeze, because you can do it directly when establishing the connection: <?php $database = new PDO('mysql:host=YOURHOST;dbname=YOURDB;charset=utf8mb4', 'YOURUSER', 'YOURPASSWORD', array( // use actual prepared statements instead of client-side escaping PDO::ATTR_EMULATE_PREPARES => false, // throw an exception in case of an error PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // fetch associative arrays by default PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, )); Note that what MySQL calls “utf8” is not UTF-8. It only covers a subset of Unicode, namely the Basic Multilingual Plane. For full Unicode, you need utf8mb4. Also note that it's not recommended to rely solely on a meta element to declare the character encoding of an HTML document. This is actually somewhat absurd: You ask the browser to parse the document in order to find out how to parse the document. This does work, but only under certain circumstances. For example, the element must be present within the first 1024 bytes of the document. A much more robust solution is to declare the encoding in the HTTP headers so that the browser knows it beforehand. You should still add a meta element in case the document gets stored offline. So the proper way would look something like this: <?php // This should be done by the webserver, not PHP. header('Content-Type: text/html; charset=utf-8'); ?> <!DOCTYPE html> <html lang="da"> <head> <meta charset="utf-8"> <title>My site</title> </head> <body> <p>Welcome</p> </body> </html>
  22. Stop right there, Erik. That code hopelessly outdated and uses many of the anti-patterns from the early days of PHP. I don't know if Dreamweaver has shitty code templates, or if you've learned this from some very bad tutorial, but this is far from proper PHP and HTML as we use it today. It's (bad) 90s code. You've declared the document as XHTML, but you're serving it as plain HTML. This is wrong and makes no sense. Why do you even want XHTML? It may have been all the rage 10 years ago, but that trend is long over. Most people never really understood how to use it, it requires a lot of discipline (no markup errors allowed), and it doesn't have all the great new elements of modern HTML. Unless you have special reasons for why you need XHTML, you shouldn't use it. Go with plain HTML. The current revision is HTML5. As David already said, the mysql_* functions are obsolete since more than 10 years and will be removed in one of the next PHP releases. Nowadays, we use PDO or MySQLi. I don't recommend MySQLi, because it can only be used for the MySQL database system and tends to be very cumbersome. PDO, on the other hand, is a universal interface for all mainstream database systems and is much more user-friendly. You're using die(mysql_error()) to print all errors on the website for the whole world to see. This, again, may have been acceptable back in the 90s when security was less important and users didn't mind being greeted with strange PHP errors. Today, security is absolutely crucial, and if people see error messages on your site, they will be very irritated. In modern application, errors need to be handled properly. And this SELECT * stuff really must die. Always select the specific columns you need. I'm not blaming you for not knowing this. But you definitely need to throw away Dreamweaver and use proper tools and proper resources. It's usually a good idea to start with plain HTML before you jump into PHP. An excellent resource is the Mozilla Developer Network. Make sure to keep away from “w3schools” and other fishy websites. When you start with PHP, get used to the manual as early as possible. It contains many important information. For example, it would have warned you that the mysql_* functions are obsolete. Do not use SET NAMES. This is a major security vulnerability, because it silently changes the character encoding without notifying PHP. As a result, critical functions like mysql_real_escape_string() may no longer work, leaving the application wide open to SQL injection attacks. The proper way to change the connection encoding is to call mysql_set_charset(). Fortunately, most modern encodings are ASCII-compatible, so you usually get away with this bug. But I wouldn't try it.
  23. PHPMailer is one of the biggest mailer libraries for PHP. It has been around since 13 years and is still actively maintained on GitHub. Do you expect your application to live longer than that? The problem with home-made mail solutions is that they're usually wrong (header injection vulnerabilities are the rule rather than the exception) and massively bloat the code with all kinds of irrelevant low-level stuff. All the script above is supposed to do is send a friggin' mail with an attachment. Yet large parts of the code are actually dedicated to the inner workings of multipart messages. In my opinion, this is a total waste of time and energy.
  24. And why not store the input exactly as is together with the original system? If you convert everything into one base system, you have to be very careful not to accidentally change the input due to rounding errors.
  25. It works perfectly. If you're having trouble with the function, then you're not using it correctly, or there's some other issue with your application. We might be able to help you, but then you have to give us information. What's your code? What's the problem? Remember that we don't have access to your server, so you need to actually tell us what's going on.
×
×
  • 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.