Jump to content

Jacques1

Members
  • Posts

    4,207
  • Joined

  • Last visited

  • Days Won

    209

Community Answers

  1. Jacques1's post in Using urlencode() was marked as the answer   
    The second code snippet doesn't make a lot of sense, because you're blindly applying urlencode() to a complete part of the URL. This will not only fudge up forward slashes. A query or fragment will also be affected.
     
    You need to apply the encoding while you assemble the URL or URL part so that you know exactly what you encode (e. g. an individual path segment or parameter).
  2. Jacques1's post in When is http_response_code() ever needed? was marked as the answer   
    Yes. It does not somehow alter the PHP configuration to send a 400 response code forever – if that's what you're worried about. Only the pending response is affected.
  3. Jacques1's post in phpmailer was marked as the answer   
    PHPMailer validates the provided e-mail addresses, so they cannot be used to inject headers.
     
    However, a library doesn't magically prevent all possible vulnerabilities. For example, in your above code you print mail errors directly on the screen, which can leak critical information about you server. Another common problem is to insert raw input into an HTML mail, which can lead to cross-site scripting vulnerabilities.
     
    So writing secure code is still your responsibility as a programmer. A library can only take care of specific problems.
  4. Jacques1's post in email verification security concerns was marked as the answer   
    Your send_mail() function has no protection against mail header injection. The above code with mostly hard-coded arguments may not be vulnerable, but that's just a happy coincidence. As soon as you have to deal with dynamic input, you will run into security problems.
     
    Using the low-level mail() function is generally a bad idea, because it's far too dangerous and error-prone. You should use a proper library like PHPMailer instead.
     
     
     
     
    This code makes no sense.
     
    A HMAC is a message authentication code used to protect data from manipulation. You don't have this kind of data. And the third argument must be a (binary) cryptographic key, not a simple name. I'm surprised that PHP even accepts that input.
     
    Neither hashes nor HMACs make sense in this context. You need to generate a binary random number and then encode it to make it human readable. A hash is only used to safely store the random number. So the procedure is as follows:
    generate random bytes encode the random bytes (hex-encoding is usually the most robust variant) and send the encoded token in an e-mail hash the raw random bytes and store the hash in the database; a simple SHA-256 hash is enough in this case, because random bytes cannot easily be brute-forced like a password from a human user
  5. Jacques1's post in Is chaining methods considered good or bad practice? was marked as the answer   
    It's considered good practice, simply because it's both nice to read and nice to write. There's even a design pattern for it: The Fluent Interface.
     
    The only reason why PDO isn't fluent is that it supports legacy error handling and uses the return values to indicate errors. Without this baggage, I'm sure our code would look exactly as you suggested (including the formatting).
  6. Jacques1's post in possible to print the current value of enum? was marked as the answer   
    // Moved from JavaScript forum
     
     
     
    Whatever language that is, it's not JavaScript. Are you confusing Java and JavaScript? Those are two entirely different languagues not related in any way.
     
    If you do mean Java, your question still makes no sense to me, because you've already answered it yourself:
    System.out.print(car); This does exactly what it says. It prints the name of the enum constant.
  7. Jacques1's post in "global" nginx configuration was marked as the answer   
    nginx has the include directive which does exactly what the name says. I'm surprised you couldn't find it, Darghon.
     
    Many settings can also be declared at the top level rather than per server block. This makes life even easier, because the values are automatically inherited but can still be overriden whenever needed.
     
    What are those global settings, anyway?
  8. Jacques1's post in XSS prevention was marked as the answer   
    XSS has nothing to do with databases or input validation. It's an output problem caused by programmers who naïvely insert data (from any source) into HTML contexts.
     
    This cannot be solved with validation, because
    formal validity doesn't mean that the data is safe in every possible context. For example, I could give you a perfectly valid e-mail address which is an XSS vector at the same time. Why? Because the format of e-mail addresses was never meant to protect web applications from XSS attacks. Why should it? it's impossible to predict the context in which the data will be used. There's not just HTML. There are thousands of different languages and data formats with distinct syntax rules, and the data may be a threat to every single one of them. a lot of data cannot be validated at all. For example, how would you “validate” the posts on this forum? We obviously have to write down HTML markup and JavaScript code all the time. That's the whole point of this site. XSS must be prevented during the HTML rendering process. The best solution is to use a proper template engine like Twig which automatically applies HTML-escaping to all outbound data. The second-best solution is to write a wrapper for the htmlspecialchars() function. Using htmlspecialchars() directly is not recommended, because it's extremely error-prone. In my experience, almost nobody understands how to use it correctly.
     
    In addition to HTML-escaping, you should use Content Security Policy. This allows you to define strict rules for JavaScript execution and block many attacks.
  9. Jacques1's post in php timer was marked as the answer   
    The whole approach sounds rather weird.
     
    You've implemented a timer with pure PHP? How does that work? Timers are classical client-side features, i. e. a task for JavaScript. Of course you can and should also store the time on the server to prevent cheating, but all the visuals should be done entirely with JavaScript.
     
    Since you're storing the time in the session, what happens when the session is destroyed before the building is finished? Does it simply disappear? You'll probably want to use the database instead.
     
    And why exactly do you have to use this weird date("his") stuff instead of a proper timestamp? Do use time()!
  10. Jacques1's post in xss protection? was marked as the answer   
    Using htmlspecialchars() directly is difficult and often leaves your application open to more subtle attacks. Use a proper wrapper:
    /** * HTML-escapes a string so that it can safely be included in an HTML document * * @param string $unsafe_input the string which should be escaped * @param string $encoding the character encoding of the input string * * @return string the escaped string */ function html_escape($unsafe_input, $encoding) { return htmlspecialchars($unsafe_input, ENT_QUOTES | ENT_SUBSTITUTE, $encoding); } Note that escaping is dependend on the character encoding, so you should have a constant or configuration value for the encoding of your HTML documents:
    <?php // UTF-8 is recommended for modern applications const APP_HTML_ENCODING = 'UTF-8'; <?php // require_once the functions and constants here // unless your webserver already sets the encoding attribute in the Content-Type header, do it here header('Content-Type: text/html;charset=utf-8'); $test_input = '"></div><script>alert("XSS")</script><div data-dummy="'; ?> <!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8"> <title>Page title</title> </head> <body> <!-- testing the escape function --> <div data-test="<?= html_escape($test_input, APP_HTML_ENCODING) ?>"></div> </body> </html>
  11. Jacques1's post in Restful Api was marked as the answer   
    The order of your parameters is wrong: In the bind_param() call, you assume it's (ID, name), but in the query it's actually (name, ID). So you need
    $stmt->bind_param("si", $name, $id); Using the number of affected rows as an error condition is also a bad idea, because it's perfectly normal for an UPDATE query to have no effect (e. g. when a previous process has already updated the value). At best, you'd include the affected rows as informational data. To get real errors, enable error reporting for MySQLi before you establish the database connection:
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); Now you'll get a mysqli_exception whenever a query fails. If you leave the exception alone (meaning: you don't catch it), PHP will automatically emit a 500 response code to signal an error.
  12. Jacques1's post in trying to create a 2d array on the fly was marked as the answer   
    Assuming the subject/grade combinations are unique:
    $descriptors[$row['subject']][$row['grades']] = $row['descriptor']; You need better variable names than "descriptors" and "row", though.
  13. Jacques1's post in elseif syntax was marked as the answer   
    You can't have an "elseif" after an "else". The "else" marks the end of the statement (as in: If none of the above is true, execute the following code).
     
    It's
    if (...) { ... } elseif (...) { ... } elseif (...) { ... } ... else { ... } If your code "just gets stuck", that means you need to fix your error reporting as well. PHP always tells you exactly what's wrong.
  14. Jacques1's post in Turn off error message at Get_file_content was marked as the answer   
    There's the error suppression operator.
     
    Whether that's a good idea is debatable, though, because it will suppress all errors, including serious ones. Consider using a more professional HTTP client like cURL.
  15. Jacques1's post in Script not working was marked as the answer   
    The bigger picture is that you need to stop writing spaghetti code.
     
    Right now, you have JavaScript code within 90s HTML markup within PHP code, next to CSS within HTML within PHP. No wonder you spend most of your time struggling with syntax errors! You've reached the point where you no longer understand your own code.
     
    JavaScript code and CSS declarations belong into external files. This will massively reduce the complexity and size of your PHP scripts, making syntax errors much less likely. The PHPHTML pasta can be untangled with a template engine like Twig, which will also fix dozens of cross-site scripting vulnerabilities in your current code (it seems you haven't even thought about security before).
     
    While it's theoretically possible to generate dynamic web pages with pure PHP, this requires a lot of discipline and security awareness. I don't recommend it.
     
    Last but not least, you should replace your current code editor with a proper IDE (integrated development environment) like Netbeans or Eclipse. This will warn you immediately when you fudge up the syntax, giving you a chance to fix the error yourself.
  16. Jacques1's post in how to use php associative array in JS was marked as the answer   
    Objects aren't ordered, so the loop can start anywhere. The (inefficient) loop also isn't necessary. Use the built-in hasOwnProperty() method mentioned above.
  17. Jacques1's post in Evaluating POST data in PHP was marked as the answer   
    So you want to check if the grade parameter does not exist at all?
    if (!isset($_POST['grade'])) ... or
    if (!array_key_exists('grade', $_POST)) ...
  18. Jacques1's post in Getting Mysql encoded Content with PHP was marked as the answer   
    unserialize()
  19. Jacques1's post in check files exist was marked as the answer   
    You have to move the return true behind the loop that that it's only executed if all files exist.
     
    Or use a boolean variable for clarity:
    $filenames = ["index.html", "areas.html", "test.html", "example.xls"]; $all_files_exist = true; foreach ($filenames as $filename) { if(!file_exists($this->skeleton_dir.$filename)) { $all_files_exist = false; break; } } return $all_files_exist;
  20. Jacques1's post in structuring array help was marked as the answer   
    array_push() appends a value to an array, so there are necessarily two arguments (or more). If you have less, your code makes no sense.
     
    It seems what you actually want to do is store a value at a specific index, which has nothing to do with array_push():
    $array[$location][$i] = $connection->sheets[0]["cells"][$i][2];
  21. Jacques1's post in Apostrophe in search term kills my page was marked as the answer   
    You're inserting $_POST['search'] straight into the query string, which means that a single quote will terminate the SQL string after the LIKE keyword and change the entire query. It's a self-inflicted SQL injection. What's much worse than your current bug is that anybody can manipulate the query and fetch sensitive data (passwords, e-mail addresses etc.) or even take over the server.
     
    To fix this vulnerability, stop inserting PHP string into queries. The whole point of prepared statements is that you use a constant query with placeholders:
    <?php const DB_HOST = 'localhost'; const DB_USER = '...'; const DB_PASSWORD = '...'; const DB_NAME = '...'; const DB_CHARSET = 'UTF8'; /* * Set up the database connection * - the character encoding *must* be defined in the DSN string, not with a SET NAMES query * - be sure to turn off "emulated prepared statements" to prevent SQL injection attacks * - turn on exceptions so that you don't have to manually check for errors */ $dSN = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHARSET; $databaseConnection = new PDO($dSN, DB_USER, DB_PASSWORD, [ PDO::ATTR_EMULATE_PREPARES => false, // activate real prepared statements PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // activate exceptions PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // fetch associative arrays by default (this isn't critical) ]); $songStmt = $databaseConnection->prepare(' SELECT artist, -- always select *concrete* columns title FROM songs WHERE artist LIKE :artist_search_term OR title LIKE :title_search_term LIMIT 100 '); $songStmt->execute([ 'artist_search_term' => $_POST['search'], 'title_search_term' => $_POST['search'], ]); foreach ($songStmt as $song) { var_dump($song); }
  22. Jacques1's post in Session is dropped after redirect? was marked as the answer   
    You're also terminating the session with session_destroy() and then try to write data to it. This of course makes no sense. Get rid of the statement. I guess what you actually want is session_regenerate_id(true).
  23. Jacques1's post in Dont understand this was marked as the answer   
    The array_intersect_key() stuff is a very obscure way of removing all ($key, $value) pairs from $data where $key isn't in $fields.
     
    So $fields is basically a whitelist of allowed keys (as explained in the comments).
  24. Jacques1's post in Handling exceptions by loading a page with a safe message. was marked as the answer   
    Ideally, you shouldn't need any handler.
     
    Disable both display_errors and display_startup_errors to simulate a production environment. Then create a script with a fatal error and watch the developer tools of your browser. You should see a blank page and a 500 response code. If this works, you have to make Apache intercept this error and display a custom error page. How do Apache and PHP communicate on your production server (not the XAMPP testing stuff)? Via FastCGI? mod_php? CGI?
     
    If you don't want to (or cannot) intercept the error with the webserver, you should register a shutdown function as explained in the Dev Shed thread. This function can then render a user-friendly error message.
  25. Jacques1's post in aes js & php was marked as the answer   
    Both the key and the IV must be raw, unencoded strings with exactly 128 bits (or 16 bytes). Right now, all your strings are hex-encoded and also way too long.
    const CRYPTO = require('crypto'); const CIPHER = "AES-128-CBC"; const MASTER_KEY_HEX = "5e2a0626516f3108e55e25e4bb6a6283"; const MASTER_KEY = new Buffer(MASTER_KEY_HEX, "hex"); // encrypt var plaintext = new Buffer("attack at dawn"); var initVector = CRYPTO.randomBytes(16); var cipher = CRYPTO.createCipheriv(CIPHER, MASTER_KEY, initVector); var ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]); console.log( ciphertext.toString("hex") ); // decrypt var decipher = CRYPTO.createDecipheriv(CIPHER, MASTER_KEY, initVector); var decryptedPlaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]); console.log( decryptedPlaintext.toString() );
×
×
  • 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.