Jump to content

Psycho

Moderators
  • Posts

    12,157
  • Joined

  • Last visited

  • Days Won

    129

Everything posted by Psycho

  1. Using the current layout as you described above here is a way you could build your page automatically. Just set up the two arrays as needed then the rest of the code will do all the work <?php //Array for section/subsection structure $sectionsAry = array( 'Interior' => array( 'Interior Misc' => 'row1', 'Floors' => 'row2' ), 'Header Section2' => array( 'Subhead 1 Sec 2' => 'row3', 'Subhead 2 Sec 2' => 'row4' ), ); //Array to hold formatting rules for values $subsecFormats = array( 'Interior Misc' => array ('match'=>'/[,]/', 'replace'=>', ') ); //Run through each section and subsections foreach($sectionsAry as $sectionName => $subsectionsAry) { //Create variable to hold the HTML output for the subsection $subsectionHTML = ''; //Process the subsections to see if there is data foreach($subsectionsAry as $subsecName => $subsecKey) { //Check if subsectionhas a value if($data->$subsecKey) { //Generate the HTML for the subsection $subsecValue = $data->$subsecKey; //Check if the value needs to be formatted if(in_array($subsecName, $subsecFormats)) { $match = $subsecFormats[$subsecName]['match']; $replace = $subsecFormats[$subsecName]['replace']; $subsecValue = preg_replace($match, $replace, $subsecValue); } $subsectionHTML .= "<dl class=\"data_example\">\n"; $subsectionHTML .= "<dt>{$subsectionName}:</dt>\n"; $subsectionHTML .= "<dd>{$subsecValue}</dd>\n"; $subsectionHTML .= "</dl>\n"; } } //Processing of all subsections complete //Check if any had subsections had values if($subsectionHTML != '') { //Show section header echo "<div class=\"data_example\">\n"; echo "<h2>{$sectionName}</h2>\n"; //Ouptu subsectioncontent echo $subsectionHTML; //Close div echo "</div>\n"; } } ?>
  2. As long as these sections follow a consistent format, then you could do all this programmatically. I would create an array of the structure of the feilds by session and then run a loop to do all of this. Let me take a few minutes to bang out an example/
  3. @xyph, You completely missed the point of my post. I was never advocating a single salt. I have only been referring to this statement. A random salt stored beside the hash is no better or worse than using any other salt that is unique to each user, no matter where it is stored. In fact, the method you described could even be considered worse than using something such as the username as a hash. Why? Because an attacker could see that the hash stored int he database it too long. He could then conclude that the salt is either at the beginning or the end of the hash. The point is that without knowing what value is being used as the salt OR how it is used there is no more or less "security". The only way to get that information would be through the source code or inside information. With a known password/hash combination the attacker might be able to reverse engineer the salt IF it was done in a simplistic manner (such as just appending the salt to the beginning). If I were to put half the salt at the beginning and half at the end and then reverse the characters it would be "realistically" impossible for someone to stumble upon the salting method through brute force. Anyway, rather than continue this discussion which isn't getting us anywhere, I challenge you to crack the following. Password: ******** Salt: 1308148757 (timestamp) Hash: 6849f5938bfc4e88bfd432f435bdece2 Hashing method: MD5 I have provided the salt and the hash. Plus I will even give you the following details about the password. It is 8 characters long and is only comprised of alpha-numeric characters. No special characters or accented letters. It is even a password I have used before, so it isn't just a random bunch of characters. So, you now have a great deal more information than someone who was able to penetrate the DB would have, but I doubt anyone would be able to figure out the password as they do not know how the salt was applied.
  4. What do you mean rebuilding your tables? The look of your tables won't be affected at all. The changes I proposed would only add some internal ID fields to the tables. The tables would look EXACTLY as they do now. The code may look much different because I moved the HTML code for the table to be within the PHP. It is messy to enter/exit PHP blocks repeatedly in your script. So, I just converted the same HTML code you have now to be generated within the PHP while loop (and adding the ID fields, nothing more).
  5. That is what I disagree with. With any salt the attacker needs to know how the salt is applied, ergo they would have to have access to the source code to gain that knowledge. With access to the the source files it would be an elementary exercise to identity that a salt is embedded in the hash itself and how to extract it. Case in point, the function above. By analyzing the code one could decipher how the salt and hash are stored. You did, so why couldn't anyone else? By analyzing that function we now know that the salt is 9 characters and is concatenated to the front of the actual hash, do we not? I believe he is saying that with ONLY the database hash, it is not possible to bruteforce passwords until you come up with that hash, since you don't know how the hash was constructed. Obviously if you have access to the source code then it would be quite trivial. Think about that for a moment. You are saying it is better to store the salt as part of the hash in the database because if someone only got the db info they wouldn't be able to brute force the hash. How would that be better than just using a single, hard-coded salt that is stored in the source files? As long as you are using a salt the attacker MUST have some knowledge of how the salt is used. That can only come from the source code. So, as long as you are using a unique salt it doesn't matter how the salt is obtained. Like I have stated before you could simply use the username as the salt. There is no way an attacker will know that is the salt without the source code. So, it is no better or worse than the method described previously.
  6. That is what I disagree with. With any salt the attacker needs to know how the salt is applied, ergo they would have to have access to the source code to gain that knowledge. With access to the the source files it would be an elementary exercise to identity that a salt is embedded in the hash itself and how to extract it. Case in point, the function above. By analyzing the code one could decipher how the salt and hash are stored. You did, so why couldn't anyone else? By analyzing that function we now know that the salt is 9 characters and is concatenated to the front of the actual hash, do we not?
  7. You can merge records from multiple tables assuming the structure is the same but . . . you would have no way to to the Delete or Update queries since you wouldn't know which table to run the queries against for each record. I'd implement some logic that sees if there are any unprocessed records in table one. If so, process some records against that table. If not, try the same for the next record. So, modify the current queries you have to use a variable for the table name and use something like this at the top of the script. $tableList = array('table1', 'table2', 'table3', 'table4'); foreach($tableList as $tableName) { $query = "SELECT * FROM `{$tableName}` WHERE `processed`=0 LIMIT 1"; $result = mysql_query($query) or die(mysql_error()); if(mysql_num_rows($reesult)>0) { //There are records in this table, exit the loop and use $tableName break; } } //Use $tableName in the processing code you already have It means you will be running multiple queries as you get to the later tables, but it's the easiest solution I can think of
  8. While I won't argue that the method shown would provide some additional complexity, it really doesn't provide any additional security. An attacker would already have to have some knowledge of the hashing method and salt (in addition to the hashed values in the database). The only way to gain that knowledge would be to view the code (unless your database has an actual field called hash!). Even just using the username, timestamp of date created, etc. are all just as good as the function above. With a unique salt for each user the attacker would have to use the same hashing methodology and then loop through hundreds of thousands of "potential" passwords in order to try and decipher a user's password. If the user is using a password such as "password" or "apple" their password will be discovered in such a brute force attempt. The reality is that 1) In order to do this the attacker would have to already have access to the data. So, the only thing the attacker would be obtaining is - possibly - the password. 2) The brute force method can be easily thwarted by requiring strong passwords. The CPU/Memory requirements to try and reverse a strong password are hugely significant. 3) Unless this is for a financial or high profile site, no one is going to bother to go to these extremes in the first place.
  9. Hmm... I guess you could use a JavaScript only solution. I assume jquery.tablesorter is a client-side only table filtering function. If you don't have hundreds of records that is a possible solution (assuming you understand that it will only work when the user has JS enabled). But, even if you go the AJAX route you would need JS + PHP. So, if you have a fairly limited record set a JS solution might be easier to implement. If the record set is large you don't want to push all that data down to the client and AJAX would be a better choice. I'm not familiar with jquery.tablesorter but I could probably give you a down-and-dirty solution: 1. Since this will be client side, you need to use the client side values. So, the first order of business is to change the options for the country select list to be the country names, not the abbreviation, so we can match up the selected value with the values in the table. $options.="<OPTION VALUE=\"{$thing}\">{$thing}</option>\n"; NOTE: I would add a default selection at the top of the list for "ALL". Make the value an empty string. Where you define the options variable use $options="<OPTION VALUE=\"\">ALL</option>\n"; Now, in the code that produces the table add an ID to each TR tag as well as the TD for the country value. Use a numerically based index appended to each <?php $rowID = 0; while($rows=mysql_fetch_array($result)) { echo "<tr id=\"row_{$rowID}\">\n"; echo "<td align=\"center\">{$rows['Project_id']}</td>\n"; echo "<td>{$rows['FinancialYear']}</td>\n"; echo "<td>{$rows['ProjectExecutive']}</td>\n"; echo "<td>{$rows['RetailProjectManager']}</td>\n"; echo "<td id=\"ctry_{$rowID}\">{$rows['Country']}</td>\n"; echo "</tr>\n"; $rowID++; } ?> Next create an onchange event for the select field <SELECT NAME="Country" type="text" onchange="filterTable(this.options[this.selectedIndex].value);"> Lastly create a function to show/hide each row based upon the selected value function filterTable(selCtry) { dim rowIdx = 0; dim tdObjVal, displayVal; while(document.getElementById('ctry_'+rowIdx)) { //Get value of current row country cell tdObjVal = document.getElementById('ctry_'+rowIdx).innerHTML; //Define display style for current row based upon selcted country displayVal = (selCtry=='' || selCtry==trObjVal) ? '' : 'none'; //Show/hide current row using display style property document.getElementById('row_'+rowIdx).style.display = displayVal; rowIdx++; } return; } All of this was done on-the-fly and not tested with your script. It may work as is or there may be some syntax errors or minor issues to fix.
  10. If you want to do this without reloading the page you will have to use AJAX: a JavaScript client-side script that makes a server-side call and updates the page accordingly. However, I would first suggest building it so that you have to submit the page - then implement AJAX. That way you can develop the server-side code independent of the client-side code. This makes it easier when developing - when there is a problem you don't have to try and figure out if it is PHP or JavaScript. Once you have the PHP code functioning, you can then implement the JavaScript code (a la AJAX) to have it work without a page refresh. So, are you having any problems with the current implementation?
  11. This third party class should work: getID3(), http://getid3.sourceforge.net/ It will work for a multitude of media formats (see link), but maybe not all formats you are looking for though.
  12. Interesting approach to get only the files using glob() with GLOB_ONLYDIR and array_diff(). I don't know why there isn't a flag such as GLOB_ONLYFILE Anyway, here is another approach that may or may not be more efficient. It only requires one glob() call, but then filters based on is_file(); $files = array_filter(glob($path.'*'), 'is_file');
  13. By header, I mean the PHP header function: http://php.net/manual/en/function.header.php. You can use it to, among many other things, redirect the script to another page. In this case you would recursively call the same script over and over. The downside of this is that there would be no visual display in the browser. And, on second thought, I'm not sure that would prevent the script from timing out since the PHP code is being executed recursively. Besides, I think a META tag in the HTML is a better option anyway. You don't have to worry about the page refreshing too early. You wouldn't output the HTML until the end of the script (when that batch is done executing), so it couldn't refresh until the HTML is output - which would be after the current batch is processed. You could also add some other text to the page on each iteration to display how many records are left to be processed. That way you have a visual indicator as to the progress. That is kind of a quick and sloppy solution. If this was something I'd be doing all th etime, I'd probably do the same thing - but with AJAX. But for a one-time or rarely used operation a META refresh should be fine.
  14. AJAX. Wasteful? Not really. In the case of an IM app, the AJAX request itself is insignificant. It probably only needs to sent the ID of the conversation and the ID if the user. If there is no new content (as would be the case in 99.99% of the requests) the server would simply return a false value (i.e. a zero) or maybe a little other info. That would take a whole whopping single bit of data. An email client would be no different. It is only when there is new data that any significant data would be returned, which is what you want anyway. It *may* be wasteful on the server, which is why you would write the code to be as efficient as possible. But, that is also why services like Google have thousands of server to support their products. If you want to validate all of this for yourself. Download an app called Fiddler. It is a little complicated to use, but it will show you all incoming/outgoing transmissions from your computer. With it I'm sure you will be able to see the multiple AJAX calls that are taking place.
  15. Then use this logic if ($code == 404) { return false; } else { return true; } Then you can run these in batches. Add a column to the table named something like "processed" as a tiny int and set the default value to 0. Then in the query to grab the records use a LIMIT on the query to only get a certain number of records (say 10) AND include a WHERE clause on the query to only get those records were "processed" = 0. Now when you process the records you will need to put the IDs into one of two arrays: a delete array and a save array. After you are done processing that batch run the delete query same as before, but then also run an update query on the records in the saved array to change the "processed" field to a 1. Then just keep running the page until you have processed all the records. You can put a header() at the end of the script or use a meta tag to auto refresh the page after it loads. <?php //Functin to validate a URL: returns true/false function validURL($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 10); //follow up to 10 redirections - avoids loops $data = curl_exec($ch); curl_close($ch); if (!$data) { return false; } else { preg_match_all("/HTTP\/1\.[1|0]\s(\d{3})/", $data, $matches); $code = end($matches[1]); if ($code == 404) { return false; } else { return true; } } } //Run query to get all the records $query = "SELECT * FROM `table` WHERE `processed` = 0 LIMIT 10"; $result = mysql_query($query) or die(mysql_error()); if(mysql_num_rows($result)==0) { echo "All records have been processed."; exit(); } $deleteList = array(); $updateList = array(); while ($info = mysql_fetch_array($query)) { //Check each record to see if it is valid if(!validURL($info['url'])) { $deleteList[] = $info['id']; } else { $updateList[] = $info['id']; } } //Delete the invalid records if(count($deleteList)>0) { $query = "DELETE FROM `table` WHERE `id` IN (" . implode(',', $deleteList) . ")"; $result = mysql_query($query) or die(mysql_error()); } //Update the records to save by setting the processed value if(count($deleteList)>0) { $query = "UPDATE `table` SET `processed` = 1 WHERE `id` (" . implode(',', $deleteList) . ")"; $result = mysql_query($query) or die(mysql_error()); } ?>
  16. What do you mean "nothing happened", are you not getting the error message
  17. Sample code ( I guessed on the field names) //Function to validate a URL: returns true/false function validURL($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 10); //follow up to 10 redirections - avoids loops $data = curl_exec($ch); curl_close($ch); if (!$data) { return false; } else { preg_match_all("/HTTP\/1\.[1|0]\s(\d{3})/", $data, $matches); $code = end($matches[1]); if ($code != 200) { return false; } else { return true; } } } //Run query to get all the records $query = "SELECT * FROM `table`"; $result = mysql_query($query) or die(mysql_error()); $deleteList = array(); while ($info = mysql_fetch_array($query)) { //Check each record to see if it is valid if(!validURL($info['url'])) { $deleteList[] = $info['id']; } } //Delete the invalid records if(count($deleteList)>0) { $query = "DELETE FROM `table` WHERE `id` IN (" . implode(',', $deleteList) . ")"; $result = mysql_query($query) or die(mysql_error()); }
  18. I would do the following. 1. Query for all the records. 2. Perform a while loop over each record and perform the validation steps that you have. As you find a record that needs to be deleted, add the record ID to an array. I'd create a function of the validation routine and have it return a true/false 3. Once the validation loop is completed, run one DELETE query on the list of records found to be invalid. However, if the validation routine takes a long time to run for each record you may have a problem with the script timing out. If that is the case you might need to process the records in batches. Also, I see a problem with your validation code. It ends with an If/Elseif, but no else. What if the returned value is no 200 or 404?
  19. What Pikachu was trying to express is that the effort is not worth the gain. The people who would want to circumvent any such "security are the ones that would go to the trouble of learning how. Case in point: I have a large music collection and I wanted an album art photo for each album of my ripped mp3s. In doing image searches every once in a while I would find an image I wanted hosted on a site that would try to "protect" the image by doing things such as disabling right-click via javascript, putting a transparent gif over the actual image or some other useless "security". It was all useless for two reasons. 1) the image has already been saved to my computer in the browser cache and 2) I could get the image by simply doing a screen capture. I can't tell you how many posts I have seen from people asking how to secure the images in their website so people can't copy them. It's a worthless goal, all it takes is for one person with the know-how to copy the image and it is there for the word. The best you can do is watermark the image so that when someone tries to pass the image off as their own they won't succeed. (Yes, tehre are some services - expensive - that will monitor the web for people using your photos, but that is closing the barn door after the horses have left. And, your attempt to get the offender to remove the image will depend greatly on where the offender is hosting their site) As for your particular request. Sure it can be done. Just make a java applet (not javascript) and require the user to install the plug-in for their browser. The plug-in could read specific data from their PC (maybe even the CPU ID) and pass that along with their registration. That would be as good of a security as you could hope to get. Of course, no user in their right mind would want to install any plug-in to access whatever 1337 content that you are hosting. Not to mention the solution would probably be rife with incompatibility issues for the various browsers. But, go for it! Don't let anyone giving advice based upon reasons and facts deter you.
  20. Are you getting any errors? If so, what are they? If you are not getting any errors and there are no records displayed then I would assume the main query (to get the records) is not returning any results. Although, I do notice that your query is only selecting the ids and you are trying to display the value of 'number' which wasn't pulled in the query. Anyway, here is a rewrite of your script. I made a lot of changes. I even changed some variable names to create some sort of consistency. You may not agree with the names I chose, but frankly, I don't care. Your structure and naming conventions suck. Additionally, I created a debugging section to echo some details to the page so you can see if the variables and results are what you expect. If something is not an appropriate value (or no value is shown) then you know where to start looking for the problem. You should always include debugging logic in your code. Otherwise when you don't get the results you expect you have no clue where to start looking. FYI: one of the possible reasons you were not seeing anything is that you were creating the prev/next links using < and > characters. Those might be interpreted as HTML tag enclosures, so you should escape them using < and > when you want them interpreted as text. <?php // find out how many rows are in the table $query = "SELECT COUNT(*) FROM `CysticAirwaves`"; $result = mysql_query($query, $conn) or trigger_error("SQL", E_USER_ERROR); $row = mysql_fetch_row($result); $total_records = $row[0]; // number of records to show per page $records_per_page = 40; // find out total pages $total_pages = ceil($total_records / $records_per_page); // get the current page or set a default if (isset($_GET['page']) && is_numeric($_GET['page'])) { //Cast var as int $current_page = (int) $_GET['page']; //Ensure $current_page is within min/max values $current_page = max($current_page, 1); $current_page = min($current_page, $total_pages); } else { // default page num $current_page = 1; } // the offset of the list, based on current page $offset = ($current_page - 1) * $records_per_page; // get the info from the db $query = "SELECT `id`, `number` FROM `CysticAirwaves` LIMIT $offset, $records_per_page"; $result = mysql_query($query, $conn) or trigger_error("SQL", E_USER_ERROR); ## DEBUG INFO ## echo "<b>Debug Info</b><br><br>\n"; echo "Total records: {$total_records}<br>\n"; echo "Records per page: {$records_per_page}<br>\n"; echo "Total pages: {$total_pages}<br>\n"; echo "Current page: {$current_page}<br>\n"; echo "Offset: {$offset}<br>\n"; echo "Data Query: {$query}<br>\n"; echo "Records returned: " . mysql_num_rows($result) . "<br>\n"; // while there are rows to be fetched... while ($row = mysql_fetch_assoc($result)) { // echo data echo "{$row['id']} : {$row['number']}<br />\n"; } // end while /****** build the pagination links ******/ // range of num links to show $range = 3; //function to create the links, to simplify the script $baseURL = "http://www.cysticlife.org/Airwaves_build.php?page="; function createPageLink($baseURL, $pageNo, $linkText) { return "<a href='{$baseURL}{$pageNo}'>{$linkText}</a>"; } // if not on page 1, show back links if ($current_page > 1) { // show << link to go back to page 1 echo createPageLink($baseURL, 1, "<<"); // show < link to go back to 1 page echo createPageLink($baseURL, ($current_page-1), "<"); } // end if // loop to show links to range of pages around current page $page_start = max(($current_page-$range), 1); $page_end = min(($current_page + $range), $total_pages); for ($x = $page_start; $x <= $page_end; $x++) { // if we're on current page... if ($x == $current_page) { // 'highlight' it but don't make a link echo " [<b>$x</b>] "; // if not current page... } else { // make it a link echo createPageLink($baseURL, $x, $x); } } // end for // if not on last page, show next and last page links if ($current_page < $total_pages) { // show > link to go forward 1 page echo createPageLink($baseURL, ($current_page+1), ">"); // show >> link to go to last page echo createPageLink($baseURL, $total_pages, ">>"); } // end if /****** end build pagination links ******/ ?> </div>
  21. Use dirname() on the current directory (which I assume to be $absdir) to return the parent directory. Then get the sub-directories from that. Also, instead of using readdir() to read through the objects in a directory you might want to look into using glob(). It will return an array of the objects and you can have it filter out files and/or folders based upon your needs. So you wouldn't need any is_dir() to test if something is a file or a folder. Also, you don't have to worry about '.' or '..'
  22. There is a tutorial on pagination on this site: http://www.phpfreaks.com/tutorial/basic-pagination I sei no need to try and explain everything that has already been explained there (as well as other tutorials freely available). Not trying to be an a**, but I'd suggest reading that tutorial and then go back to what you have. If you have questions after reading that, then by all means post them. I will respond to this statement though I'm not sure I understand your confusion. You have this line in your code $currentPage = 1; So, every time the script is run you are setting the current page to page 1. If you click one of your pagination links you are setting a value on the query string which set a value for $_GET['page']. But, since you don't do anything with that value the "current page" will always be 1. Take a look at the tutorial, it shows you have to incorporate $_GET['page'] into the pagination.
  23. Really? Did you read what I posted.
  24. There may be free alternatives, I just didn't bother looking. Wouldn't be a bad idea to spend some time googling to see.
×
×
  • 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.