RIPS – A static source code analyser for vulnerabilities in PHP scripts

In the last years I have been working on my PHP Scanner (now called RIPS) which has been released recently during the Month Of PHP Security and was awarded as the 2nd best external submission.
RIPS is a tool written in PHP itself and designed to easily detect, review and exploit PHP vulnerabilities by static source code and taint analysis. It is open source and freely available at SourceForge (yey!).

Before using it I recommend reading the paper (HTML, PDF) I submitted to be aware of the limitations RIPS has, either due to static source code analysis or because of my implementation of it.
In short: RIPS is not ready yet for firing it on big code trees like wordpress, but I think it does a good job for home-made or smaller open source apps and in assisting code reviews. I hope I will find time in the future to improve RIPS and I am honestly thankful for any feedback, bugreports, code improvements or feature requests.

[download RIPS]

Update 04.07.10: A new version 0.31 has been released.
Update 13.08.10: A new version 0.32 has been released.
Update 11.09.10: A new version 0.33 has been released.


26 Responses to RIPS – A static source code analyser for vulnerabilities in PHP scripts

  1. Steve Pinkham says:

    RIPS looks intriguing, I look forward to testing it out.
    Also, I like the look of the PDF. Any chance of making the LaTeX source available? 🙂

  2. Jan Hančič says:

    After I click scan (and enter a path to files off course) I get a blank screen without any errors.
    Is there any special configuration I have to make to make this work? I haven’t found any readme file anywhere.

    • Reiners says:

      hm try to scan some basic php scripts first to look if the scanner works for simple test cases. in /config/general.php you can also enable error_reporting and see what causes the problem. maybe you don’t have the tokenizer extension (should be available since php 4.3.0 but some OS ship PHP with only minimum extension available). if only a specific script raises the error, please send it to me and I’ll have a look at it.

      • diabloneo says:

        I encounter this problem, too. I found that the problem is due to the file permission of the source code file.

    • Reiners says:

      thanks for helping out diabloneo.

  3. hkhexon says:

    I will have a look at it, nice project 😀

  4. Ams says:

    Reiners, congrats on second place! Hope you will continue developing this tool.

  5. Looks interesting. Wish you to keep on adding new features in contrast to stalled Pixy project.

    p.s. You might want to read about some other limitations of the taint analysis in my blog…

  6. Reiners says:

    hi andrew,

    thank you very much for your interesting links. there are quite some different approaches I find interesting, e.g. saving a taint-flag (xss, sqli) for each variable instead of doing it the other way around: checking for sanitization during the traceback. I will do some tests which approach fits better to RIPS.

    • hi Johannes,
      I am glad you have found them useful. Looking forward for your experiments and feature improvements.

      p.s. Please feel free to ask me any questions, I am always ready to help

  7. Robert (Jamie) Munro says:

    RIPS looks like a great tool. I’ve been looking at Pixy and PHP-Sat, which didn’t work well, and the PHP taint plugin, which was a pain to install.

    While I have been able to find a couple of problems using RIPS, I’m struggling to interpret some of it’s output.

    I presume that the white and red colored dots at the start of lines indicate that those lines contain tainted code, but I can’t find any documentation on what the difference is.

    Also, it would be great when it shows a line like:

    mysql_query (“insert into foo values (‘$a’,’$b’,’$c’,’$d’)”;

    if it could say which of $a, $b, $c or $d it is complaining about (in practice, I have inserts with a lot more columns that this).

    • Reiners says:

      hi robert,I’m glad to hear you like the tool,please let me know about all problems you have.for the interpretation of the output:I already improved the detailing of the output by highlighting the tainting variables and commenting the potential vulnerability type.I’ll release a new version in the next weeks.regarding the colored dots:white is tainted by userinput,red is secured by the developer.rips was designed for private usage but the more people use it the more documentation and explaination I’ll build in.stay tuned for the next version.

  8. Robert (Jamie) Munro says:

    So red is good and white is bad? IMHO red is normally a bad thing, and green a good thing. It would be good if you could put the dots next to the variables they are talking about, rather than across the whole line – if I have a line like:

    $a = $b; $c = $d;

    I can’t tell which the dot refers to. I’m guessing the second one ($c) only.

    In my code, I have a line like:

    $user_digest = md5($_POST[‘password’]);

    But it’s given this line a white dot even though “md5” is listed in config/securing.php in F_SECURING_STRING.

    If I change it to $user_digest = mysql_real_escape_string(md5($_POST[‘password’])); then I get a red dot.

    I do look forward to the next version. I think what you are doing should be compulsory for all users of PHP to use on their code before they release it to any users. The fact that it is written in PHP and has no dependencies means there is little excuse not to run it on your test server.

  9. Joel says:


    First thank you for the great work.
    I used it on some small php code a while ago and it worked great.
    Some remarks:
    1-I remember display starting at the execution point and then going (backward) to the input. I think display would be somehow more natural starting at input and finishing at execution point. It remebers more of an execution flow.
    2- I tried to scan a framework based project (namely Yii). It never worked. I made settings to have the script run endless but it didn’t help.
    Do you have some measure of projects size limits?
    3-Let say one has a framework and it’s possible to scan it but it’s long. Then the code of the framework almost never changes. Would it be possible to export the results of a framework scan in such a way that later on, quick scans of projects based on the framework can be made.
    If such a feature was available I am sure community would share the load, scan all main frameworks and upload the result somewhere. This would be really useful.
    4-What are limitations for scan of big projects? Is it that when the size of memory needed overcomes RAM it starts to swap and then is really too slow or is it something else?

    Once again thanks a lot

    • Reiners says:

      hi joel,

      thank you very much for your feedback! Regarding to your questions:

      1: I decided to chose the backward direction because that is the way the source code analysis is handled (first looking for potentially vulnerable functions and then tracing if they are tainted by user input). In my opinion this way of visualization is better than the other way around because you start looking at the function call you want to inject to and you can immediately see what this vulnerability is about and what you want to accomplish (e.g. inject SQL code). then you follow the tree down to the user input and you can see if your goal can be accomplished. for better understanding I will add the vulnerability type (e.g. “possible SQL Injection”) to each output.

      2 and 4: RIPS has problems to scan large code trees, mainly because it takes a lot of time which is mostly prohibited by the webserver/PHP configuration. I set the max execution timeout to 120 seconds in the config/general.php because the scan result should be available in under a minute, but this time is expected for small or simple webapps. As I have heard professional products can take some hours to scan large projects, so I don’t think RIPS is slow. I think it is even faster than other tools because it does not use a CFG.
      What I do when I scan larger code with RIPS is to scan subdirectories of the project separately. Sometimes it is even necessary to scan one big file separately to get a result within a minute. Of course this depends not only on the amount of lines but also on the amount of includes and traces being made. Of course you can also scan the whole project at once if you configure your webserver and php correctly and wait some time. but scanning subdirectories or specific files has the advantage to limit the scan result to a more clear output.
      I’ll have a look at Yii and see if I find any bugs or if it just takes quite some time so scan.

      3: this is a very good idea and I’ll see what I can do to implement this very useful feature. I just need to find a good way to store previous results and to compare it effectively. However I think it will not decrease the time to scan because I will need to scan every potential vulnerability again to see if changes on the code changes the tainting. But I’ll see.

      thanks again for your input.

  10. Joel says:

    Thanks for the answer,
    1- I understand your point of view. I think it is vulnerability search oriented and not developer demonstration oriented.
    My point is that the goal is not to find flaws but to explain things to developers, which are used to see code in the running direction.
    But anyhow it’s a detail
    2- I am used to other scan tools and I agree that RIPS is not slow (avoiding CFG seems to be the great winner for you).
    2-I think to simplify issues with time best is to make a phpcli, in which tcp connection doesn’t play (being dependent on network stability for a multi-hours scan is a pity). I’ll try to look into making such a file tonight. Should be easy.

    3-I have some idea about that, I’ll be writing when i have a little more time to concentrate


    Now some other stuff.I scanned a project and I found it too fast of a scan so i went to Verbosity level 5:

    File: /var/www/proboks/html/wsdl/admin.ajax.php
    3: session_start
    ==> No question

    5: include_once

    6: include_once

    Now the definition of CONFIG_PATH (in ,quite straightforward (I actually modified it with hope it’ll help:

    So what could I do:
    Is there a place to define PATH ?
    Is the only way to make find and replace for all my define ?
    If so I believe I’ll make some script for that, and I’ll share it. But i thought that the Zend engine would care of it for you.

    Once again thanks a lot and good continuation.

  11. Reiners says:

    1. I’ll have a look how easy it would be to add an option to switch the order of the output tree.

    2. not to forget that a CFG would bring a better result in special cases.

    3. I’m looking forward to your ideas =)

    regarding your scanresult:
    as you assumed there is probably an include() which could not be reconstructed by RIPS.
    could you post a more detailed output for line 6 ? It should display the exact code line and add a comment what RIPS was trying to include. define()’s are normally fully supported by RIPS, but I need the exact code to debug it.

    thanks again for your input, I really appreciate it!

  12. Vinod says:

    Hi, I am really in opensource contribution for ur Project, seems the PDF is quite enough for understanding the RIPS scanner and how it works theoretically, But is there any way by which I could get the CONTROL FLOW DIAGRAM and SEQUENCE DIAGRAM of the RIPS, that would definitely help me in further understanding of rips and allow me to further contribute to the development.

    • Reiners says:

      Hi Vinod, I understand that it is a pain to understand the code :S Basically the main happening is in /functions/scan.php. The function scan_file() gets all tokens of a source code file and then loops through those tokens. It then detects semantic by connected tokens and reacts accordingly.

      $tokens = fix_tokens( token_get_all($code) );	
       for($i=0;$i<count($tokens); $i++)
          list($token_name, $token_value, $line_nr) = $tokens[$i];
          if($token_name === T_VARIABLE && $tokens[$i+1] === '=') // var declaration	
          if($token_name === T_STRING && $tokens[$i+1] === '(') // function call

      For example when a variable is found and a ‘=’ follows, a variable declaration is found and saved. When a string is found (token name T_STRING) and a braclet follows, a function call is detected. Then it checks whether this is a sensitive sink (configured in /config/PVF.php), all parameters are collected and for each of them scan_parameter() will be called recursivly, which returns $userinput=true/false to detect if the parameter is tainted or not. All results are stored in $output which will be parsed at the end in /functions/output.php.

      Let me know if you need anything else or a control flow diagram for specific parts would be more helpful.

  13. Vinod says:

    Firstly, once again, thanks for such a wonderful scanner 🙂

    Secondly, yes, thanks for briefing me out on basic flow, I have known that, actually I have tried to debug it and understand a bit of flow as much as i could ! It would be of further help, if I could get the Flow Diagrams, and/or sequence diagrams on the major parts?

  14. vinod says:

    Or the Data flow Diagram ?

  15. Tarique Khan says:

    First….Thanks for providing a great project Robert….its really good tool for php.

    But i am finding difficulty to interpret the output.

    • Reiners says:

      Hi Tarique, thank you for your feedback. Could you be more precise on what you are missing or what is not clear to you? I may try to improve this in the new rewritten version of RIPS.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: